commit
360287fedf
3 changed files with 448 additions and 0 deletions
-
BIN.DS_Store
-
19config.js
-
429index.html
@ -0,0 +1,19 @@ |
|||||
|
const websocketAddress = "ws://localhost:8888/websocket/123"; |
||||
|
const config = { |
||||
|
你好: "123", |
||||
|
b: "1231231", |
||||
|
}; |
||||
|
|
||||
|
const commonMessage = { |
||||
|
protocol: "iflytopCanProtocolStackV1", |
||||
|
message: { |
||||
|
attribute: "normal", |
||||
|
priority: 4, |
||||
|
type: "write", |
||||
|
targetId: 130, |
||||
|
sourceId: 1, |
||||
|
seq: 0, |
||||
|
ctrlPointAddr: 10500, |
||||
|
ctrlPointVal: 1, |
||||
|
}, |
||||
|
}; |
@ -0,0 +1,429 @@ |
|||||
|
<!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; |
||||
|
} |
||||
|
.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; |
||||
|
flex: 0.6; |
||||
|
padding: 24px; |
||||
|
overflow: scroll; |
||||
|
} |
||||
|
.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; |
||||
|
} |
||||
|
.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; |
||||
|
} |
||||
|
</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="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="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> |
||||
|
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 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 connectWs = () => { |
||||
|
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) { |
||||
|
console.log(evt.data); |
||||
|
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 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 = ctrlPointVal; |
||||
|
} |
||||
|
if (type == "report") { |
||||
|
reportAddress.value = ctrlPointAddr; |
||||
|
reportVal.value = ctrlPointVal; |
||||
|
} |
||||
|
} catch (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 { |
||||
|
protocol, |
||||
|
message: { |
||||
|
...message, |
||||
|
targetId: id.value, |
||||
|
ctrlPointAddr: base.value + off.value, |
||||
|
ctrlPointVal: 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); |
||||
|
}; |
||||
|
</script> |
||||
|
</html> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue