mirror of
https://github.com/CodeLabClub/codelab_adapter_extensions.git
synced 2024-11-25 16:36:27 +08:00
add web page
This commit is contained in:
parent
c648734d9d
commit
826b6266db
237
src/message_browser.html
Executable file
237
src/message_browser.html
Executable file
@ -0,0 +1,237 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>Message Browser</title>
|
||||
<link
|
||||
href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
|
||||
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
||||
<!--need jquery-->
|
||||
|
||||
<script src="https://cdn.bootcss.com/socket.io/2.2.0/socket.io.slim.js"></script>
|
||||
<link
|
||||
href="https://cdn.bootcss.com/codemirror/5.19.0/codemirror.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.bootcss.com/codemirror/5.19.0/codemirror.js"></script>
|
||||
<link
|
||||
href="https://cdn.bootcss.com/codemirror/5.19.0/theme/solarized.min.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.bootcss.com/codemirror/5.19.0/mode/python/python.min.js"></script>
|
||||
</head>
|
||||
<!--edit ~/codelab_adapter/src/message_browser.html 实时生效-->
|
||||
<body>
|
||||
<!--标签页 不同message + console-->
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row-fluid">
|
||||
<div class="span12"><h3>Message from codelab-adapter</h3></div>
|
||||
<div
|
||||
style="margin-top:10px"
|
||||
class="alert alert-info"
|
||||
role="alert"
|
||||
>
|
||||
新消息出现在顶部(往下滚动)
|
||||
</div>
|
||||
<div class="span12"><div id="console"></div></div>
|
||||
</div>
|
||||
<hr />
|
||||
<div class="row-fluid" style="margin: 10px">
|
||||
<div class="span12"><h3>Message to codelab-adapter</h3></div>
|
||||
<div class="span12">
|
||||
<div class="tabbable" id="tabs-604082">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active">
|
||||
<a href="#panel-456287" data-toggle="tab"
|
||||
>eim</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#panel-943211" data-toggle="tab"
|
||||
>eim/python</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#panel-943212" data-toggle="tab"
|
||||
>REST API</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="panel-456287">
|
||||
<div
|
||||
style="margin-top:10px"
|
||||
class="alert alert-info"
|
||||
role="alert"
|
||||
>
|
||||
可用于发送任何消息
|
||||
</div>
|
||||
<input
|
||||
id="eim_input"
|
||||
class="form-control form-control-lg"
|
||||
type="text"
|
||||
placeholder="input message"
|
||||
style="margin-top:10px"
|
||||
value="{"topic":"from_scratch/extensions","payload":{"content": "message", "extension_id": "eim"}}"
|
||||
/>
|
||||
<!--html 转义 https://www.sojson.com/rehtml-->
|
||||
<button
|
||||
style="margin-top:5px"
|
||||
class="btn btn-info"
|
||||
type="button"
|
||||
onclick="send_eim_message()"
|
||||
>
|
||||
broadcast
|
||||
</button>
|
||||
</div>
|
||||
<div class="tab-pane" id="panel-943211">
|
||||
<div
|
||||
style="margin-top:10px"
|
||||
class="alert alert-info"
|
||||
role="alert"
|
||||
>
|
||||
使用时请打开extension_python_kernel插件
|
||||
</div>
|
||||
|
||||
<div class="span12">
|
||||
<div id="code_playgroud"></div>
|
||||
<button
|
||||
style="margin-top:5px"
|
||||
class="btn btn-info"
|
||||
type="button"
|
||||
onclick="send_python_code()"
|
||||
>
|
||||
broadcast
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane" id="panel-943212">
|
||||
<div
|
||||
style="margin-top:10px"
|
||||
class="alert alert-info"
|
||||
role="alert"
|
||||
>
|
||||
<pre>
|
||||
var xhr = new XMLHttpRequest();
|
||||
var url = "https://codelab-adapter.codelab.club:12358/api/message"
|
||||
xhr.open("POST", url, true);
|
||||
var sendData = {"topic":"from_scratch/extensions","payload":{"content": "REST API", "extension_id": "eim"}};
|
||||
xhr.setRequestHeader('content-type', 'application/json');
|
||||
xhr.send(JSON.stringify(sendData));
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<input
|
||||
id="rest_input"
|
||||
class="form-control form-control-lg"
|
||||
type="text"
|
||||
placeholder="input message"
|
||||
style="margin-top:10px"
|
||||
value="{"topic":"from_scratch/extensions","payload":{"content": "REST API", "extension_id": "eim"}}"
|
||||
/>
|
||||
<button
|
||||
style="margin-top:5px"
|
||||
class="btn btn-info"
|
||||
type="button"
|
||||
onclick="send_rest_api()"
|
||||
>
|
||||
broadcast
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/*
|
||||
const url = new URL(window.location.href);
|
||||
var adapterHost = url.searchParams.get("adapter_host");
|
||||
if (!adapterHost) {
|
||||
var adapterHost = "codelab-adapter.codelab.club";
|
||||
}
|
||||
|
||||
this.socket = io(`//${adapterHost}:12358` + "/test", {
|
||||
transports: ["websocket"]
|
||||
});
|
||||
*/
|
||||
const SCRATCH_TOPIC = "from_scratch/extensions"
|
||||
pythonCodeMirror = CodeMirror(
|
||||
document.getElementById("code_playgroud"),
|
||||
{
|
||||
lineNumbers: true,
|
||||
styleActiveLine: true,
|
||||
value: "print('hello world')",
|
||||
mode: "python"
|
||||
}
|
||||
);
|
||||
var theme = "solarized dark";
|
||||
pythonCodeMirror.setOption("theme", theme);
|
||||
|
||||
consoleCodeMirror = CodeMirror(document.getElementById("console"), {
|
||||
//lineNumbers: true,
|
||||
styleActiveLine: true,
|
||||
value: "//Message from codelab-adapter",
|
||||
mode: "javascript" //json
|
||||
});
|
||||
var theme = "solarized dark";
|
||||
consoleCodeMirror.setOption("theme", theme);
|
||||
|
||||
// 监听外部事件
|
||||
function put_console(codeMirror, message) {
|
||||
var now = new Date().toLocaleString();
|
||||
var newcode = ` ${now} ${message}\n${codeMirror.getValue()}`;
|
||||
codeMirror.setValue(newcode);
|
||||
// window.codeMirror = consoleCodeMirror;
|
||||
}
|
||||
const url = new URL(window.location.href);
|
||||
var adapterHost = url.searchParams.get("adapter_host"); // 支持树莓派(分布式使用)
|
||||
if (!adapterHost) {
|
||||
var adapterHost = url.hostname;
|
||||
}
|
||||
|
||||
var socket = io(`//${adapterHost}:12358` + "/test", {
|
||||
transports: ["websocket"]
|
||||
});
|
||||
// socket.emit("actuator", { topic: "eim", message: text.message });
|
||||
socket.on("sensor", msg => {
|
||||
console.log(msg);
|
||||
put_console(consoleCodeMirror, JSON.stringify(msg.message));
|
||||
});
|
||||
|
||||
function send_python_code() {
|
||||
const extension_id = "eim/python";
|
||||
const code = pythonCodeMirror.getValue();
|
||||
const content = code;
|
||||
console.log("python code:\n", code);
|
||||
socket.emit("actuator", { topic: SCRATCH_TOPIC, payload: {content: content,extension_id: extension_id} });
|
||||
}
|
||||
function send_rest_api(){
|
||||
var rest_input = document.getElementById("rest_input").value;
|
||||
var xhr = new XMLHttpRequest();
|
||||
var url = `//${adapterHost}:12358/api/message`
|
||||
xhr.open("POST", url, true);
|
||||
// var sendData = {topic: "eim", payload: "hello"};
|
||||
xhr.setRequestHeader('content-type', 'application/json');
|
||||
//xhr.send(JSON.stringify(sendData));
|
||||
xhr.send(rest_input);
|
||||
}
|
||||
|
||||
function send_eim_message() {
|
||||
//
|
||||
var payload = document.getElementById("eim_input").value;
|
||||
window.message = payload;
|
||||
console.log("eim payload", payload);
|
||||
socket.emit("actuator", JSON.parse(payload));
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
75
src/web_log_page.html
Executable file
75
src/web_log_page.html
Executable file
@ -0,0 +1,75 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>view log</title>
|
||||
|
||||
<script src="https://cdn.bootcss.com/socket.io/2.2.0/socket.io.slim.js"></script>
|
||||
<link
|
||||
href="https://cdn.bootcss.com/codemirror/5.19.0/codemirror.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.bootcss.com/codemirror/5.19.0/codemirror.js"></script>
|
||||
<link
|
||||
href="https://cdn.bootcss.com/codemirror/5.19.0/theme/solarized.min.css"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
</head>
|
||||
<body>
|
||||
<h2><center>view log</center></h2>
|
||||
<p><center style="margin: 15px">新消息出现在顶部(往下滚动)</center></p>
|
||||
<p>grep: <input id="grep" type="text" name="FirstName" value="" /></p>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
consoleCodeMirror = CodeMirror(document.getElementById("console"), {
|
||||
//lineNumbers: true,
|
||||
styleActiveLine: true,
|
||||
value: "//Message from codelab-adapter",
|
||||
mode: "javascript" //json
|
||||
});
|
||||
var theme = "solarized dark";
|
||||
consoleCodeMirror.setOption("theme", theme);
|
||||
|
||||
// 监听外部事件
|
||||
function put_console(codeMirror, message) {
|
||||
var now = new Date().toLocaleString();
|
||||
var newcode = ` ${now} ${message}\n${codeMirror.getValue()}`;
|
||||
codeMirror.setValue(newcode);
|
||||
// window.codeMirror = consoleCodeMirror;
|
||||
}
|
||||
|
||||
// todo 与当前域名一致
|
||||
const url = new URL(window.location.href);
|
||||
var adapterHost = url.searchParams.get("adapter_host"); // 支持树莓派(分布式使用)
|
||||
if (!adapterHost) {
|
||||
var adapterHost = url.hostname;
|
||||
}
|
||||
|
||||
socket = io(`//${adapterHost}:12358` + "/all_zmq_message", {
|
||||
transports: ["websocket"]
|
||||
});
|
||||
// socket.emit("actuator", { topic: "eim", message: text.message });
|
||||
socket.on("view_log", msg => {
|
||||
// console.log(msg.message); // ok
|
||||
var string_message = JSON.stringify(msg.message);
|
||||
console.log(string_message);
|
||||
var grep = document.getElementById("grep").value;
|
||||
window.grep = grep;
|
||||
window.string_message = string_message;
|
||||
if (!grep) {
|
||||
// 如果没有grep条件,则打印全部
|
||||
put_console(consoleCodeMirror, string_message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (string_message.includes(grep)) {
|
||||
// 如果有grep条件,打印过滤之后的
|
||||
put_console(consoleCodeMirror, string_message);
|
||||
return;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
249
src/webui.html
Executable file
249
src/webui.html
Executable file
@ -0,0 +1,249 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
vue:
|
||||
https://cn.vuejs.org/v2/guide/list.html
|
||||
|
||||
websocket:
|
||||
https://codepen.io/louisjordan/pen/NggLBQ
|
||||
https://www.jianshu.com/p/9d8b2e42328c
|
||||
-->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<script src="/static/vue.min.js"></script>
|
||||
<script src="/static/socket.io.slim.js"></script>
|
||||
<link rel="stylesheet" href="/static/normalize.css" />
|
||||
<link rel="stylesheet" href="/static/element-ui_2_12_0_index.css" />
|
||||
<script src="/static/element-ui_2_12_0_index.js"></script>
|
||||
<link rel="shortcut icon" href="/static/favicon.ico" />
|
||||
<title>CodeLab Adapter Web UI</title>
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
body {
|
||||
background-color: white;
|
||||
}
|
||||
section {
|
||||
text-align: center;
|
||||
min-width: 500px;
|
||||
}
|
||||
header {
|
||||
padding: 20px 0;
|
||||
background-color: #4e97fe;
|
||||
color: white;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0px 1px 4px 1px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
header div.container {
|
||||
width: 500px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
div.links {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 15px;
|
||||
}
|
||||
div.link a {
|
||||
font-size: 13px;
|
||||
color: white;
|
||||
margin: 0 12px;
|
||||
}
|
||||
div.extensions {
|
||||
padding-top: 10px;
|
||||
}
|
||||
div.extension {
|
||||
margin: 0 auto;
|
||||
width: 500px;
|
||||
padding: 5px 90px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<section id="app">
|
||||
<header>
|
||||
<div class="container">
|
||||
<h2>CodeLab Adapter v2 Web UI</h2>
|
||||
<p>status: {{ status }}</p>
|
||||
<p>version: {{ version }}</p>
|
||||
<el-button round v-on:click="exit_adapter_app"
|
||||
>exit</el-button
|
||||
>
|
||||
<div class="links">
|
||||
<div class="link" v-for="(url, link_name) in links">
|
||||
<a target="_blank" :href="url">{{ link_name }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div id="extension-list">
|
||||
<div class="extensions">
|
||||
<div
|
||||
class="extension"
|
||||
v-for="(statu, extension) in extensions_statu"
|
||||
>
|
||||
<label for="extension">{{ extension }} </label>
|
||||
<el-switch
|
||||
id="extension"
|
||||
@change="check($event, extension)"
|
||||
v-model="extensions_statu[extension]"
|
||||
>
|
||||
</el-switch>
|
||||
</div>
|
||||
</div>
|
||||
<ul id="logs">
|
||||
<li v-for="log in logs.slice().reverse()" class="log">
|
||||
{{ log.event }}: {{ log.data }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
<script>
|
||||
const ADAPTER_TOPIC = "adapter/extensions/data";
|
||||
const SCRATCH_TOPIC = "scratch/extensions/command";
|
||||
const EXTENSIONS_OPERATE_TOPIC = "core/extensions/operate";
|
||||
const NODES_OPERATE_TOPIC = "core/nodes/operate";
|
||||
const EXTENSIONS_STATUS_TOPIC = "core/extensions/status";
|
||||
const ADAPTER_STATUS_TOPIC = "core/status";
|
||||
const EXTENSIONS_STATUS_TRIGGER_TOPIC =
|
||||
"core/extensions/status/trigger";
|
||||
const EXTENSION_STATU_CHANGE_TOPIC = "core/extension/statu/change";
|
||||
const NOTIFICATION_TOPIC = "core/notification";
|
||||
|
||||
const EXTENSION_ID = "eim";
|
||||
const extensions_bar = new Vue({
|
||||
el: "#app",
|
||||
data: {
|
||||
logs: [],
|
||||
status: "disconnected", // connected
|
||||
version: "",
|
||||
//checkedExtensions: [],
|
||||
//extensions: ["extension_eim", "extension_eim2"],
|
||||
extensions_statu: {},
|
||||
links: {
|
||||
webdebug: "/webdebug",
|
||||
"view log": "/web_log_page",
|
||||
scratch3: "https://scratch3v2.codelab.club"
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
exit_adapter_app: function(event) {
|
||||
let turn = "stop";
|
||||
const message = {
|
||||
topic: NODES_OPERATE_TOPIC,
|
||||
payload: {
|
||||
content: turn,
|
||||
extension_id: "adapter/app"
|
||||
}
|
||||
};
|
||||
this.socket.emit("actuator", message);
|
||||
},
|
||||
check: function(state, extension) {
|
||||
// console.log(`${e.target.value} ${e.target.checked}`);
|
||||
console.log(`${extension} ${state}`);
|
||||
const extension_name = extension;
|
||||
let turn;
|
||||
if (state === true) {
|
||||
turn = "start";
|
||||
console.log("start");
|
||||
} else {
|
||||
turn = "stop";
|
||||
console.log("stop");
|
||||
}
|
||||
|
||||
const message = {
|
||||
topic: EXTENSIONS_OPERATE_TOPIC,
|
||||
payload: {
|
||||
content: turn,
|
||||
extension_id: EXTENSION_ID,
|
||||
extension_name: extension_name
|
||||
}
|
||||
};
|
||||
this.socket.emit("actuator", message);
|
||||
},
|
||||
connect() {
|
||||
const url = new URL(window.location.href);
|
||||
var adapterHost = url.searchParams.get("adapter_host"); // 支持树莓派(分布式使用)
|
||||
if (!adapterHost) {
|
||||
var adapterHost = url.hostname;
|
||||
}
|
||||
|
||||
this.socket = io(`//${adapterHost}:12358` + "/test", {
|
||||
transports: ["websocket"]
|
||||
});
|
||||
|
||||
this.socket.on("connect", () => {
|
||||
// 触发一次发布插件状态的请求
|
||||
|
||||
const message = {
|
||||
topic: EXTENSIONS_STATUS_TRIGGER_TOPIC,
|
||||
payload: {
|
||||
content: "EXTENSIONS_STATUS_TRIGGER_TOPIC"
|
||||
}
|
||||
};
|
||||
this.socket.emit("actuator", message);
|
||||
this.status = "connected!";
|
||||
});
|
||||
this.socket.on("disconnect", reason => {
|
||||
this.status = `disconnect! ${reason}`;
|
||||
});
|
||||
// onconnect: status
|
||||
// socket.emit("actuator", { topic: "eim", message: text.message });
|
||||
this.extensions_statu = {};
|
||||
const status_checked_map = { start: true, stop: false };
|
||||
this.socket.on("sensor", msg => {
|
||||
console.log("recv:", msg.message);
|
||||
if (
|
||||
msg.message.topic ===
|
||||
EXTENSION_STATU_CHANGE_TOPIC
|
||||
) {
|
||||
// todo 开始主动获取一次
|
||||
// update extension status(start/stop open/close)
|
||||
const extension_name =
|
||||
msg.message.payload.extension_name;
|
||||
const content = msg.message.payload.content;
|
||||
this.extensions_statu[extension_name] =
|
||||
status_checked_map[content];
|
||||
console.log(
|
||||
`${extension_name} statu change to ${content}`
|
||||
);
|
||||
|
||||
// update extension status. start/stop
|
||||
}
|
||||
|
||||
if (msg.message.topic === EXTENSIONS_STATUS_TOPIC) {
|
||||
const content = msg.message.payload.content;
|
||||
this.extensions_statu = content;
|
||||
}
|
||||
if (msg.message.topic === NOTIFICATION_TOPIC) {
|
||||
const content = msg.message.payload.content;
|
||||
console.log("notification:", content);
|
||||
alert(content);
|
||||
}
|
||||
if (msg.message.topic === ADAPTER_STATUS_TOPIC) {
|
||||
const content = msg.message.payload.content;
|
||||
console.log("adapter info:", content);
|
||||
this.version = content.version;
|
||||
}
|
||||
|
||||
/*
|
||||
this.logs.push({
|
||||
event: "receive message",
|
||||
data: msg.message
|
||||
});
|
||||
*/
|
||||
});
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
// init
|
||||
this.connect();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user