Commit dd14a1ab by qianmo

Merge remote-tracking branch 'origin/main'

# Conflicts:
#	xdc.sqlite
parents 9d3134e3 3e88f29b
......@@ -11,6 +11,8 @@ router.register('device_communication/simulate_communicate',
urlpatterns = [
re_path(r'^device_communication/$', views.get_protocol_names),
re_path(r'^device_communication/protocol_performance/(?P<protocol_name>.+)/$', views.get_protocol_field_names),
re_path(r'^device_communication/performance/(?P<type>.+)/(?P<protocol_name>.+)/$',
views.get_checked_field_names),
re_path(r'^device_communication/set_communication_to_devinfo_table/$',
views.set_communication_to_devinfo_table),
]
......
import json
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
......@@ -40,6 +41,25 @@ def get_protocol_field_names(request, protocol_name):
return Response(data=res_data, status=status.HTTP_200_OK)
@api_view(['GET'])
def get_checked_field_names(request, type, protocol_name):
"""
获取指定指令下选择监控的字段
"""
# 获取该协议下的指令集合
if type == '1':
manager = DeviceCommunicationParameter.objects
else:
manager = SimulateDeviceCommunicationParameter.objects
cmds = manager.filter(protocol_name=protocol_name).all()
cmd_set = set()
for cmd in cmds:
performance_fields = json.loads(cmd.performance_fields)
cmd_set.update(performance_fields)
return Response(data=cmd_set, status=status.HTTP_200_OK)
@api_view(['POST'])
def set_communication_to_devinfo_table(request):
"""
......
......@@ -18,7 +18,7 @@
v-for="(item, index) in tableHeader"
:key="index"
:prop="item"
:fixed="isTitleColumn ? 'left' : ''"
:fixed="isTitleColumn"
>
</el-table-column>
</el-table>
......@@ -95,7 +95,9 @@ watch( () => props.tag, (newValue) => {
}
})
const isTitleColumn = (column: any) => column.property === 'title'
const isTitleColumn = (column: any): string => {
return column.property === 'title'? 'left' : ''
}
</script>
<style scoped>
......
<template>
<div class="w-48% float-left border-solid border-black border-1">
<el-scrollbar ref="scrollbarRef" style="height: 30rem;" class="mb-10" always>
<div ref="innerRef">
<p v-for="item in items" :key="item" class="scrollbar-demo-item text-sm">
<div>{{ JSON.parse(item)?.ts }}</div>
{{ item }}
</p>
</div>
</el-scrollbar>
<div>
<el-input style="width: 80%;" v-model="input" placeholder="Please input" @keyup.enter="send" />
<el-button class="ml-4" @click="send">Send</el-button>
</div>
</div>
<div class="w-50% float-right border-solid border-black border-1">
<el-scrollbar style="height: 30rem;" class="mb-10" always>
<device-performance-table
v-for="param in deviceTableParams"
mt-5
:dev-name="param.devName"
:protocol-name="param.protocolName"
:group-name="param.key"
:key="param.key"
@delete-table="deleteDeviceInfo(param)" />
</el-scrollbar>
<el-button @click="dialogVisible = true">Add table</el-button>
</div>
<el-dialog class="w-150" v-model="dialogVisible" title="Select device">
<el-select class="w-100" v-model="selectedDeviceName">
<el-option v-for="deviceInfo in deviceInfos" :key="deviceInfo.dev_name" :label="deviceInfo.dev_name" :value="deviceInfo.dev_name" />
</el-select>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">Cancel</el-button>
<el-button type="primary" @click="addDeviceTable">
Confirm
</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, onMounted, watch, onBeforeUnmount } from 'vue';
import { ElScrollbar, ElInput, ElButton, ElSelect, ElOption, ElMessage } from 'element-plus';
import DevicePerformanceTable from '@/components/home/DevicePerformanceTabel'
import axios from 'axios';
const innerRef = ref<HTMLDivElement>();
const scrollbarRef = ref<InstanceType<typeof ElScrollbar>>();
const input = ref('');
const items = ref<string[]>([
JSON.stringify([{ "CMDS": "$,", "Xaxis": "034.00", "Comma": ",", "Yaxis": "034.00", "Azimuth": "000.00", "ElevationAngle": "090.00", "ACUstatus": "P", "XTrackerSigIntensity": "255", "YTrackerSigIntensity": "255", "X_STATUS": "244", "Y_STATUS": "245", "XInitPhase": "012", "XPolarizationType": "1", "SPolarizationType": "0", "XTrackerVoltageLimit": "255", "STrackerVoltageLimit": "255", "SUpPolarizationType": "1", "XUpPolarizationType": "1", "TrackingStatus": "0", "TrackingBand": "1", "X-Bias": "+0.00", "Y-Bias": "+0.00", "END": "\r\n", "XaxisAlarm": "0", "XaxisServoStatus": "1", "EasternLimit": "0", "WestLimit": "0", "YaxisAlarm": "0", "YaxisServoStatus": "1", "SouthrLimit": "0", "NorthLimit": "1" }]),
JSON.stringify([{ "CMDS": "$,", "Xaxis": "034.00", "Comma": ",", "Yaxis": "034.00", "Azimuth": "000.00", "ElevationAngle": "090.00", "ACUstatus": "P", "XTrackerSigIntensity": "255", "YTrackerSigIntensity": "255", "X_STATUS": "244", "Y_STATUS": "245", "XInitPhase": "012", "XPolarizationType": "1", "SPolarizationType": "0", "XTrackerVoltageLimit": "255", "STrackerVoltageLimit": "255", "SUpPolarizationType": "1", "XUpPolarizationType": "1", "TrackingStatus": "0", "TrackingBand": "1", "X-Bias": "+0.00", "Y-Bias": "+0.00", "END": "\r\n", "XaxisAlarm": "0", "XaxisServoStatus": "1", "EasternLimit": "0", "WestLimit": "0", "YaxisAlarm": "0", "YaxisServoStatus": "1", "SouthrLimit": "0", "NorthLimit": "1" }]),
JSON.stringify([{ "CMDS": "$,", "Xaxis": "034.00", "Comma": ",", "Yaxis": "034.00", "Azimuth": "000.00", "ElevationAngle": "090.00", "ACUstatus": "P", "XTrackerSigIntensity": "255", "YTrackerSigIntensity": "255", "X_STATUS": "244", "Y_STATUS": "245", "XInitPhase": "012", "XPolarizationType": "1", "SPolarizationType": "0", "XTrackerVoltageLimit": "255", "STrackerVoltageLimit": "255", "SUpPolarizationType": "1", "XUpPolarizationType": "1", "TrackingStatus": "0", "TrackingBand": "1", "X-Bias": "+0.00", "Y-Bias": "+0.00", "END": "\r\n", "XaxisAlarm": "0", "XaxisServoStatus": "1", "EasternLimit": "0", "WestLimit": "0", "YaxisAlarm": "0", "YaxisServoStatus": "1", "SouthrLimit": "0", "NorthLimit": "1" }]),
JSON.stringify([{ "CMDS": "$,", "Xaxis": "034.00", "Comma": ",", "Yaxis": "034.00", "Azimuth": "000.00", "ElevationAngle": "090.00", "ACUstatus": "P", "XTrackerSigIntensity": "255", "YTrackerSigIntensity": "255", "X_STATUS": "244", "Y_STATUS": "245", "XInitPhase": "012", "XPolarizationType": "1", "SPolarizationType": "0", "XTrackerVoltageLimit": "255", "STrackerVoltageLimit": "255", "SUpPolarizationType": "1", "XUpPolarizationType": "1", "TrackingStatus": "0", "TrackingBand": "1", "X-Bias": "+0.00", "Y-Bias": "+0.00", "END": "\r\n", "XaxisAlarm": "0", "XaxisServoStatus": "1", "EasternLimit": "0", "WestLimit": "0", "YaxisAlarm": "0", "YaxisServoStatus": "1", "SouthrLimit": "0", "NorthLimit": "1" }]),
JSON.stringify([{ "CMDS": "$,", "Xaxis": "034.00", "Comma": ",", "Yaxis": "034.00", "Azimuth": "000.00", "ElevationAngle": "090.00", "ACUstatus": "P", "XTrackerSigIntensity": "255", "YTrackerSigIntensity": "255", "X_STATUS": "244", "Y_STATUS": "245", "XInitPhase": "012", "XPolarizationType": "1", "SPolarizationType": "0", "XTrackerVoltageLimit": "255", "STrackerVoltageLimit": "255", "SUpPolarizationType": "1", "XUpPolarizationType": "1", "TrackingStatus": "0", "TrackingBand": "1", "X-Bias": "+0.00", "Y-Bias": "+0.00", "END": "\r\n", "XaxisAlarm": "0", "XaxisServoStatus": "1", "EasternLimit": "0", "WestLimit": "0", "YaxisAlarm": "0", "YaxisServoStatus": "1", "SouthrLimit": "0", "NorthLimit": "1" }]),
]);
const flag = ref<boolean>(false);
let chatSocket: WebSocket | null = null;
const send = () => {
if (chatSocket === null) {
console.error('chatSocket is null');
return;
}
chatSocket.send(JSON.stringify({
'message': input.value
}));
input.value = '';
}
watch(flag, () => {
setTimeout(() => {
scrollbarRef.value!.setScrollTop(innerRef.value!.offsetHeight);
}, 50);
});
onMounted(() => {
chatSocket = new WebSocket(
'ws://'
+ window.location.host
+ '/ws/chat/mqtt/'
);
chatSocket.onmessage = (e) => {
// console.log(e);
// console.log(e.data)
// // 接收到的是字节流数据(ArrayBuffer)
// const byteArray = new Uint8Array(e.data);
// // 将字节流转换为字符串或其他格式进行处理
// const message = byteArray.toString();
// items.value.push(JSON.stringify(e.data));
items.value.push(e.data);
flag.value = !flag.value
};
chatSocket.onclose = (e) => {
console.error('Chat socket closed unexpectedly', e);
};
axios.get('/api/xpro_all_devinfo/')
.then((res) => {
deviceInfos.value = res.data
})
.catch((err) => {
console.log(err);
})
})
onBeforeUnmount(() => {
chatSocket?.close();
})
// 添加设备监控操作
const deviceInfos = ref<any[]>([]);
const selectedDeviceName = ref<string>('')
const dialogVisible = ref<boolean>(false);
type MonitorType = {
key: string
protocolName: string
devName: string
}
const deviceTableParams = ref<MonitorType[]>([]);
const addDeviceTable = () => {
if (deviceInfos.value.length === 0) {
ElMessage.warning('input invalid');
return;
}
for (let deviceInfo of deviceInfos.value) {
if (deviceInfo.dev_name === selectedDeviceName.value) {
if ((deviceInfo.comunitate_mode as string).toUpperCase().includes('TCP')) {
deviceTableParams.value.push({
key: (deviceInfo.tcp_port).toString(),
protocolName: deviceInfo.protocol_name,
devName: deviceInfo.dev_name
});
}
else {
deviceTableParams.value.push({
key: (deviceInfo.udp_port_src).toString(),
protocolName: deviceInfo.protocol_name,
devName: deviceInfo.dev_name
});
}
}
}
dialogVisible.value = false
ElMessage.success(`add ${selectedDeviceName.value} successfully!`);
}
const deleteDeviceInfo = (param: MonitorType) => {
deviceTableParams.value.splice(deviceTableParams.value.indexOf(param), 1);
}
</script>
<style scoped>
.scrollbar-demo-item {
display: flex;
/* align-items: center; */
/* justify-content: center; */
height: auto;
margin: 10px;
text-align: left;
border-radius: 4px;
background: #fff;
color: #4d4c4c;
}
</style>
<template>
<div>
<div class="text-right">
<el-button type="danger" @click="del" :icon="Delete" circle />
<div>
<div class="float-left text-black ml-4">
<p>{{ props.devName }}</p>
</div>
<div class="float-right">
<el-button type="danger" size="small" class="mr-4" @click="del" :icon="Delete" circle />
</div>
</div>
<el-table :data="tableData" class="w-full">
<el-table-column v-for="(_, key) in tableData[0]" :label="key" :prop="key" width="150" />
<el-table-column v-for="(_, key) in tableData[0]" :label="key" :prop="key" />
</el-table>
</div>
</template>
......@@ -13,15 +18,19 @@
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { Delete } from '@element-plus/icons-vue'
import axios from 'axios';
type propsType = {
devName: string
groupName: string
protocolName: string
}
const props = defineProps<propsType>()
type tableDataType = Record<string, string>[]
// const tableData = ref<tableDataType>([{}]);
const tableData = ref<tableDataType>([{}])
const tableTitles = ref<string[]>([])
let table_websocket: WebSocket | null = null
onMounted(() => {
......@@ -31,28 +40,41 @@ onMounted(() => {
table_websocket.onmessage = (e) => {
// console.log(e.data);
// TODO: 通过获取需要监控的变量将 key 写死
let data = JSON.parse(e.data).message
for (const [key, value] of Object.entries(data[0] as Record<string, string>)) {
console.log(key, value);
if (tableTitles.value.indexOf(key) !== -1) {
tableData.value[0][key] = value
}
}
}
table_websocket.onclose = (e) => {
console.error('Table socket closed unexpectedly', e);
}
axios.get('/api/device_communication/performance/1/' + props.protocolName)
.then((res) => {
tableTitles.value = res.data
for (let key of res.data) {
tableData.value[0][key] = ''
}
})
.catch((err) => {
console.log(err);
})
})
const emits = defineEmits(['deleteTable'])
const del = () => {
emits('deleteTable')
table_websocket!.close()
}
onBeforeUnmount(() => {
if (table_websocket!.OPEN) {
table_websocket!.close()
}
table_websocket?.close()
})
</script>
......@@ -76,7 +76,7 @@
<script setup lang="ts">
import {ref, watch} from 'vue'
import DeviceTable from "./device-table.vue";
// import DeviceTable from "./device-table.vue";
const deviceVisible = ref(false)
const virtualDeviceVisible = ref(false)
......
......@@ -3,7 +3,7 @@
<div class="container">
<div class="left">
<div class="mr-4">协议版本</div>
<el-select v-model="value">
<el-select v-model="currentVersion">
<!-- TODO: 选择协议版本 -->
<el-option
v-for="option in options"
......@@ -77,14 +77,18 @@
<script setup lang="ts">
import { ref,onMounted } from 'vue'
import { ElMessage, ElMessageBox } from "element-plus";
import { GetProtocolVersion,ProtocolInit } from "@/dao/protocol"
import { ProtocolInit } from "@/dao/protocol"
import ProtocolTable from "./ProtocolTable.vue";
import type { DeviceProtocolResponse, ProtocolCmdResponse } from './types';
import { useProtocolVersionStore } from '@/stores/allProtocolVersion';
const addCmd = ref<boolean>(false)
const value = ref('')
const options = ref<Array>([])
const protocol_names = ref<Array>([])
const currentVersion = ref('')
type OptionType = {
value: string
label: string
}
const options = ref<OptionType[]>([])
const formLabelWidth = '140px'
type propsType = {
......@@ -118,37 +122,46 @@ const open = () => {
})
}
async function getVersion(){
await GetProtocolVersion()
.then((res) => {
for (const item of res){
protocol_names.value.push(item.protocol_name)
if (item.protocol_name === props.name){
let version_paths = JSON.parse(item.version_paths)
for (const item2 of version_paths){
options.value.push({value: item2.version, label: item2.version})
}
}
}
})
.catch((err) => {
console.log(err);
})
}
function Init(){
ProtocolInit({protocol_name: props.name})
.then((res) => {
.then((_) => {
options.value.push({value: "init", label: "init"})
currentVersion.value = "init"
})
.catch((err) => {
console.log(err);
})
}
onMounted(async () => {
await getVersion()
if (protocol_names.value.indexOf(props.name) === -1){
const store = useProtocolVersionStore()
onMounted(() => {
// 判断是否需要初始化
let flag = true
for (let protocolVersion of store.protocolVersions){
if (protocolVersion.protocol_name === props.name) {
let version_paths = JSON.parse(protocolVersion.version_paths)
for (let version_path of version_paths){
options.value.push({value: version_path.version, label: version_path.version})
}
flag = false
break
}
}
if (!flag) {
for (let item of store.currentVersions){
if (item.protocol_name === props.name) {
currentVersion.value = item.version
}
}
}
// 如果需要初始化
if (flag){
Init()
}
})
......
......@@ -228,7 +228,7 @@ const addField = () => {
fields.value.value = ''
fields.value.minvalue = 'null'
fields.value.maxvalue = 'null'
fields.value.datatype = ''
fields.value.datatype = 1
fields.value.lua_script_in = 'null'
fields.value.lua_script_out = 'null'
fields.value.operation_in = 0
......
import axios from "axios"
const baseURL = 'http://192.168.0.214:8000/op'
// const baseURL = 'http://192.168.0.214:8000/op'
export function DeviceProtocol() {
return axios.get('/api/dev_cmd_name_poll').then(
......
import axios from "axios"
const baseURL = 'http://192.168.0.214:8000/op'
// const baseURL = 'http://192.168.0.214:8000/op'
export function GetProtocolVersion(){
return axios.get('/api/all_protocol_version/').then(
......@@ -11,9 +11,18 @@ export function GetProtocolVersion(){
}
export function ProtocolInit(protocol_name: any){
return axios.post('api/protocol_version_manage/init/', protocol_name).then(
return axios.post('/api/protocol_version_manage/init/', protocol_name).then(
function (response){
return response.data
}
)
}
export function GetCurrentVersion() {
return axios.get('/api/current_versions/').then(
function (response) {
return response.data
}
)
}
......@@ -6,7 +6,7 @@ const router = createRouter({
{
path: '/',
name: 'index',
component: () => import('@/views/index/HomePage.vue'),
component: () => import('@/views/index/Home.vue'),
},
{
path: '/protocol',
......
import { defineStore } from 'pinia'
import { ref } from 'vue'
type ProtocolVersion = {
protocol_name: string
version_paths: string
}
type CurrentVersion = {
protocol_name: string
version: string
}
export const useProtocolVersionStore = defineStore('protocolVersion', () => {
const protocolVersions = ref<ProtocolVersion[]>([])
const currentVersions = ref<CurrentVersion[]>([])
return {
protocolVersions,
currentVersions
}
})
\ No newline at end of file
<template>
<el-scrollbar ref="scrollbarRef" style="height: 25rem;" class="mb-10" always>
<div ref="innerRef">
<p v-for="item in items" :key="item" class="scrollbar-demo-item text-sm">
<div>{{ JSON.parse(item)?.ts }}</div>
{{ item }}
</p>
</div>
</el-scrollbar>
<el-input v-model="input" placeholder="Please input" @keyup.enter="send"></el-input>
<el-button @click="send">Send</el-button>
<device-performance-table
v-for="param in deviceTableParams"
mt-5
:group-name="param"
:key="param"
@delete-table="deleteDeviceInfo(param)" />
<el-button @click="addDeviceTable" class="mt-5" >Add table</el-button>
</template>
<script setup lang="ts">
import { ref, onMounted, watch } from 'vue';
import { ElScrollbar, ElInput, ElButton } from 'element-plus';
import { ElMessage, ElMessageBox } from 'element-plus'
import DevicePerformanceTable from '@/components/DevicePerformanceTabel'
const innerRef = ref<HTMLDivElement>();
const scrollbarRef = ref<InstanceType<typeof ElScrollbar>>();
const input = ref('');
const items = ref<string[]>([
JSON.stringify([{"CMDS": "$,", "Xaxis": "034.00", "Comma": ",", "Yaxis": "034.00", "Azimuth": "000.00", "ElevationAngle": "090.00", "ACUstatus": "P", "XTrackerSigIntensity": "255", "YTrackerSigIntensity": "255", "X_STATUS": "244", "Y_STATUS": "245", "XInitPhase": "012", "XPolarizationType": "1", "SPolarizationType": "0", "XTrackerVoltageLimit": "255", "STrackerVoltageLimit": "255", "SUpPolarizationType": "1", "XUpPolarizationType": "1", "TrackingStatus": "0", "TrackingBand": "1", "X-Bias": "+0.00", "Y-Bias": "+0.00", "END": "\r\n", "XaxisAlarm": "0", "XaxisServoStatus": "1", "EasternLimit": "0", "WestLimit": "0", "YaxisAlarm": "0", "YaxisServoStatus": "1", "SouthrLimit": "0", "NorthLimit": "1"}]),
JSON.stringify([{"CMDS": "$,", "Xaxis": "034.00", "Comma": ",", "Yaxis": "034.00", "Azimuth": "000.00", "ElevationAngle": "090.00", "ACUstatus": "P", "XTrackerSigIntensity": "255", "YTrackerSigIntensity": "255", "X_STATUS": "244", "Y_STATUS": "245", "XInitPhase": "012", "XPolarizationType": "1", "SPolarizationType": "0", "XTrackerVoltageLimit": "255", "STrackerVoltageLimit": "255", "SUpPolarizationType": "1", "XUpPolarizationType": "1", "TrackingStatus": "0", "TrackingBand": "1", "X-Bias": "+0.00", "Y-Bias": "+0.00", "END": "\r\n", "XaxisAlarm": "0", "XaxisServoStatus": "1", "EasternLimit": "0", "WestLimit": "0", "YaxisAlarm": "0", "YaxisServoStatus": "1", "SouthrLimit": "0", "NorthLimit": "1"}]),
JSON.stringify([{"CMDS": "$,", "Xaxis": "034.00", "Comma": ",", "Yaxis": "034.00", "Azimuth": "000.00", "ElevationAngle": "090.00", "ACUstatus": "P", "XTrackerSigIntensity": "255", "YTrackerSigIntensity": "255", "X_STATUS": "244", "Y_STATUS": "245", "XInitPhase": "012", "XPolarizationType": "1", "SPolarizationType": "0", "XTrackerVoltageLimit": "255", "STrackerVoltageLimit": "255", "SUpPolarizationType": "1", "XUpPolarizationType": "1", "TrackingStatus": "0", "TrackingBand": "1", "X-Bias": "+0.00", "Y-Bias": "+0.00", "END": "\r\n", "XaxisAlarm": "0", "XaxisServoStatus": "1", "EasternLimit": "0", "WestLimit": "0", "YaxisAlarm": "0", "YaxisServoStatus": "1", "SouthrLimit": "0", "NorthLimit": "1"}]),
JSON.stringify([{"CMDS": "$,", "Xaxis": "034.00", "Comma": ",", "Yaxis": "034.00", "Azimuth": "000.00", "ElevationAngle": "090.00", "ACUstatus": "P", "XTrackerSigIntensity": "255", "YTrackerSigIntensity": "255", "X_STATUS": "244", "Y_STATUS": "245", "XInitPhase": "012", "XPolarizationType": "1", "SPolarizationType": "0", "XTrackerVoltageLimit": "255", "STrackerVoltageLimit": "255", "SUpPolarizationType": "1", "XUpPolarizationType": "1", "TrackingStatus": "0", "TrackingBand": "1", "X-Bias": "+0.00", "Y-Bias": "+0.00", "END": "\r\n", "XaxisAlarm": "0", "XaxisServoStatus": "1", "EasternLimit": "0", "WestLimit": "0", "YaxisAlarm": "0", "YaxisServoStatus": "1", "SouthrLimit": "0", "NorthLimit": "1"}]),
JSON.stringify([{"CMDS": "$,", "Xaxis": "034.00", "Comma": ",", "Yaxis": "034.00", "Azimuth": "000.00", "ElevationAngle": "090.00", "ACUstatus": "P", "XTrackerSigIntensity": "255", "YTrackerSigIntensity": "255", "X_STATUS": "244", "Y_STATUS": "245", "XInitPhase": "012", "XPolarizationType": "1", "SPolarizationType": "0", "XTrackerVoltageLimit": "255", "STrackerVoltageLimit": "255", "SUpPolarizationType": "1", "XUpPolarizationType": "1", "TrackingStatus": "0", "TrackingBand": "1", "X-Bias": "+0.00", "Y-Bias": "+0.00", "END": "\r\n", "XaxisAlarm": "0", "XaxisServoStatus": "1", "EasternLimit": "0", "WestLimit": "0", "YaxisAlarm": "0", "YaxisServoStatus": "1", "SouthrLimit": "0", "NorthLimit": "1"}]),
]);
const flag = ref<boolean>(false);
let chatSocket: WebSocket | null = null;
const send = () => {
if (chatSocket === null) {
console.error('chatSocket is null');
return;
}
chatSocket.send(JSON.stringify({
'message': input.value
}));
input.value = '';
}
watch(flag, () => {
setTimeout(() => {
scrollbarRef.value!.setScrollTop(innerRef.value!.offsetHeight);
}, 50);
});
onMounted(() => {
chatSocket = new WebSocket(
'ws://'
+ window.location.host
+ '/ws/chat/mqtt/'
);
chatSocket.onmessage = (e) => {
// console.log(e);
// console.log(e.data)
// // 接收到的是字节流数据(ArrayBuffer)
// const byteArray = new Uint8Array(e.data);
// // 将字节流转换为字符串或其他格式进行处理
// const message = byteArray.toString();
// items.value.push(JSON.stringify(e.data));
items.value.push(e.data);
flag.value = !flag.value
};
chatSocket.onclose = (e) => {
console.error('Chat socket closed unexpectedly', e);
};
})
const deviceTableParams = ref<string[]>([]);
const addDeviceTable = () => {
ElMessageBox.prompt('Please input WebSocket group name', 'Tip', {
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
})
.then(({ value }) => {
ElMessage({
type: 'success',
message: `new websocket group name is chat_${value}`,
})
deviceTableParams.value.push(value);
})
.catch(() => {
ElMessage({
type: 'info',
message: 'Input canceled',
})
})
}
const deleteDeviceInfo = (param: string) => {
deviceTableParams.value.splice(deviceTableParams.value.indexOf(param), 1);
}
</script>
<style scoped>
.scrollbar-demo-item {
display: flex;
/* align-items: center; */
/* justify-content: center; */
height: auto;
margin: 10px;
text-align: left;
border-radius: 4px;
background: #fff;
color: #4d4c4c;
}
</style>
<template>
<div class="common-layout">
<el-container>
<el-aside width="200px">
<kit-menu @handleMenuItemSelect="MenuItem"></kit-menu>
</el-aside>
<el-main>
<el-button @click="addDevice = true">新增模拟设备</el-button>
<component :is="currentComponent"></component>
</el-main>
</el-container>
</div>
<el-dialog v-model="addDevice" title="新增指令">
<el-form >
<el-form-item label="设备名称" :label-width="formLabelWidth">
<el-input autocomplete="off" />
</el-form-item>
<el-form-item label="设备英文名称" :label-width="formLabelWidth">
<el-input autocomplete="off" />
</el-form-item>
<el-form-item label="协议" :label-width="formLabelWidth">
<el-select>
<el-option label="TX"></el-option>
<el-option label="RX"></el-option>
</el-select>
</el-form-item>
<el-form-item label="通信方式" :label-width="formLabelWidth">
<el-select>
<el-option label="ASCII"></el-option>
<el-option label="HEX"></el-option>
</el-select>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="addDevice = false">取消</el-button>
<el-button type="primary" @click="open">
确定
</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import {ref, shallowRef} from "vue";
import {ElMessage, ElMessageBox} from "element-plus";
import KitMenu from "../../components/kit-menu.vue";
import KitDevice from "../../components/kit-device.vue";
const currentComponent = shallowRef(KitDevice)
const addDevice = ref(false)
const formLabelWidth = '140px'
function MenuItem(index){
console.log(index)
currentComponent.value = KitDevice
}
function open(){
ElMessageBox.confirm(
'是否确认增加?',
'Warning',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
ElMessage({
type: 'success',
message: '增加成功',
})
addDevice.value = false
})
.catch(() => {
ElMessage({
type: 'info',
message: '已取消',
})
})
}
</script>
<style>
body,html{
height: 100%;
}
html,body,.common-layout,.el-container{
margin: 0px;
padding: 0px;
height: 100%;
}
.el-aside {
background-color: #ffffff;
color: #333;
text-align: center;
line-height: 200px;
}
.el-main {
border: 1px solid;
/*background-color: #f3f4f6;*/
color: #333;
/*text-align: center;*/
}
</style>
<template>
<chat />
</template>
<script setup lang="ts">
// import { ref } from 'vue';
import Chat from '@/components/home/Chat.vue';
</script>
<template>
<div class="flex items-center w-1/2">
<div style="width: 10%" >订阅主题</div>
<el-input style="width: 30%" class="ml-4"></el-input>
<el-button style="width: 15%" class="ml-4">连接mqtt</el-button>
</div>
<div class="flex mt-4" style="height: 80%;">
<div style="width: 40%; height: 100%">
<div style="height: 90%; border: 1px solid">
</div>
<div class="flex mt-4">
<el-input></el-input>
<el-button class="ml-4" @click="setting">设置指令</el-button>
<el-button>发送指令</el-button>
</div>
</div>
<div style="width: 58%; height: 100%; border: 1px solid;overflow: auto;" class="ml-4" >
<div style="border-bottom: 1px solid">
<el-button-group>
<el-button
class="square-button"
:type="type1 ? 'primary' : 'default'"
@click="showComponent('real')"
>设备</el-button>
<el-button
class="square-button"
:type="type2 ? 'primary' : 'default'"
@click="showComponent('virtual')"
>模拟设备</el-button>
</el-button-group>
</div>
<KitDevice v-if="tag" :tag = "tag"></KitDevice>
</div>
</div>
<div class="flex mt-4 items-center" style="height: 10%">
<div style="width: 90%; height: 100%;border: 1px solid;overflow: auto;" ref="messageContainer">
<span v-for="message in messages">
{{ message }}
<br />
</span>
</div>
<el-button class="ml-4" size="large">导出</el-button>
</div>
<el-dialog v-model="cmdVisible">
<el-form>
<el-form-item label="设备" :label-width="formLabelWidth">
<el-select v-model="cmds.device" @change="checkToShowInput">
<el-option label="option 1" value="option 1" />
</el-select>
</el-form-item>
<el-form-item label="指令名" :label-width="formLabelWidth">
<el-select v-model="cmds.cmd_name" @change="checkToShowInput">
<el-option label="option 1" value="option 1" />
</el-select>
</el-form-item>
<el-form-item label="某个字段" :label-width="formLabelWidth" v-if="show">
<el-input autocomplete="off" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="cmdVisible = false">取消</el-button>
<el-button type="primary" @click="cmdVisible = false">
确定
</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import {onMounted, onUpdated, ref } from 'vue'
import KitDevice from "@/components/kit-device";
const messages = ref([1,2,3,4,5,6,7,8])
const messageContainer = ref(null);
const tag = ref('real')
const socket = ref(null)
const type1 = ref(true)
const type2 = ref(false)
const cmdVisible = ref(false)
const formLabelWidth = '140px'
const cmds = ref(
{device: '', cmd_name: ''}
)
const show = ref(false)
function scrollToBottom() {
if (messageContainer.value) {
messageContainer.value!.scrollTop = messageContainer.value!.scrollHeight;
}
}
onUpdated(() => {
// 在 messages 更新后滚动到底部
scrollToBottom();
});
onMounted(() => {
socket.value = new WebSocket('ws://'
+ 'localhost:8000'
+ '/ws/chat/mqtt/')
socket.value.onmessage = (e) => {
messages.value.push(e.data)
}
scrollToBottom();
})
const showComponent = (str) => {
if (str === 'real'){
type1.value = true
type2.value = false
}else if (str === 'virtual'){
type1.value = false
type2.value = true
}
tag.value = str
}
const checkToShowInput = () => {
show.value = cmds.value.device && cmds.value.cmd_name
}
const setting = () => {
cmdVisible.value = true
// cmds.value.device = ''
// cmds.value.cmd_name = ''
for (const key in cmds.value){
cmds.value[key] = ''
}
show.value = false
}
</script>
<style>
.square-button {
border-radius: 0;
}
</style>
\ No newline at end of file
<template>
<div class="w-screen h-screen">
<div class="w-full shadow-md flex justify-between items-center" :style="{height: headerHeight,backgroundColor:'#23479C', color:'white'}">
<div class="flex justify-center items-center cursor-pointer w-1/4" @click="routeTo('index')">
<div class="text-center">{{configKit.title}}</div>
</div>
<el-menu
:class="menuWith===''?'grow':''"
:style="menuWith===''?{}:{width: menuWith}"
activeTextColor="#00d0FF"
textColor="white"
:unique-opened="true"
:collapse-transition="false"
backgroundColor="#23479C"
mode="horizontal"
:default-active="storeCurrentRoute.name"
@select="routeTo">
<template v-for="(item, _) of storePageMenu" :key="item.name">
<el-sub-menu
v-if="menuItemFilter(item.children).length>0"
:index="item.name">
<template #title>
<div class="flex items-center">
<kit-icon class="w-4 h-4" :name="item.menuIcon"></kit-icon>
<span class="ml-2">{{item.menuTitle }}</span>
</div>
</template>
<el-menu-item
v-for="child of menuItemFilter(item.children)"
:index="child.name">
<template #title>
{{child.menuTitle}}
</template>
</el-menu-item>
</el-sub-menu>
<el-menu-item
v-else-if="item.name && item.component && (!item.authFunc || item.authFunc())"
:index="item.name">
<div class="flex justify-center items-center h-full">
<kit-icon class="w-4 h-4" :name="item.menuIcon"></kit-icon>
</div>
<template #title>
<span class="ml-2">{{ item.menuTitle }}</span>
</template>
</el-menu-item>
</template>
</el-menu>
<div class="rounded-full border border-white border-solid mx-4">
<kit-icon name="common-avatar" class="w-7 h-7 text-white" @click="usercenter=true"></kit-icon>
</div>
<el-drawer
v-model="usercenter"
title="个人中心"
size="240px"
direction="rtl">
<user-center class="text-black" />
</el-drawer>
</div>
<div v-if="storeCurrentRoute.name==='train-index'" class="overflow-auto p-4 w-full" style="background-color:#0b1634" :style="{height: 'calc(100vh - '+headerHeight+')'}">
<router-view />
</div>
<div v-else class="overflow-auto p-4 w-full bg-gray-100" :style="{height: 'calc(100vh - '+headerHeight+')'}">
<router-view />
</div>
</div>
</template>
<script setup lang="ts">
import { ref,onMounted} from 'vue';
import {storePageMenu} from "../../lib/router/index";
import {useRouter} from "vue-router";
import {configKit, storeCurrentRoute} from "../../lib/store/index.js";
import UserCenter from "/components/user-center";
//
// import {isBureau,isBureau0, isSchool} from "../store/model";
// import {storeTrainSelect} from "../store/train-select";
defineProps({
menuWith:{
type: String,
default: ""
}
})
const router = useRouter()
console.log(router)
// 顶部高
const headerHeight = ref('60px')
const usercenter = ref(false)
function routeTo(name){
router.push({name})
}
// menu
function menuItemFilter(itemChildren) {
if(!itemChildren) itemChildren = []
return itemChildren.filter((child) => !child.authFunc || child.authFunc());
}
onMounted(()=>{
})
</script>
<style>
.el-menu--horizontal{
border-bottom-width: 0;
}
</style>
......@@ -27,16 +27,30 @@
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { ref, onMounted } from 'vue';
import KitCollapse from "@/components/protocol/KitCollapse";
import { GetProtocolVersion, GetCurrentVersion } from '@/dao/protocol';
import { useProtocolVersionStore } from '@/stores/allProtocolVersion';
const isShow = ref<boolean>(false)
const formLabelWidth = '140px'
const store = useProtocolVersionStore()
onMounted(() => {
GetProtocolVersion()
.then(res => {
store.protocolVersions.push(...res)
})
GetCurrentVersion()
.then(res => {
store.currentVersions = res
})
})
// TODO:添加协议
const addProtocol = () => {
isShow.value = false
console.log('addProtocol')
}
</script>
......
......@@ -33,21 +33,20 @@ def send_message(data: dict, device_name: str):
"""
send_websocket_message(data)
# dev_info = TableXproAllDevinfo.objects.filter(dev_name=device_name).first()
# if "TCP" in dev_info.comunitate_mode.upper():
# name = dev_info.tcp_port
# elif "UDP" in dev_info.comunitate_mode.upper():
# name = dev_info.udp_port_src
# print(name)
# send_websocket_message(data, group_name=f'chat_{name}')
cmds = data.get('CMDS')
if cmds is None:
return
if cmds[0] == '$':
send_websocket_message(data, group_name="chat_acu7m5")
else:
send_websocket_message(data, group_name="chat_hwf")
dev_info = TableXproAllDevinfo.objects.filter(dev_name=device_name).first()
if "TCP" in dev_info.comunitate_mode.upper():
name = dev_info.tcp_port
elif "UDP" in dev_info.comunitate_mode.upper():
name = dev_info.udp_port_src
send_websocket_message(data, group_name=f'chat_{name}')
# cmds = data.get('CMDS')
# if cmds is None:
# return
# if cmds[0] == '$':
# send_websocket_message(data, group_name="chat_acu7m5")
# else:
# send_websocket_message(data, group_name="chat_hwf")
client = mqtt.Client()
......
from django.urls import re_path
from rest_framework.routers import DefaultRouter
from . import views
router = DefaultRouter()
router.register(r'current_versions', views.CurrentDevVersionViewSet)
urlpatterns = [
re_path(r'^protocol_version_manage/init/$', views.init),
......@@ -13,3 +16,5 @@ urlpatterns = [
views.raw_file_download),
re_path(r'^all_protocol_version/$', views.AllProtocolVersionViewSet.as_view({'get': 'list'})),
]
urlpatterns += router.urls
......@@ -193,3 +193,8 @@ def raw_file_download(request, protocol_name, version):
response['Content-Type'] = 'multipart/form-data'
response['filename'] = file_name
return response
class CurrentDevVersionViewSet(GenericViewSet, ListModelMixin):
queryset = CurrentDevVersion.objects.all()
serializer_class = CurrentDevVersionSerializer
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment