You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <style> *, html, body { margin: 0; padding: 0; box-sizing: border-box; } li { list-style: none; } .container { display: flex; width: 100vw; align-items: center; box-sizing: border-box; justify-content: space-between; } .left_chat { border: solid 1px #000; height: 100vh; display: flex; box-sizing: border-box; flex-direction: column; padding: 24px; overflow: scroll; width: 500px; min-width: 500px; } .right_message { height: 100vh; box-sizing: border-box; flex: 1; } .btn { padding: 36px; font-size: 24px; margin-top: 24px; width: 100%; } .right_message { padding: 24px; border: solid 1px #000; display: flex; flex-direction: column; } .message_wrap { flex: 1; border: solid 1px #ddd; overflow: scroll; } .message { padding: 6px 8px; border-bottom: solid 1px #ddd; } .input_wrap { display: flex; align-items: center; /* margin-bottom: 20px; */ } .input_wrap .ws_connnect { flex: 2; padding: 4px 0; margin-right: 20px; } .input_wrap .connect { flex: 1; } .order { display: grid; grid-template-columns: repeat(1, 1fr); column-gap: 20px; row-gap: 10px; margin-bottom: 20px; } .status { padding: 4px 0; border-bottom: solid 2px #ddd; margin-bottom: 10px; } .tabs { margin: 20px 0; }
.tab-bar { display: flex; }
.tab { padding: 10px 20px; border: 1px solid #ccc; border-bottom: none; cursor: pointer; }
/* .active { border-bottom: 2px solid blue; } */
.tab-panel { display: none; padding: 20px; border: 1px solid #ccc; }
.active { display: block; }
.common_order_input { display: flex; align-items: center; justify-content: space-evenly; padding: 0 20px; margin-bottom: 10px; } .common_order_input .single { display: flex; flex-direction: column; align-items: center; } .single .input { width: 100%; text-align: center; padding: 4px; } .common_btns { width: 100%; } .btn_c { width: 100%; padding: 4px 0; margin-bottom: 10px; } .report_c { border: solid 1px #ddd; padding: 10px; } .form_line { display: flex; align-items: center; width: 100%; margin-bottom: 10px; } .form_line .tit { margin-right: 6px; white-space: nowrap; } .form_line .info { width: 100%; text-align: center; padding: 4px 0; } .report_c .title { border-bottom: solid 1px #ddd; margin-bottom: 10px; }
.mod-tab .tab_top { float: left; padding: 5px 20px; border-top: 1px solid #ccc; border-left: 1px solid #ccc; background-color: #ddd; } .header .tab_top:last-child { border-right: 1px solid #ccc; } .content { border: 1px solid #ccc; width: 100%; height: 100%; } .header::after { content: ""; display: block; clear: both; }
.mod-tab .header .active { background-color: #fff; }
.mod-tab .content .panel { display: none; } .mod-tab .content .active { display: block; }
.card_container { padding: 0 10px; } .card_container .title { margin-bottom: 10px; border-bottom: solid 1px #ddd; } .card_container .form { display: flex; margin-bottom: 10px; align-items: center; justify-content: space-between; } .card_container .form .label { white-space: nowrap; margin-right: 10px; } .card_container .form .input { flex: 1; padding: 4px 0; text-align: center; } .card_container .form .btn { padding: 0; margin: 0; width: 40px; margin-left: 10px; } .card_container .form .input_config { width: 60px; padding: 4px 0; text-align: center; } </style> </head> <body> <div class="container"> <div class="left_chat"> <div class="input_wrap"> <input type="text" class="ws_connnect" id="ws_connnect_input" /> <button class="connect" onclick="connectWs()">连接</button> </div> <p class="status" id="status">当前状态: 未连接</p> <div class="mod-tab"> <div class="header"> <button class="tab_top active button1">基本控制</button> <button class="tab_top button2">电机控制</button> <button class="tab_top button3">舵机控制</button> </div> <div class="content"> <div class="panel active"> <div class="report_c"> <p class="title">上报解析</p> <div class="form_line"> <p class="tit">ADDRESS:</p> <input type="text" class="info" disabled id="report_address" /> </div> <div class="form_line"> <p class="tit">VALUE:</p> <input type="text" class="info" disabled id="report_val" /> </div> </div> <div class="report_c"> <p class="title">回执解析</p> <div class="form_line"> <p class="tit">ADDRESS:</p> <input type="text" class="info" disabled id="receipt_address" /> </div> <div class="form_line"> <p class="tit">VALUE:</p> <input type="text" class="info" disabled id="receipt_val" /> </div> <div class="form_line"> <p class="tit">结果:</p> <input type="text" class="info" value="无" disabled id="receipt_message" /> </div> </div> <div class="tabs"> <ul class="tab-bar"> <li class="tab active">通用指令</li> <li class="tab">指令列表</li> </ul> <div class="tab-content"> <div class="tab-panel active"> <div class="common_order_input"> <div class="single"> <p>ID</p> <input type="text" class="input" id="common_id" /> </div> <div class="single" style="margin-left: 10px; margin-right: 5px" > <p>BASE</p> <input type="text" class="input" id="common_base" /> </div> <div class="single" style="margin-left: 5px; margin-right: 10px" > <p>OFFSET</p> <input type="text" class="input" id="common_off" /> </div> <div class="single"> <p>VALUE</p> <input type="text" class="input" id="common_value" /> </div> </div> <div class="common_btns"> <button class="btn_c" onclick="writeFun()">写</button> <button class="btn_c" onclick="read()">读</button> <button class="btn_c" onclick="autoReport()"> 使能自动上报 </button> <button class="btn_c" onclick="reportCycle()"> 设置上报周期 </button> </div> </div> <div class="tab-panel"> <div class="order" id="order"></div> </div> </div> </div> </div> <div class="panel"> <div class="common_order_input" style="border-bottom: solid 2px #ddd; padding-bottom: 10px" > <div class="single"> <p>ID</p> <input type="text" class="input" /> </div> <div class="single" style="margin-left: 10px; margin-right: 5px" > <p>BASE</p> <input type="text" class="input" /> </div> <div class="single" style="margin-left: 5px; margin-right: 10px" > <p>OFFSET</p> <input type="text" class="input" /> </div> </div> <div class="card_container"> <h3 class="title">状态</h3> <div class="form"> <p class="label">异常</p> <input type="text" class="input" /> <button class="btn">读</button> </div> <div class="form"> <p class="label">状态</p> <input type="text" class="input" /> <button class="btn">读</button> </div> <div class="form"> <p class="label">位置</p> <input type="text" class="input" /> <button class="btn">读</button> </div> </div> <div class="card_container"> <h3 class="title">配置</h3> <div class="form"> <p class="label">反复运动启始位置</p> <input type="text" class="input_config" /> <button class="btn">读</button> <button class="btn">写</button> </div> <div class="form"> <p class="label">反复运动终止位置</p> <input type="text" class="input_config" /> <button class="btn">读</button> <button class="btn">写</button> </div> <div class="form"> <p class="label">运行时速度配置</p> <input type="text" class="input_config" /> <button class="btn">读</button> <button class="btn">写</button> </div> </div> <div class="card_container"> <h3 class="title">动作</h3> <div class="form"> <p class="label">舵机移动到角度</p> <input type="text" class="input" /> <button class="btn">写</button> </div> <div class="form"> <p class="label">舵机停止</p> <input type="text" class="input" /> <button class="btn">写</button> </div> <div class="form"> <p class="label">清除异常</p> <input type="text" class="input" /> <button class="btn">写</button> </div> <div class="form"> <p class="label">反复运动</p> <input type="text" class="input" /> <button class="btn">写</button> </div> </div> </div> <div class="panel"> <div class="common_order_input" style="border-bottom: solid 2px #ddd; padding-bottom: 10px" > <div class="single"> <p>ID</p> <input type="text" class="input" /> </div> <div class="single" style="margin-left: 10px; margin-right: 5px" > <p>BASE</p> <input type="text" class="input" /> </div> <div class="single" style="margin-left: 5px; margin-right: 10px" > <p>OFFSET</p> <input type="text" class="input" /> </div> </div> <div class="card_container"> <h3 class="title">状态</h3> <div class="form"> <p class="label">设备状态</p> <input type="text" class="input" /> <button class="btn">读</button> </div> <div class="form"> <p class="label">异常状态</p> <input type="text" class="input" /> <button class="btn">读</button> </div> <div class="form"> <p class="label">当前转速</p> <input type="text" class="input" /> <button class="btn">读</button> </div> <div class="form"> <p class="label">当前位置</p> <input type="text" class="input" /> <button class="btn">读</button> </div> </div> <div class="card_container"> <h3 class="title">配置</h3> <div class="form"> <p class="label">加速度</p> <input type="text" class="input_config" /> <button class="btn">读</button> <button class="btn">写</button> </div> <div class="form"> <p class="label">减速度</p> <input type="text" class="input_config" /> <button class="btn">读</button> <button class="btn">写</button> </div> <div class="form"> <p class="label">速度</p> <input type="text" class="input_config" /> <button class="btn">读</button> <button class="btn">写</button> </div> <div class="form"> <p class="label">零点偏移</p> <input type="text" class="input_config" /> <button class="btn">读</button> <button class="btn">写</button> </div> <div class="form"> <p class="label">归零速度</p> <input type="text" class="input_config" /> <button class="btn">读</button> <button class="btn">写</button> </div> <div class="form"> <p class="label">归零减速度</p> <input type="text" class="input_config" /> <button class="btn">读</button> <button class="btn">写</button> </div> <div class="form"> <p class="label">归零最大位移</p> <input type="text" class="input_config" /> <button class="btn">读</button> <button class="btn">写</button> </div> <div class="form"> <p class="label">归零第一阶段移动距离</p> <input type="text" class="input_config" /> <button class="btn">读</button> <button class="btn">写</button> </div> </div> <div class="card_container"> <h3 class="title">动作</h3> <div class="form"> <p class="label">速度模式控制</p> <input type="text" class="input" /> <button class="btn">写</button> </div> <div class="form"> <p class="label">位置模式控制</p> <input type="text" class="input" /> <button class="btn">写</button> </div> <div class="form"> <p class="label">位置模式相对位置</p> <input type="text" class="input" /> <button class="btn">写</button> </div> <div class="form"> <p class="label">归零</p> <input type="text" class="input" /> <button class="btn">写</button> </div> <div class="form"> <p class="label">零位校准</p> <input type="text" class="input" /> <button class="btn">写</button> </div> <div class="form"> <p class="label">停止</p> <input type="text" class="input" /> <button class="btn">写</button> </div> <div class="form"> <p class="label">清空异常</p> <input type="text" class="input" /> <button class="btn">写</button> </div> </div> </div> </div> </div> </div> <div class="right_message"> <div class="message_wrap" id="message_wrap"></div> <div style="display: flex; align-items: center; margin-top: 10px"> <textarea style="flex: 1" name="bio" rows="15" cols="40"></textarea> <div style="display: flex; flex-direction: column; height: 100%"> <button style="flex: 1" onclick="sendMessage()">发送</button> <button style="flex: 1" onclick="clearTextArea()">清空</button> </div> </div> </div> </div> </body> <script src="./config.js"></script> <script> window.onload = () => { const commonI = document.querySelector("#common_id"); const commonB = document.querySelector("#common_base"); commonI.value = localStorage.getItem("id"); commonB.value = localStorage.getItem("base"); }; var ws = null; const websocketInput = document.querySelector("#ws_connnect_input"); websocketInput.value = websocketAddress; // 先向order下动态添加指令集合 const order = document.querySelector("#order");
for (let key in config) { const button = document.createElement("button"); button.textContent = key; button.className = "order_btn"; button.setAttribute("v", key); order?.appendChild(button); }
order.addEventListener("click", (e) => { const item = e.target; if (item && item.getAttribute("v")) { const key = item.getAttribute("v"); sendOrder(config[key]); } });
const commonI = document.querySelector("#common_id"); const commonB = document.querySelector("#common_base"); commonI.addEventListener("input", (e) => { localStorage.setItem("id", e.target.value); }); commonB.addEventListener("input", (e) => { localStorage.setItem("base", e.target.value); });
const tabs = document.querySelector(".tabs"); const tabBars = document.querySelectorAll(".tab-bar .tab"); const tabPanels = document.querySelectorAll(".tab-content .tab-panel");
for (let i = 0; i < tabBars.length; i++) { tabBars[i].onclick = function () { removeActive(); this.classList.add("active"); tabPanels[i].classList.add("active"); }; }
function removeActive() { for (let i = 0; i < tabBars.length; i++) { tabBars[i].classList.remove("active"); tabPanels[i].classList.remove("active"); } } const clearMessage = () => { const messageWrap = document.querySelector("#message_wrap"); messageWrap.innerHTML = ""; }; const clearTextArea = () => { const textArea = document.querySelector("textarea"); textArea.value = ""; clearMessage(); }; const sendMessage = () => { if (ws) { const textArea = document.querySelector("textarea"); const messageVal = textArea.value; ws.send(messageVal); const messageWrap = document.querySelector("#message_wrap"); const div = document.createElement("div"); div.classList = ["message"]; div.textContent = `Tx: ${messageVal}`; messageWrap.appendChild(div); messageWrap.scrollTop = messageWrap.scrollHeight - messageWrap.clientHeight; } else { } };
const transValToName = (val) => { switch (val) { case 0x00: return "kSuccess"; case 2: return "kRegNotFound"; case 3: return "kRegNotWritable"; case 4: return "kRegNotReadable"; case 5: return "kIllegalValue"; case 6: return "kDeviceBusy"; case 7: return "kDeviceException"; case 8: return "kChannelDeviceException"; case 9: return "kParameterError"; case 10: return "kOvertime"; case 11: return "kOperationInvalid"; case 12: return "kunsupportOperation"; case 13: return "kIllegalOperation"; case 14: return "kPermissionDenied"; case 15: return "koutOfRange"; case 16: return "kmotorNotRunToHome"; case 17: return "kParameterOutOfLimit"; } }; const connectWs = () => { console.log(123); const input = document.querySelector("#ws_connnect_input"); const status = document.querySelector("#status"); const address = input.value; try { ws = new WebSocket(address); ws.onopen = function () { console.log("Connected to WebSocket server."); // 改变状态 status.innerHTML = `当前状态: 已连接${address}`; };
ws.onmessage = function (evt) { const messageWrap = document.querySelector("#message_wrap"); const div = document.createElement("div"); div.classList = ["message"]; div.textContent = `Rx: ${evt.data}`; messageWrap.appendChild(div); messageWrap.scrollTop = messageWrap.scrollHeight - messageWrap.clientHeight; // 对消息进行处理 try { const { message: messageBody } = JSON.parse(evt.data); const { type, ctrlPointAddr, ctrlPointVal } = messageBody; const receiptMessage = document.querySelector("#receipt_message"); const receiptAddress = document.querySelector("#receipt_address"); const receiptVal = document.querySelector("#receipt_val"); const reportAddress = document.querySelector("#report_address"); const reportVal = document.querySelector("#report_val"); if (type == "receipt") { receiptMessage.value = "正确"; receiptAddress.value = ctrlPointAddr; receiptVal.value = ctrlPointVal; } if (type == "error_receipt") { receiptMessage.value = "错误"; receiptAddress.value = ctrlPointAddr; // 错误回执需要吧值和英文进行对应 receiptVal.value = transValToName(ctrlPointVal); } if (type == "report") { reportAddress.value = ctrlPointAddr; reportVal.value = ctrlPointVal; } } catch (error) { console.log(error); } };
ws.onclose = function () { status.innerHTML = `当前状态: 已关闭`; }; } catch (error) { status.innerHTML = `当前状态: 连接错误`; } }; const sendOrder = (msg) => { if (ws) { ws.send(msg); const messageWrap = document.querySelector("#message_wrap"); const div = document.createElement("div"); div.classList = ["message"]; div.textContent = `Tx: ${msg}`; messageWrap.appendChild(div); messageWrap.scrollTop = messageWrap.scrollHeight - messageWrap.clientHeight; } };
const getCommonOrderInput = (type) => { const id = document.querySelector("#common_id"); const base = document.querySelector("#common_base"); const off = document.querySelector("#common_off"); const value = document.querySelector("#common_value"); const { protocol, message } = commonMessage; return JSON.stringify({ protocol, message: { ...message, targetId: parseInt(id.value), ctrlPointAddr: parseInt(base.value) + parseInt(off.value), ctrlPointVal: parseInt(value.value), type, }, }); };
const writeFun = () => { const msg = getCommonOrderInput("write"); sendOrder(msg); }; const read = () => { const msg = getCommonOrderInput("read"); sendOrder(msg); }; const autoReport = () => { const msg = getCommonOrderInput("set_auto_report_enable_flag"); sendOrder(msg); }; const reportCycle = () => { const msg = getCommonOrderInput("set_auto_report_period"); sendOrder(msg); };
document.querySelectorAll(".tab_top").forEach(function (node) { node.addEventListener("click", function () { var index; this.parentElement .querySelectorAll(".tab_top") .forEach(function (e, inx) { //e.style.display='none' 跳转的时候隐藏按钮 e.classList.remove("active"); if (node === e) { index = inx; } }); this.classList.add("active"); this.parentElement.nextElementSibling .querySelectorAll(".panel") .forEach(function (panel) { panel.classList.remove("active"); }); this.parentElement.nextElementSibling .querySelectorAll(".panel") [index].classList.add("active"); }); }); </script> </html>
|