Commit 968d5086 by qianmo

Merge branch 'main' into fh

# Conflicts:
#	frontend/package.json
#	frontend/src/App.vue
#	frontend/src/main.ts
#	frontend/src/style.css
#	frontend/tsconfig.json
#	frontend/vite.config.ts
#	frontend/yarn.lock
#	vue_django/settings.py
#	xdc.sqlite
parents fce834bf 4201aedc
## 介绍
- master 分支,主要为后端接口
- fh 分支,为界面
![1692668065114](image/README/1692668065114.png)
各个文件夹或文件作用
- chat:测试 websocket 的模块
- device_communication:device 通信参数模块
- device_data_op:对 device 已有的表的操作模块
- download_db:测试 下载 sqlite 文件模块
- frontend:前端文件夹
- mqtt:测试 mqtt 连接与发送内容的模块
- protocol_version_manage:协议版本控制模块
- scripts_generate:测试 脚本生成模块
- vue_django:django 项目主模块
- db.sqlite3:没用
- manage.py:django 项目启动文件
- poetry.lock,pyproject.toml:poetry 的管理文件
- xdc.sqlite:device 数据库
## 安装依赖
1. 创建 conda 的虚拟环境
```
conda create -n django-venv python=3.9.16
```
2. 激活 django-venv 虚拟环境
```
conda activate django-venv
```
可以使用 pip list 查看是否为一个新的环境
3. 激活虚拟环境后下载 poetry
```
pip install poetry
```
4. 使用 poetry 命令下载依赖
```
poetry install
```
5. 转到 frontend 文件夹,下载前端的依赖(node 版本最低为16,我这里使用的是 16.20.1)
```
yarn install
```
```
npm install
```
6. 下载完依赖之后打包项目
```
yarn build
```
```
npm run build
```
7. 退回到 vue_django_test 文件夹,启动项目,就能正常看见页面了
```
python manage.py runserver
```
ps:以上步骤在 windows 环境和 ubuntu 20.04 下都测试过,都能正常跑起来
## 运行项目
使用 `python manage.py runserver` 运行项目(目前运行项目只有接口,可能只能通过接口调试工具来测试)
![1692841750241](image/README/1692841750241.png)
## 注意
* 如果是在远程的情况下,需要将 vue_django 目录中 urls.py 文件中的 `mqtt``chat` url 给注释了,否则启动不成功
* ![1692841883700](image/README/1692841883700.png)
......@@ -4,6 +4,8 @@ import json
from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer
from channels.generic.websocket import AsyncWebsocketConsumer
from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync
# sync code
......@@ -72,10 +74,16 @@ class ChatConsumer(AsyncWebsocketConsumer):
# Receive message from room group
async def chat_message(self, event):
message = event["message"]
message = dict(event["message"])
# Send message to WebSocket
await self.send(text_data=json.dumps({"message": message}))
await self.send(text_data=json.dumps({"message": [message]}))
# await self.send(bytes_data=message)
def send_websocket_message(message, group_name="chat_mqtt"):
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(
group_name,
{"type": "chat.message", "message": message}
)
# chat/urls.py
from django.urls import path
from . import views
urlpatterns = [
......
from django.shortcuts import render
from django.contrib import admin
# Register your models here.
from django.apps import AppConfig
class DeviceCommunicationConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'device_communication'
# Generated by Django 3.2.19 on 2023-08-24 03:03
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='DeviceCommunicationParameter',
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
('station_id', models.CharField(max_length=10)),
('device_id', models.IntegerField(default=0)),
('device_name', models.CharField(max_length=100)),
('device_name_chn', models.CharField(max_length=100)),
('protocol_name', models.CharField(max_length=100)),
('communicate_mode', models.CharField(max_length=100)),
('tcp_ip', models.CharField(blank=True, default='', max_length=40)),
('tcp_port', models.IntegerField(default=0)),
('udp_ip_src', models.CharField(blank=True, default='', max_length=40)),
('udp_port_src', models.IntegerField(default=0)),
('udp_ip_dst', models.CharField(blank=True, default='', max_length=40)),
('udp_port_dst', models.IntegerField(default=0)),
('performance_fields', models.TextField()),
],
options={
'db_table': 'DeviceCommunicationParameter',
},
),
migrations.CreateModel(
name='SimulateDeviceCommunicationParameter',
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
('station_id', models.CharField(max_length=10)),
('device_id', models.IntegerField(default=0)),
('device_name', models.CharField(max_length=100)),
('device_name_chn', models.CharField(max_length=100)),
('protocol_name', models.CharField(max_length=100)),
('communicate_mode', models.CharField(max_length=100)),
('tcp_ip', models.CharField(blank=True, default='', max_length=40)),
('tcp_port', models.IntegerField(default=0)),
('udp_ip_src', models.CharField(blank=True, default='', max_length=40)),
('udp_port_src', models.IntegerField(default=0)),
('udp_ip_dst', models.CharField(blank=True, default='', max_length=40)),
('udp_port_dst', models.IntegerField(default=0)),
('performance_fields', models.TextField()),
],
options={
'db_table': 'SimulateDeviceCommunicationParameter',
},
),
]
from django.db import models
def allow_none(value):
"""
当传过来的值为 none 时,则在数据库里存一个空值
:param value: 通过基本校验之后的值
"""
if value == "none":
return ""
return value
# Create your models here.
class SimulateDeviceCommunicationParameter(models.Model):
"""
模拟设备通信参数
"""
id = models.AutoField(primary_key=True)
station_id = models.CharField(max_length=10)
device_id = models.IntegerField(default=0)
device_name = models.CharField(max_length=100)
device_name_chn = models.CharField(max_length=100)
protocol_name = models.CharField(max_length=100)
communicate_mode = models.CharField(max_length=100)
tcp_ip = models.CharField(max_length=40, default="", blank=True)
tcp_port = models.IntegerField(default=0)
udp_ip_src = models.CharField(max_length=40, default="", blank=True)
udp_port_src = models.IntegerField(default=0)
udp_ip_dst = models.CharField(max_length=40, default="", blank=True)
udp_port_dst = models.IntegerField(default=0)
performance_fields = models.TextField()
def validate(self, attrs: dict):
"""
校验字段,在进行基础校验之后,如果字段名称为下面的字段,
且当传过来的值为 none 时,存一个空值
:param attrs: 通过基本校验之后的值
"""
for field_name, value in attrs.items():
if field_name in (['tcp_ip', 'tcp_port', 'udp_ip_src', 'udp_port_src',
'udp_ip_dst', 'udp_port_dst']):
attrs[field_name] = allow_none(value)
return attrs
class Meta:
db_table = 'SimulateDeviceCommunicationParameter'
class DeviceCommunicationParameter(models.Model):
"""
设备通信参数
{
"station_id": "XX1",
"device_id": 1,
"device_name": "XXXX",
"device_name_chn": "XXXX",
"protocol_name": "HY_VirtualDevice_PROTOCOL",
"communicate_mode": "TCP_CLIENT",
"tcp_ip": "127.0.0.1",
"tcp_port": 8888,
"performance_fields": ["info", "END", "CMDS"]
}
"""
id = models.AutoField(primary_key=True)
station_id = models.CharField(max_length=10)
device_id = models.IntegerField(default=0)
device_name = models.CharField(max_length=100)
device_name_chn = models.CharField(max_length=100)
protocol_name = models.CharField(max_length=100)
communicate_mode = models.CharField(max_length=100)
tcp_ip = models.CharField(max_length=40, default="", blank=True)
tcp_port = models.IntegerField(default=0)
udp_ip_src = models.CharField(max_length=40, default="", blank=True)
udp_port_src = models.IntegerField(default=0)
udp_ip_dst = models.CharField(max_length=40, default="", blank=True)
udp_port_dst = models.IntegerField(default=0)
performance_fields = models.TextField()
def validate(self, attrs: dict):
"""
校验字段,在进行基础校验之后,如果字段名称为下面的字段,
且当传过来的值为 none 时,存一个空值
:param attrs: 通过基本校验之后的值
"""
for field_name, value in attrs.items():
if field_name in (['tcp_ip', 'tcp_port', 'udp_ip_src', 'udp_port_src',
'udp_ip_dst', 'udp_port_dst']):
attrs[field_name] = allow_none(value)
return attrs
class Meta:
db_table = 'DeviceCommunicationParameter'
from rest_framework.serializers import ModelSerializer
from .models import (SimulateDeviceCommunicationParameter,
DeviceCommunicationParameter)
class SimulateDeviceCommunicationParameterSerializer(ModelSerializer):
class Meta:
model = SimulateDeviceCommunicationParameter
fields = '__all__'
class DeviceCommunicationParameterSerializer(ModelSerializer):
class Meta:
model = DeviceCommunicationParameter
fields = '__all__'
from django.urls import re_path
from rest_framework.routers import DefaultRouter
from . import views
router = DefaultRouter()
router.register('device_communication/communicate',
views.DeviceCommunicationParameterViewSet)
router.register('device_communication/simulate_communicate',
views.SimulateDeviceCommunicationParameterViewSet)
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/set_communication_to_devinfo_table/$',
views.set_communication_to_devinfo_table),
]
urlpatterns += router.urls
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from rest_framework.viewsets import ModelViewSet
from .models import (SimulateDeviceCommunicationParameter, DeviceCommunicationParameter)
from protocol_version_manage.models import (AllProtocolVersion, AllProtocolDefinAndVersion,
AllDevCmdDefineAndVersion)
from device_data_op.models import TableXproAllDevinfo
from .serializers import (SimulateDeviceCommunicationParameterSerializer,
DeviceCommunicationParameterSerializer)
@api_view(['GET'])
def get_protocol_names(request):
"""
获取所有协议,并返回
"""
protocol_names = AllProtocolVersion.objects.all()
res_data = ([{'value': protocol_name.protocol_name, 'label': protocol_name.protocol_name}
for protocol_name in protocol_names])
return Response(data=res_data, status=status.HTTP_200_OK)
@api_view(['GET'])
def get_protocol_field_names(request, protocol_name):
"""
获取指定协议下的指令集
"""
# 获取该协议下的指令集合
cmds = AllProtocolDefinAndVersion.objects.filter(protocol_name=protocol_name, cmd_type='RX').all()
cmd_set = set([cmd.cmd_name for cmd in cmds])
# 获取指令集合下的字段
fields = AllDevCmdDefineAndVersion.objects.filter(cmd_name__in=cmd_set, cmd_type='RX').all()
field_name_set = set([field.fieldname for field in fields])
res_data = ([field_name for field_name in field_name_set])
return Response(data=res_data, status=status.HTTP_200_OK)
@api_view(['POST'])
def set_communication_to_devinfo_table(request):
"""
将设备通信参数或模拟设备通信参数设置到设备信息表
"""
type = request.data.get('type')
if type is None or type == '':
return Response(status=status.HTTP_400_BAD_REQUEST)
if type == 'simulate_communicate':
communications = SimulateDeviceCommunicationParameter.objects.all()
else:
communications = DeviceCommunicationParameter.objects.all()
# 清空设备信息表
# TODO:实际开始用的时候,需要将这个注释打开
# TableXproAllDevinfo.objects.all().delete()
TableXproAllDevinfo.objects.bulk_create(
[TableXproAllDevinfo(sta_id=communication.station_id,
dev_id=communication.device_id,
dev_name=communication.device_name,
dev_name_chn=communication.device_name_chn,
protocol_name=communication.protocol_name,
cmd_excel_path="null",
comunitate_mode=communication.communicate_mode,
tcp_ip=communication.tcp_ip,
tcp_port=communication.tcp_port,
udp_ip_src=communication.udp_ip_src,
udp_port_src=communication.udp_port_src,
udp_ip_dst=communication.udp_ip_dst,
udp_port_dst=communication.udp_port_dst,
udpmc_ip="",
udpmc_ip_tx="",
udpmc_port_tx=0,
udpmc_ip_rx="",
udpmc_port_rx=0,
remarks="")
for communication in communications])
return Response(status=status.HTTP_200_OK)
class DeviceCommunicationParameterViewSet(ModelViewSet):
queryset = DeviceCommunicationParameter.objects.all()
serializer_class = DeviceCommunicationParameterSerializer
def list(self, request):
serializer = self.get_serializer(self.get_queryset(), many=True)
data = sorted(serializer.data, key=lambda item: (item['station_id'], item['device_id']))
return Response(data)
def perform_create(self, serializer):
super().perform_create(serializer)
device_infos = self.queryset.filter(station_id=serializer.instance.station_id).all()
for i in range(len(device_infos)):
device_infos[i].device_id = i + 1
device_infos[i].save()
if serializer.instance.id == device_infos[i].id:
serializer.instance.device_id = device_infos[i].device_id
def perform_destroy(self, instance):
"""
删除某个记录之后,更新 device_id
"""
super().perform_destroy(instance)
communications = self.get_queryset().filter(station_id=instance.station_id).all()
for i in range(len(communications)):
communications[i].device_id = i + 1
communications[i].save()
class SimulateDeviceCommunicationParameterViewSet(ModelViewSet):
queryset = SimulateDeviceCommunicationParameter.objects.all()
serializer_class = SimulateDeviceCommunicationParameterSerializer
def list(self, request):
serializer = self.get_serializer(self.get_queryset(), many=True)
data = sorted(serializer.data, key=lambda item: (item['station_id'], item['device_id']))
return Response(data)
def perform_create(self, serializer):
super().perform_create(serializer)
device_infos = self.queryset.filter(station_id=serializer.instance.station_id).all()
for i in range(len(device_infos)):
device_infos[i].device_id = i + 1
device_infos[i].save()
if serializer.instance.id == device_infos[i].id:
serializer.instance.device_id = device_infos[i].device_id
def perform_destroy(self, instance):
"""
删除某个记录之后,更新 device_id
"""
super().perform_destroy(instance)
communications = self.get_queryset().filter(station_id=instance.station_id).all()
for i in range(len(communications)):
communications[i].device_id = i + 1
communications[i].save()
from rest_framework.routers import SimpleRouter
from .views import (TableAllDevCmdDefineView, TableDevCmdNamePollView,
TableSoftLimitAngleView, TableXproAllDevinfoView)
from .views import test
from django.urls import re_path
router = SimpleRouter()
router.register(r'all_dev_cmd_define', TableAllDevCmdDefineView)
......@@ -9,4 +10,9 @@ router.register(r'dev_cmd_name_poll', TableDevCmdNamePollView)
router.register(r'soft_limit_angle', TableSoftLimitAngleView)
router.register(r'xpro_all_devinfo', TableXproAllDevinfoView)
urlpatterns = router.urls
urlpatterns = [
re_path(r'^test/$', test),
]
urlpatterns += router.urls
import json
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import api_view
from rest_framework import status
from .models import (TableAllDevCmdDefine, TableDevCmdNamePoll,
TableSoftLimitAngle, TableXproAllDevinfo)
from .serializers import (TableAllDevCmdDefineSerializer, TableDevCmdNamePollSerializer,
......@@ -20,6 +26,7 @@ class TableAllDevCmdDefineView(ModelViewSet):
def perform_destroy(self, instance):
"""
删除某个字段,需要将字段的 index 更新
TODO: 返回更新后的数据(不能做完一个操作之后,页面就刷新)
"""
# 获取改字段的 cmd_name
......@@ -54,5 +61,71 @@ class TableXproAllDevinfoView(ModelViewSet):
serializer_class = TableXproAllDevinfoSerializer
@swagger_auto_schema(method='post', request_body=openapi.Schema(
type=openapi.TYPE_OBJECT,
properties={
'cmds': openapi.Schema(type=openapi.TYPE_OBJECT, properties={
'protocol_name': openapi.Schema(type=openapi.TYPE_STRING),
'cmd_name': openapi.Schema(type=openapi.TYPE_STRING),
'cmd_type': openapi.Schema(type=openapi.TYPE_STRING),
'encode': openapi.Schema(type=openapi.TYPE_STRING),
'timing_cmd_cycle_period': openapi.Schema(type=openapi.TYPE_INTEGER),
'cmd_explain': openapi.Schema(type=openapi.TYPE_STRING),
'fields': openapi.Schema(type=openapi.TYPE_ARRAY, items=openapi.Items(type=openapi.TYPE_OBJECT, properties={
"cmd_name": openapi.Schema(type=openapi.TYPE_STRING),
"cmd_type": openapi.Schema(type=openapi.TYPE_STRING),
"fieldindex": openapi.Schema(type=openapi.TYPE_INTEGER),
"fieldname": openapi.Schema(type=openapi.TYPE_STRING),
"fieldsize": openapi.Schema(type=openapi.TYPE_INTEGER),
"value": openapi.Schema(type=openapi.TYPE_STRING),
"minvalue": openapi.Schema(type=openapi.TYPE_STRING),
"maxvalue": openapi.Schema(type=openapi.TYPE_STRING),
"datatype": openapi.Schema(type=openapi.TYPE_INTEGER),
"operation_in": openapi.Schema(type=openapi.TYPE_INTEGER),
"operation_in_num": openapi.Schema(type=openapi.TYPE_INTEGER),
"operation_out": openapi.Schema(type=openapi.TYPE_INTEGER),
"operation_out_num": openapi.Schema(type=openapi.TYPE_INTEGER),
"operabo_in": openapi.Schema(type=openapi.TYPE_INTEGER),
"operabo_out": openapi.Schema(type=openapi.TYPE_INTEGER),
"lua_script_in": openapi.Schema(type=openapi.TYPE_STRING),
"lua_script_out": openapi.Schema(type=openapi.TYPE_STRING)
}))
})
}
))
@api_view(['POST'])
def test(request):
protocol_cmd = TableDevCmdNamePollView()
cmd_fields = TableAllDevCmdDefineView()
# print(request.data)
protocol_cmd.request = request
protocol_cmd.format_kwarg = None # 设置 format_kwarg 属性
cmd_fields.request = request
cmd_fields.format_kwarg = None # 设置 format_kwarg 属性
cmds = request.data.get('cmds')
for cmd in cmds.values():
# 将指令的字段属性从字典中弹出
fields = cmd.pop('fields')
# 创建协议指令
protocol_cmd_serializer = protocol_cmd.get_serializer(data=cmd)
protocol_cmd_serializer.is_valid(raise_exception=True)
cmd_explain = protocol_cmd_serializer.validated_data.get('cmd_explain')
try:
json.loads(cmd_explain)
except json.JSONDecodeError:
cmd_explain_dict = {
'explain': cmd_explain,
'version': "20230101"
}
cmd_explain = json.dumps(cmd_explain_dict)
protocol_cmd_serializer.validated_data['cmd_explain'] = cmd_explain
protocol_cmd.perform_create(protocol_cmd_serializer)
# 创建指令
for field in fields:
cmd_fields_serializer = cmd_fields.get_serializer(data=field)
cmd_fields_serializer.is_valid(raise_exception=True)
cmd_fields.perform_create(cmd_fields_serializer)
return Response(status=status.HTTP_201_CREATED)
<template>
<el-table :data="tableData" class="w-full">
<el-table-column v-for="(_, key) in tableData[0]" :label="key" :prop="key" width="150" />
</el-table>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
type propsType = {
groupName: string
}
const props = defineProps<propsType>()
type tableDataType = Record<string, string>[]
// const tableData = ref<tableDataType>([{}]);
const tableData = ref<tableDataType>([{}])
onMounted(() => {
let table_websocket = new WebSocket(
'ws://' + window.location.host + '/ws/chat/' + props.groupName! + '/'
)
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>)) {
tableData.value[0][key] = value
}
}
table_websocket.onclose = (e) => {
console.error('Table socket closed unexpectedly', e);
}
})
</script>
<template>
<div class="text-right mb-5">
<el-button type="primary" @click="applyComunications"> 应用 </el-button>
<el-button type="primary" @click="copy">copy to ini</el-button>
<el-button type="primary" @click="addDevice">Add device</el-button>
</div>
<div class="demo-collapse">
<el-collapse>
<el-collapse-item class="pt-10" v-for="(device_info_list, station_id) in device_infos">
<template #title>
<span class="text-3xl font-bold"> {{ station_id }} </span>
</template>
<device-info-card
@deleteDeviceInfo="deleteDeviceInfo"
v-for="device_info in device_info_list"
:device-info="device_info"
:tab-type="props.tabType"
/>
</el-collapse-item>
</el-collapse>
</div>
<edit-dialog
:is-show="isShow"
:tab-type="props.tabType"
@close="isShow = false"
@change-device-info="changeDeviceInfo"
type="add" />
</template>
<script setup lang="ts">
import axios from 'axios';
import { onMounted, ref } from 'vue'
import { ElMessage } from 'element-plus'
import useClipboard from 'vue-clipboard3'
import DeviceInfoCard from '@/components/device_communication/DeviceInfoCard'
import type { DeviceInfo } from '@/components/device_communication/types'
import EditDialog from '@/components/device_communication/EditDialog';
type propType = {
tabType: string
}
const props = defineProps<propType>()
// device info card 相关
const device_infos = ref<Record<string, DeviceInfo[]>>({})
// 获取当前选择的页面
onMounted(() => {
axios.get('/api/device_communication/' + props.tabType + '/')
.then(res => {
// console.log(res.data);
// 将数据按照不同的 station_id 分组
for (let i = 0; i < res.data.length; i++) {
if (device_infos.value[res.data[i].station_id] !== undefined) {
device_infos.value[res.data[i].station_id].push(res.data[i])
} else {
device_infos.value[res.data[i].station_id] = [res.data[i]]
}
}
})
.catch(err => {
console.log(err);
})
})
type param = {
station_id: string
id: number
}
const deleteDeviceInfo = (params: param) => {
for (let i = 0; i < device_infos.value[params.station_id].length; i++) {
if ((device_infos.value[params.station_id])[i].id === params.id) {
// 如果 station_id 对应的设备列表为空,则删除 station_id
if (device_infos.value[params.station_id].length === 1) {
delete device_infos.value[params.station_id]
return
}
// 删除
device_infos.value[params.station_id].splice(i, 1)
}
}
}
const isShow = ref(false)
const addDevice = () => {
isShow.value = true
}
const changeDeviceInfo = (params: DeviceInfo) => {
console.log('changeDeviceInfo')
console.log(params);
if (device_infos.value[params.station_id] === undefined) {
device_infos.value[params.station_id] = [params]
} else {
device_infos.value[params.station_id].push(params)
}
}
// clipboard 赋值到设备信息到 ini 文件中
const { toClipboard } = useClipboard()
const copy = async () => {
let configText = composeConfigText()
try {
await toClipboard(configText)
ElMessage({
message: '复制成功',
type: 'success',
})
} catch (error) {
console.log(error);
}
}
// 生成和 ini 文件中类似的配置格式
function composeConfigText(): string {
let configText = ''
for (const [station_level, device_info_list] of Object.entries(device_infos.value)) {
configText += `[Device_info_${station_level}]\n`
configText += `dev_num=${device_info_list.length}\n`
for (let i = 1; i <= device_info_list.length; i++) {
configText += `dev${i}_id=${device_info_list[i - 1].device_id}\n`
configText += `dev${i}_name=${device_info_list[i - 1].device_name}\n`
configText += `dev${i}_name_chn=${device_info_list[i - 1].device_name_chn}\n`
configText += `dev${i}_datacatlog=${device_info_list[i - 1].protocol_name}\n`
}
}
return configText
}
// 应用设备通信参数
const applyComunications = () => {
console.log('applyComunications')
axios.post('/api/device_communication/set_communication_to_devinfo_table/', {
type: props.tabType
})
.then((res) => {
console.log(res.data);
ElMessage({
message: '应用成功',
type: 'success'
})
})
.catch((err) => {
console.log(err);
ElMessage({
message: '应用失败',
type: 'error'
})
})
}
</script>
<template>
<el-descriptions :title="deviceInfo.device_name" :column=1>
<template #extra>
<el-button type="danger" size="small" @click="del">delete</el-button>
<el-button type="primary" size="small" @click="dialogFormVisible = true">Edit</el-button>
</template>
<el-descriptions-item label="协议名">{{ deviceInfo.protocol_name }}</el-descriptions-item>
<el-descriptions-item label="通信参数" :column=3>
<span> {{ deviceInfo.communicate_mode }} </span>
<span v-if="isTcp">
<span ml-9> {{ deviceInfo.tcp_ip }} </span>
<span ml-9> {{ deviceInfo.tcp_port }} </span>
</span>
<span v-else>
<span ml-9> {{ deviceInfo.udp_ip_src}} </span>
<span ml-9> {{ deviceInfo.udp_port_src }} </span>
<span ml-9> {{ deviceInfo.udp_ip_dst }} </span>
<span ml-9> {{ deviceInfo.udp_port_dst }} </span>
</span>
</el-descriptions-item>
<el-descriptions-item label="性能参数">
<el-tag v-for="tag in checked_performance_fields" :key="tag" class="mx-1 mt-1">
{{ tag }}
</el-tag>
</el-descriptions-item>
</el-descriptions>
<el-divider />
<edit-dialog
:is-show="dialogFormVisible"
:device-info="deviceInfo"
:tab-type="props.tabType"
@close="dialogFormVisible = false"
@change-device-info="changeDeviceInfo"
type="edit" />
</template>
<script setup lang="ts">
import { onMounted, ref, watch} from 'vue';
import axios from 'axios';
import { ElMessage, ElMessageBox } from 'element-plus';
import type { DeviceInfo } from '@/components/device_communication/types';
import EditDialog from './EditDialog.vue';
type propType = {
deviceInfo: DeviceInfo,
tabType: string
}
const props = defineProps<propType>();
const deviceInfo = ref<DeviceInfo>(props.deviceInfo)
const checked_performance_fields = ref<string[]>([])
const isTcp = ref<boolean>(true)
// performance_fields tag
const dialogFormVisible = ref(false)
onMounted(() => {
isTcp.value = deviceInfo.value.communicate_mode.toUpperCase().includes('TCP'.toUpperCase())
checked_performance_fields.value = JSON.parse(deviceInfo.value.performance_fields!)
deviceInfo.value.checked_performance_fields = checked_performance_fields.value
})
// 观察 device_info 是否有变化,如果有变化则更新
watch(() => props.deviceInfo, () => {
deviceInfo.value = props.deviceInfo
})
const emit = defineEmits(['deleteDeviceInfo'])
const del = () => {
ElMessageBox.confirm("确认删除吗?", "TIP")
.then(() => {
let station_id = deviceInfo.value.station_id
let id = deviceInfo.value.id
axios.delete('/api/device_communication/' + props.tabType + '/' + id + '/')
.then(() => {
emit('deleteDeviceInfo', { station_id, id })
ElMessage({
message: '删除成功',
type: 'success',
})
})
.catch((err) => {
console.log(err);
})
})
.catch(() => {});
}
const changeDeviceInfo = (device_info: DeviceInfo) => {
console.log('changeDeviceInfo')
deviceInfo.value = device_info
checked_performance_fields.value = JSON.parse(device_info.performance_fields!)
}
</script>
<style>
.el-descriptions__label:not(.is-bordered-label) {
color: var(--el-text-color-regular) !important;
font-weight: bold;
}
</style>
\ No newline at end of file
<template>
<el-dialog v-model="dialogFormVisible" title="编辑通信参数" @close="handleClose">
<el-form :model="form" ref="formRef" :rules="rules">
<el-form-item label="设备名称" :label-width="formLabelWidth" prop="device_name">
<el-input v-model="form.device_name" autocomplete="false" />
</el-form-item>
<el-form-item label="设备中文名" :label-width="formLabelWidth" prop="device_name_chn">
<el-input v-model="form.device_name_chn" autocomplete="false" />
</el-form-item>
<!-- <el-form-item label="设备序号" :label-width="formLabelWidth" prop="device_name_chn">
<el-input v-model="form.device_id" autocomplete="false" />
</el-form-item> -->
<el-form-item label="所属站点" :label-width="formLabelWidth" prop="station_id">
<el-input v-model="form.station_id" autocomplete="false" />
</el-form-item>
<el-form-item label="协议名称" :label-width="formLabelWidth" prop="protocol_name">
<el-select v-model="form.protocol_name" @change="handleProtocolChange(form.protocol_name, [])">
<el-option v-for="protocolName in store.protocolNames" :label="protocolName.label" :value="protocolName.value" />
</el-select>
</el-form-item>
<el-form-item label="通信模式" :label-width="formLabelWidth" prop="communicate_mode">
<el-select v-model="form.communicate_mode" @change="handleModeChange">
<el-option label="TCP_SERVER" value="TCP_SERVER" />
<el-option label="TCP_CLIENT" value="TCP_CLIENT" />
<el-option label="UDP" value="UDP" />
<el-option label="UDP_MC" value="UDP_MC" />
</el-select>
</el-form-item>
<div v-if="isTcp">
<el-form-item label="IP" :label-width="formLabelWidth" prop="tcp_ip">
<el-input v-model="form.tcp_ip" autocomplete="false" />
</el-form-item>
<el-form-item label="端口" :label-width="formLabelWidth" prop="tcp_port">
<el-input v-model="form.tcp_port" autocomplete="false" />
</el-form-item>
</div>
<div v-else>
<el-form-item label="源IP" :label-width="formLabelWidth" prop="udp_ip_src">
<el-input v-model="form.udp_ip_src" autocomplete="false" />
</el-form-item>
<el-form-item label="源端口" :label-width="formLabelWidth" prop="udp_port_src">
<el-input v-model="form.udp_port_src" autocomplete="false" />
</el-form-item>
<el-form-item label="目标IP" :label-width="formLabelWidth" prop="udp_ip_dst">
<el-input v-model="form.udp_ip_dst" autocomplete="false" />
</el-form-item>
<el-form-item label="目标端口" :label-width="formLabelWidth" prop="udp_port_dst">
<el-input v-model="form.udp_port_dst" autocomplete="false" />
</el-form-item>
</div>
<el-form-item label="监控属性" :label-width="formLabelWidth">
<el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange">
Check all
</el-checkbox>
<el-checkbox-group v-model="checked_performance_fields" @change="handleCheckedFieldsChange">
<el-checkbox v-for="field in performance_fields" :key="field" :label="field">
{{ field }}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogFormVisible = false">Cancel</el-button>
<el-button type="primary" @click="submit_form">
Confirm
</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { reactive, ref, watch } from 'vue';
import type { CheckboxValueType, ElForm } from 'element-plus';
import { ElMessage, FormRules } from 'element-plus'
import axios from 'axios';
import { DeviceInfo } from "./types";
import { useProtocolNamesStore } from '@/stores/protocolNames';
// protocol name 存储
const store = useProtocolNamesStore()
// form 表单对象
const formRef = ref<typeof ElForm>()
// 弹出框是否可见,默认不可见
// 弹出框表单 label 的宽度
const dialogFormVisible = ref(false)
const formLabelWidth = "120px"
// 父组件往这里传的类型
type porpsType = {
isShow: boolean,
deviceInfo?: DeviceInfo,
type: string,
tabType: string
}
const props = defineProps<porpsType>()
// 返回父组件的方法
const emit = defineEmits(['close', 'changeDeviceInfo'])
// 关闭弹出框的执行的操作
const handleClose = () => {
// 向父组件发射关闭弹出框的事件
emit('close')
// 表单所有的校验和数据重置
formRef.value!.resetFields()
}
// 默认表单数据
const form = ref<DeviceInfo>({
station_id: "",
device_id: 0,
device_name: "",
device_name_chn: "",
protocol_name: "",
communicate_mode: "",
tcp_ip: "",
tcp_port: 0,
udp_ip_src: "",
udp_port_src: 0,
udp_ip_dst: "",
udp_port_dst: 0
})
// 检测弹出框是否弹出,如果弹出赋值
watch(() => props.isShow, () => {
dialogFormVisible.value = props.isShow
// 判断传下来的类型是不是 edit,如果是,需要将展示的数据放到表单上
if (props.isShow && props.type === "edit") {
form.value = {
id: props.deviceInfo!.id,
station_id: props.deviceInfo!.station_id,
device_id: props.deviceInfo!.device_id,
device_name: props.deviceInfo!.device_name,
device_name_chn: props.deviceInfo!.device_name_chn,
protocol_name: props.deviceInfo!.protocol_name,
communicate_mode: props.deviceInfo!.communicate_mode,
tcp_ip: props.deviceInfo!.tcp_ip,
tcp_port: props.deviceInfo!.tcp_port,
udp_ip_src: props.deviceInfo!.udp_ip_src,
udp_port_src: props.deviceInfo!.udp_port_src,
udp_ip_dst: props.deviceInfo!.udp_ip_dst,
udp_port_dst: props.deviceInfo!.udp_port_dst,
}
handleModeChange(form.value.communicate_mode)
checked_performance_fields.value = props.deviceInfo!.checked_performance_fields!
handleProtocolChange(form.value.protocol_name, checked_performance_fields.value)
}
})
// 校验 ip 是否正确
const validateIP = (_: any, value: any, callback: any) => {
if (value === '') {
callback(new Error('Please input the IP again'))
}
const ipRegex = /^(\d{1,3}\.){3}\d{1,3}$/;
if (!ipRegex.test(value)) {
callback(new Error('请输入有效的IP地址'));
} else {
callback();
}
}
// 校验 port 是否正确
const validatePort = (_: any, value: any, callback: any) => {
if (value === '') {
callback(new Error('Please input the port again'))
}
const portRegex = /^[1-9]\d{1,4}$/;
if (!portRegex.test(value)) {
callback(new Error('请输入有效的端口'));
} else {
callback();
}
}
// 表单校验规则
const rules = reactive<FormRules<typeof form>>({
station_id: [{ required: true, message: 'Please input station id', trigger: 'blur' }],
// device_id: [{ required: true, message: 'Please input device id', trigger: 'blur' }],
device_name: [{ required: true, message: 'Please input device name', trigger: 'blur' }],
device_name_chn: [{ required: true, message: 'Please input device name chn', trigger: 'blur' }],
protocol_name: [{ required: true, message: 'Please input protocol name', trigger: 'blur' }],
communicate_mode: [{ required: true, message: 'Please input communicate mode', trigger: 'blur' }],
tcp_ip: [
{ required: true, message: 'Please input tcp ip', trigger: 'blur' },
{ validator: validateIP, trigger: 'blur' }],
tcp_port: [
{ required: true, message: 'Please input tcp port', trigger: 'blur' },
{ validator: validatePort, trigger: 'blur'}
],
udp_ip_src: [
{ required: true, message: 'Please input upd src ip', trigger: 'blur' },
{ validator: validateIP, trigger: 'blur' }],
udp_port_src: [
{ required: true, message: 'Please input udp src port', trigger: 'blur' },
{ validator: validatePort, trigger: 'blur'}
],
udp_ip_dst: [
{ required: true, message: 'Please input udp dst ip', trigger: 'blur' },
{ validator: validateIP, trigger: 'blur' }],
udp_port_dst: [
{ required: true, message: 'Please input udp dst port', trigger: 'blur' },
{ validator: validatePort, trigger: 'blur'}
],
})
// 下拉框选择触发的事件
const handleProtocolChange = (protocol_name: string, checked_fields: string[]) => {
axios.get('/api/device_communication/protocol_performance/' + protocol_name + '/')
.then((res) => {
performance_fields.value = res.data
checked_performance_fields.value = checked_fields
})
.catch((err) => {
console.log(err);
})
}
// 性能参数相关
const checkAll = ref(false)
// 设置不确定状态,仅负责样式控制
const isIndeterminate = ref(true)
const performance_fields = ref<string[]>([])
const checked_performance_fields = ref<string[]>([])
// 全选
const handleCheckAllChange = (val: CheckboxValueType) => {
checked_performance_fields.value = val ? performance_fields.value : []
isIndeterminate.value = false
}
// 选中某个
const handleCheckedFieldsChange = (value: CheckboxValueType[]) => {
const checkedCount = value.length
checkAll.value = checkedCount === performance_fields.value.length
isIndeterminate.value = checkedCount > 0 && checkedCount < performance_fields.value.length
}
// 选择通信模式后
const isTcp = ref(true)
const handleModeChange = (value: string) => {
console.log(value)
isTcp.value = value.toUpperCase().includes('TCP'.toUpperCase())
}
// 提交表单
const submit_form = () => {
// 表单字段全部正确才能提交
formRef.value!.validate((valid: boolean) => {
if (valid) {
submit()
} else {
ElMessage({
message: '请检查表单',
type: 'error'
})
}
})
}
const submit = () => {
// 获取表单数据
let data: DeviceInfo = {
station_id: form.value.station_id,
device_id: form.value.device_id,
device_name: form.value.device_name,
device_name_chn: form.value.device_name_chn,
protocol_name: form.value.protocol_name,
communicate_mode: form.value.communicate_mode,
tcp_ip: form.value.tcp_ip,
tcp_port: form.value.tcp_port,
udp_ip_src: form.value.udp_ip_src,
udp_port_src: form.value.udp_port_src,
udp_ip_dst: form.value.udp_ip_dst,
udp_port_dst: form.value.udp_port_dst,
performance_fields: JSON.stringify(checked_performance_fields.value)
}
if (props.type === "add") {
// 添加通信参数方法
axios.post('/api/device_communication/' + props.tabType + '/', data)
.then((res) => {
console.log(res.data)
data = res.data
ElMessage({
message: '创建成功',
type: 'success'
})
emit('changeDeviceInfo', data)
})
.catch((err) => {
console.log(err);
})
}
else if (props.type === "edit")
{
// 修改通信参数方法
data.id = form.value.id
axios.put('/api/device_communication/' + props.tabType + '/' + data.id + '/', data)
.then((res) => {
console.log(res);
ElMessage({
message: '修改成功',
type: 'success'
})
emit('changeDeviceInfo', data)
})
.catch((err) => {
console.log(err);
})
}
emit('close')
}
</script>
export interface DeviceInfo {
id?: number,
station_id: string,
device_id: number,
device_name: string,
device_name_chn: string,
protocol_name: string,
communicate_mode: string,
tcp_ip: string,
tcp_port: number,
udp_ip_src: string,
udp_port_src: number,
udp_ip_dst: string,
udp_port_dst: number,
performance_fields?: string
checked_performance_fields?: string[]
}
import { defineStore } from 'pinia'
import { ref } from 'vue'
type ProtocolName = {
label: string
value: string
}
export const useProtocolNamesStore = defineStore('protocolNames', () => {
const protocolNames = ref<ProtocolName[]>([])
return {
protocolNames
}
})
<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[]>([
'{"interface_id":"IID_OAM_Server_HistoryPerformance","dst_suid":285540352,"src_suid":285474816,"priority":100,"ts":"2023-08-08T08:16:14.224831Z","parameters":[{"@type":"type.googleapis.com/RequireHistoryPerformance","station_id":286261248,"start_time":"2023-07-17 02:27:44","end_time":"2023-07-17 02:39:07"}],"forward_flag":0,"request_index":"0","operations_type":0}',
'{"interface_id":"IID_OAM_Server_HistoryPerformance","dst_suid":285540352,"src_suid":285474816,"priority":100,"ts":"2023-08-08T08:16:14.224831Z","parameters":[{"@type":"type.googleapis.com/RequireHistoryPerformance","station_id":286261248,"start_time":"2023-07-17 02:27:44","end_time":"2023-07-17 02:39:07"}],"forward_flag":0,"request_index":"0","operations_type":0}',
'{"interface_id":"IID_OAM_Server_HistoryPerformance","dst_suid":285540352,"src_suid":285474816,"priority":100,"ts":"2023-08-08T08:16:14.224831Z","parameters":[{"@type":"type.googleapis.com/RequireHistoryPerformance","station_id":286261248,"start_time":"2023-07-17 02:27:44","end_time":"2023-07-17 02:39:07"}],"forward_flag":0,"request_index":"0","operations_type":0}',
'{"interface_id":"IID_OAM_Server_HistoryPerformance","dst_suid":285540352,"src_suid":285474816,"priority":100,"ts":"2023-08-08T08:16:14.224831Z","parameters":[{"@type":"type.googleapis.com/RequireHistoryPerformance","station_id":286261248,"start_time":"2023-07-17 02:27:44","end_time":"2023-07-17 02:39:07"}],"forward_flag":0,"request_index":"0","operations_type":0}',
'{"interface_id":"IID_OAM_Server_HistoryPerformance","dst_suid":285540352,"src_suid":285474816,"priority":100,"ts":"2023-08-08T08:16:14.224831Z","parameters":[{"@type":"type.googleapis.com/RequireHistoryPerformance","station_id":286261248,"start_time":"2023-07-17 02:27:44","end_time":"2023-07-17 02:39:07"}],"forward_flag":0,"request_index":"0","operations_type":0}',
'{"interface_id":"IID_OAM_Server_HistoryPerformance","dst_suid":285540352,"src_suid":285474816,"priority":100,"ts":"2023-08-08T08:16:14.224831Z","parameters":[{"@type":"type.googleapis.com/RequireHistoryPerformance","station_id":286261248,"start_time":"2023-07-17 02:27:44","end_time":"2023-07-17 02:39:07"}],"forward_flag":0,"request_index":"0","operations_type":0}',
'{"interface_id":"IID_OAM_Server_HistoryPerformance","dst_suid":285540352,"src_suid":285474816,"priority":100,"ts":"2023-08-08T08:16:14.224831Z","parameters":[{"@type":"type.googleapis.com/RequireHistoryPerformance","station_id":286261248,"start_time":"2023-07-17 02:27:44","end_time":"2023-07-17 02:39:07"}],"forward_flag":0,"request_index":"0","operations_type":0}',
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);
......@@ -43,8 +43,8 @@ onMounted(() => {
);
chatSocket.onmessage = (e) => {
console.log(e);
console.log(e.data)
// console.log(e);
// console.log(e.data)
// // 接收到的是字节流数据(ArrayBuffer)
// const byteArray = new Uint8Array(e.data);
// // 将字节流转换为字符串或其他格式进行处理
......@@ -58,12 +58,34 @@ onMounted(() => {
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',
})
})
}
</script>
<template>
<el-scrollbar ref="scrollbarRef" mb-10 height="400px" always>
<div ref="innerRef">
<p v-for="item in items" :key="item" class="scrollbar-demo-item">
<p v-for="item in items" :key="item" class="scrollbar-demo-item text-sm">
<div>{{ JSON.parse(item)?.ts }}</div>
{{ item }}
</p>
......@@ -72,7 +94,9 @@ onMounted(() => {
<el-input v-model="input" placeholder="Please input" @keyup.enter="send"></el-input>
<el-button @click="send">Send</el-button>
<br/>
<device-performance-table v-for="param in deviceTableParams" mt-5 :group-name="param" :key="param" />
<el-button @click="addDeviceTable" class="mt-5" >Add table</el-button>
</template>
<style scoped>
......
<template>
<el-tabs v-model="activeName" type="card" class="demo-tabs">
<el-tab-pane label="device" name="device">
<communication-tab tab-type="communicate" />
</el-tab-pane>
<el-tab-pane label="simulate_device" name="simulate_device">
<communication-tab tab-type="simulate_communicate" />
</el-tab-pane>
</el-tabs>
</template>
<script lang="ts" setup>
import axios from 'axios';
import { onMounted, ref } from 'vue'
import { useProtocolNamesStore } from '@/stores/protocolNames'
import CommunicationTab from "@/components/device_communication/CommunicationTab";
// tab 相关
const activeName = ref<string>('simulate_device')
onMounted(() => {
axios.get('/api/device_communication/')
.then((res) => {
const store = useProtocolNamesStore()
store.protocolNames.push(...res.data)
})
})
</script>
<template>
<el-select class="mb-5" v-model="value" placeholder="Select">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<br>
<el-tag v-for="tag in tags" :key="tag" class="mx-1" closable @close="handleClose(tag)">
{{ tag }}
</el-tag>
</template>
<script lang="ts" setup>
import axios from 'axios';
import { onMounted, ref, watch } from 'vue'
const tags = ref<string[]>(['111', '222'])
const handleClose = (tag: string) => {
tags.value.splice(tags.value.indexOf(tag), 1)
console.log(tags.value);
}
const value = ref('')
type OptionItem = {
value: string,
label: string
}
const options = ref<OptionItem[]>([])
onMounted(() => {
axios.get(
'api/device_communication/'
).then((res) => {
options.value = res.data
}).catch((err) => {
console.log(err);
})
})
watch(value, () => {
axios.post(
'api/device_communication/protocol_performance/',
{
'protocol_name': value.value,
}).then((res) => {
console.log(res)
tags.value = res.data
}).catch((err) => {
console.log(err);
})
})
</script>
<template>
<el-upload
class="upload-demo"
action="api/protocol_version_manage/file_upload/"
:show-file-list="false"
:data="data"
>
<el-button type="primary">Click to upload</el-button>
</el-upload>
<br>
<el-button type="primary" @click="downloadFile">下载原始文件</el-button>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import axios from "axios";
const data = ref({
"protocol_name": "HY_VirtualDevice_PROTOCOL",
"version": "222",
});
const downloadFile = () => {
let url = "api/protocol_version_manage/file_download/HY_VirtualDevice_PROTOCOL/222/";
axios({
url,
method: "GET",
responseType: "blob",
}).then((res) => {
// 下载文件
console.log(res);
const blob = new Blob([res.data], { type: "multipart/form-data" });
const link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
link.download = decodeURIComponent(res.headers["filename"]);
link.click();
});
console.log("downloadFile");
};
</script>
// vite.config.ts
import { defineConfig } from "file:///W:/work/NetCopilot/test/vue_django/frontend/node_modules/vite/dist/node/index.js";
import vue from "file:///W:/work/NetCopilot/test/vue_django/frontend/node_modules/@vitejs/plugin-vue/dist/index.mjs";
import legacy from "file:///W:/work/NetCopilot/test/vue_django/frontend/node_modules/@vitejs/plugin-legacy/dist/index.mjs";
import UnoCSS from "file:///W:/work/NetCopilot/test/vue_django/frontend/node_modules/unocss/dist/vite.mjs";
import { resolve } from "path";
import process from "process";
function pathResolve(dir) {
return resolve(process.cwd(), ".", dir);
}
var vite_config_default = defineConfig({
resolve: {
alias: {
"@": pathResolve("src")
},
extensions: [".ts", ".js", ".vue"]
// 使用路径别名时想要省略的后缀名,可以自己 增减
},
plugins: [
legacy({
targets: ["defaults", "not IE 11"]
}),
vue(),
UnoCSS()
],
base: "./",
server: {
host: "0.0.0.0"
}
});
export {
vite_config_default as default
};
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJXOlxcXFx3b3JrXFxcXE5ldENvcGlsb3RcXFxcdGVzdFxcXFx2dWVfZGphbmdvXFxcXGZyb250ZW5kXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ZpbGVuYW1lID0gXCJXOlxcXFx3b3JrXFxcXE5ldENvcGlsb3RcXFxcdGVzdFxcXFx2dWVfZGphbmdvXFxcXGZyb250ZW5kXFxcXHZpdGUuY29uZmlnLnRzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9XOi93b3JrL05ldENvcGlsb3QvdGVzdC92dWVfZGphbmdvL2Zyb250ZW5kL3ZpdGUuY29uZmlnLnRzXCI7aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAndml0ZSdcbmltcG9ydCB2dWUgZnJvbSAnQHZpdGVqcy9wbHVnaW4tdnVlJ1xuaW1wb3J0IGxlZ2FjeSBmcm9tICdAdml0ZWpzL3BsdWdpbi1sZWdhY3knXG5pbXBvcnQgVW5vQ1NTIGZyb20gJ3Vub2Nzcy92aXRlJ1xuaW1wb3J0IHsgcmVzb2x2ZSB9IGZyb20gJ3BhdGgnXG5pbXBvcnQgcHJvY2VzcyBmcm9tICdwcm9jZXNzJ1xuXG5mdW5jdGlvbiBwYXRoUmVzb2x2ZShkaXI6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiByZXNvbHZlKHByb2Nlc3MuY3dkKCksICcuJywgZGlyKVxufTtcblxuXG4vLyBodHRwczovL3ZpdGVqcy5kZXYvY29uZmlnL1xuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcbiAgcmVzb2x2ZToge1xuICAgIGFsaWFzOiB7XG4gICAgICBcIkBcIjogcGF0aFJlc29sdmUoJ3NyYycpXG4gICAgfSxcbiAgICBleHRlbnNpb25zOiBbJy50cycsICcuanMnLCAnLnZ1ZSddIC8vIFx1NEY3Rlx1NzUyOFx1OERFRlx1NUY4NFx1NTIyQlx1NTQwRFx1NjVGNlx1NjBGM1x1ODk4MVx1NzcwMVx1NzU2NVx1NzY4NFx1NTQwRVx1N0YwMFx1NTQwRFx1RkYwQ1x1NTNFRlx1NEVFNVx1ODFFQVx1NURGMSBcdTU4OUVcdTUxQ0ZcbiAgfSxcbiAgcGx1Z2luczogW1xuICAgIGxlZ2FjeSh7XG4gICAgICB0YXJnZXRzOiBbJ2RlZmF1bHRzJywgJ25vdCBJRSAxMSddLFxuICAgIH0pLFxuICAgIHZ1ZSgpLFxuICAgIFVub0NTUygpXG4gIF0sXG4gIGJhc2U6ICAnLi8nLFxuICBzZXJ2ZXI6IHtcbiAgICBob3N0OiAnMC4wLjAuMCcsXG4gIH1cbn0pXG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQStULFNBQVMsb0JBQW9CO0FBQzVWLE9BQU8sU0FBUztBQUNoQixPQUFPLFlBQVk7QUFDbkIsT0FBTyxZQUFZO0FBQ25CLFNBQVMsZUFBZTtBQUN4QixPQUFPLGFBQWE7QUFFcEIsU0FBUyxZQUFZLEtBQXFCO0FBQ3hDLFNBQU8sUUFBUSxRQUFRLElBQUksR0FBRyxLQUFLLEdBQUc7QUFDeEM7QUFJQSxJQUFPLHNCQUFRLGFBQWE7QUFBQSxFQUMxQixTQUFTO0FBQUEsSUFDUCxPQUFPO0FBQUEsTUFDTCxLQUFLLFlBQVksS0FBSztBQUFBLElBQ3hCO0FBQUEsSUFDQSxZQUFZLENBQUMsT0FBTyxPQUFPLE1BQU07QUFBQTtBQUFBLEVBQ25DO0FBQUEsRUFDQSxTQUFTO0FBQUEsSUFDUCxPQUFPO0FBQUEsTUFDTCxTQUFTLENBQUMsWUFBWSxXQUFXO0FBQUEsSUFDbkMsQ0FBQztBQUFBLElBQ0QsSUFBSTtBQUFBLElBQ0osT0FBTztBQUFBLEVBQ1Q7QUFBQSxFQUNBLE1BQU87QUFBQSxFQUNQLFFBQVE7QUFBQSxJQUNOLE1BQU07QUFBQSxFQUNSO0FBQ0YsQ0FBQzsiLAogICJuYW1lcyI6IFtdCn0K
......@@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default()
from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2
from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
import TDSCmd_pb2 as TDSCmd__pb2
from . import TDSCmd_pb2 as TDSCmd_pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x17\x44\x65vice_datastruct.proto\x1a\x19google/protobuf/any.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x0cTDSCmd.proto\"o\n\x12Proto3DeviceAllCMD\x12\n\n\x02ID\x18\x01 \x01(\x05\x12\x10\n\x08\x44\x45V_NAME\x18\x02 \x01(\t\x12\x15\n\rPROTOCOL_NAME\x18\x03 \x01(\t\x12$\n\x04\x43MDs\x18\x04 \x03(\x0b\x32\x16.Proto3DeviceCMDDefine\"~\n\x15Proto3DeviceCMDDefine\x12\x10\n\x08\x43MD_NAME\x18\x01 \x01(\t\x12\x0e\n\x06\x45NCODE\x18\x02 \x01(\t\x12\x1f\n\x17Timing_CMD_Cycle_period\x18\x03 \x01(\x05\x12\"\n\x06\x66\x65lids\x18\x04 \x03(\x0b\x32\x12.Proto3CMDFieldCfg\"\x9d\x01\n\x17Proto3ForReloadProtocol\x12\x10\n\x08\x64\x65v_name\x18\x01 \x01(\t\x12\x10\n\x08\x63md_name\x18\x02 \x01(\t\x12-\n\x05\x66lags\x18\x03 \x01(\x0e\x32\x1e.Proto3ForReloadProtocol.Flags\"/\n\x05\x46lags\x12\x13\n\x0fNORMAL_DISPATCH\x10\x00\x12\x11\n\rFULL_DISPATCH\x10\x01\"\xa8\x01\n\x19Proto3TableDevCmdNamePoll\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x15\n\rprotocol_name\x18\x02 \x01(\t\x12\x10\n\x08\x63md_name\x18\x03 \x01(\t\x12\x10\n\x08\x63md_type\x18\x04 \x01(\t\x12\x0e\n\x06\x65ncode\x18\x05 \x01(\t\x12\x1f\n\x17timing_cmd_cycle_period\x18\x06 \x01(\x05\x12\x13\n\x0b\x63md_explain\x18\x07 \x01(\t\"\x85\x03\n\x1aProto3TableAllDevCmdDefine\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x10\n\x08\x63md_name\x18\x02 \x01(\t\x12\x10\n\x08\x63md_type\x18\x03 \x01(\t\x12\x12\n\nfieldindex\x18\x04 \x01(\x05\x12\x11\n\tfieldname\x18\x05 \x01(\t\x12\x11\n\tfieldsize\x18\x06 \x01(\x05\x12\r\n\x05value\x18\x07 \x01(\t\x12\x10\n\x08minvalue\x18\x08 \x01(\t\x12\x10\n\x08maxvalue\x18\t \x01(\t\x12\x10\n\x08\x64\x61tatype\x18\n \x01(\x05\x12\x14\n\x0coperation_in\x18\x0b \x01(\x05\x12\x18\n\x10operation_in_num\x18\x0c \x01(\x05\x12\x15\n\roperation_out\x18\r \x01(\x05\x12\x19\n\x11operation_out_num\x18\x0e \x01(\x05\x12\x12\n\noperabo_in\x18\x0f \x01(\x05\x12\x13\n\x0boperabo_out\x18\x10 \x01(\x05\x12\x15\n\rlua_script_in\x18\x11 \x01(\t\x12\x16\n\x0elua_script_out\x18\x12 \x01(\t\"\xa2\x03\n\x13Proto3DeviceInfoCfg\x12\n\n\x02ID\x18\x01 \x01(\x05\x12\x0e\n\x06STA_ID\x18\x02 \x01(\t\x12\x0e\n\x06\x44\x45V_ID\x18\x03 \x01(\x05\x12\x10\n\x08\x44\x45V_NAME\x18\x04 \x01(\t\x12\x14\n\x0c\x44\x45V_NAME_CHN\x18\x05 \x01(\t\x12\x15\n\rPROTOCOL_NAME\x18\x06 \x01(\t\x12\x16\n\x0e\x43MD_EXCEL_PATH\x18\x07 \x01(\t\x12\x17\n\x0f\x43OMUNITATE_MODE\x18\x08 \x01(\t\x12\x0e\n\x06TCP_IP\x18\t \x01(\t\x12\x10\n\x08TCP_PORT\x18\n \x01(\x05\x12\x12\n\nUDP_IP_SRC\x18\x0b \x01(\t\x12\x14\n\x0cUDP_PORT_SRC\x18\x0c \x01(\x05\x12\x12\n\nUDP_IP_DST\x18\r \x01(\t\x12\x14\n\x0cUDP_PORT_DST\x18\x0e \x01(\x05\x12\x10\n\x08UDPMC_IP\x18\x0f \x01(\t\x12\x13\n\x0bUDPMC_IP_TX\x18\x10 \x01(\t\x12\x15\n\rUDPMC_PORT_TX\x18\x11 \x01(\x05\x12\x13\n\x0bUDPMC_IP_RX\x18\x12 \x01(\t\x12\x15\n\rUDPMC_PORT_RX\x18\x13 \x01(\x05\x12\x0f\n\x07REMARKS\x18\x14 \x01(\t\"\xed\x02\n\x11Proto3CMDFieldCfg\x12\n\n\x02ID\x18\x01 \x01(\x05\x12\x12\n\nfieldIndex\x18\x02 \x01(\x05\x12\x11\n\tfieldName\x18\x03 \x01(\t\x12\x11\n\tfieldSize\x18\x04 \x01(\x05\x12\r\n\x05value\x18\x05 \x01(\t\x12\x10\n\x08minValue\x18\x06 \x01(\t\x12\x10\n\x08maxValue\x18\x07 \x01(\t\x12\x10\n\x08\x64\x61taType\x18\x08 \x01(\x05\x12\x14\n\x0coperation_in\x18\t \x01(\x05\x12\x18\n\x10operation_in_num\x18\n \x01(\x05\x12\x15\n\roperation_out\x18\x0b \x01(\x05\x12\x19\n\x11operation_out_num\x18\x0c \x01(\x05\x12\x12\n\noperaBO_in\x18\r \x01(\x05\x12\x13\n\x0boperaBO_out\x18\x0e \x01(\x05\x12\x15\n\rLua_Script_in\x18\x0f \x01(\t\x12\x16\n\x0eLua_Script_out\x18\x10 \x01(\t\x12\x13\n\x0bvalue_bytes\x18\x13 \x01(\x0c\"\xaa\x01\n\x1cProto3TableSoftLimitAngleCfg\x12\n\n\x02ID\x18\x01 \x01(\x05\x12\x0e\n\x06STA_ID\x18\x02 \x01(\t\x12\x10\n\x08\x44\x45V_NAME\x18\x03 \x01(\t\x12\x14\n\x0c\x44\x45V_NAME_CHN\x18\x04 \x01(\t\x12\x15\n\rPROTOCOL_NAME\x18\x05 \x01(\t\x12\x1e\n\x16PITCH_SOFT_LIMIT_ANGLE\x18\x06 \x01(\t\x12\x0f\n\x07REMARKS\x18\x07 \x01(\t\"\xd9\x02\n\x0bTDSDBC_CURD\x12\r\n\x05table\x18\x01 \x01(\t\x12!\n\x05\x66lags\x18\x02 \x01(\x0e\x32\x12.TDSDBC_CURD.Flags\x12)\n\toperation\x18\x03 \x01(\x0e\x32\x16.TDSDBC_CURD.Operation\x12\x18\n\x04\x63ode\x18\x04 \x01(\x0e\x32\n.CodeValue\x12\x0b\n\x03msg\x18\x05 \x01(\t\x12\x0f\n\x07msg_CHN\x18\x06 \x01(\t\x12&\n\x08\x61ny_data\x18\x07 \x03(\x0b\x32\x14.google.protobuf.Any\"/\n\x05\x46lags\x12\x13\n\x0fNORMAL_DISPATCH\x10\x00\x12\x11\n\rFULL_DISPATCH\x10\x01\"\\\n\tOperation\x12\x11\n\rOPERATION_ADD\x10\x00\x12\x11\n\rOPERATION_DEL\x10\x01\x12\x14\n\x10OPERATION_UPDATE\x10\x02\x12\x13\n\x0fOPERATION_QUERY\x10\x03\"\xbc\x01\n\x11TDSXDC_Device_cmd\x12\x10\n\x08\x44\x65viceID\x18\x01 \x01(\r\x12\x10\n\x08\x64\x65v_name\x18\x02 \x01(\t\x12\x10\n\x08\x63md_name\x18\x03 \x01(\t\x12\x15\n\rprotocol_name\x18\x04 \x01(\t\x12\x18\n\x04\x63ode\x18\x05 \x01(\x0e\x32\n.CodeValue\x12\x0b\n\x03msg\x18\x06 \x01(\t\x12\x0f\n\x07msg_CHN\x18\x07 \x01(\t\x12\"\n\x06\x66ields\x18\x08 \x03(\x0b\x32\x12.Proto3CMDFieldCfg*\x7f\n\x0e\x41larmID_define\x12\x0b\n\x07ID_Base\x10\x00\x12\x15\n\x0e\x44\x65vAla_id_Base\x10\x80\x87\xa7\x0e\x12\x18\n\x11\x44\x65vAla_id_Offline\x10\x81\x87\xa7\x0e\x12/\n(DevAla_id_Antenna_pitch_angle_soft_limit\x10\x82\x87\xa7\x0e\x42\x0cZ\n../protogob\x06proto3')
......
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: mod-agi.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import builder as _builder
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\rmod-agi.proto\x12\x15satllite.protobuf.agi\"\xd0\x01\n\nCalcTleReq\x12\x0f\n\x07noradID\x18\x01 \x01(\x05\x12\x11\n\tnoradName\x18\x02 \x01(\t\x12\x0c\n\x04year\x18\x03 \x01(\x05\x12\r\n\x05month\x18\x04 \x01(\x05\x12\x0b\n\x03\x64\x61y\x18\x05 \x01(\x05\x12\x0c\n\x04hour\x18\x06 \x01(\x05\x12\x0e\n\x06minute\x18\x07 \x01(\x05\x12\x0e\n\x06second\x18\x08 \x01(\x05\x12\t\n\x01\x61\x18\t \x01(\x02\x12\n\n\x02\x65\x65\x18\n \x01(\x02\x12\t\n\x01I\x18\x0b \x01(\x02\x12\x0c\n\x04raan\x18\x0c \x01(\x02\x12\x0b\n\x03\x61rc\x18\r \x01(\x02\x12\t\n\x01m\x18\x0e \x01(\x02\"9\n\nCalcTleRet\x12\r\n\x05line0\x18\x01 \x01(\t\x12\r\n\x05line1\x18\x02 \x01(\t\x12\r\n\x05line2\x18\x03 \x01(\t\"\xba\x02\n\rCalcReportReq\x12\x15\n\rstartDateTime\x18\x01 \x01(\t\x12\x13\n\x0b\x65ndDateTime\x18\x02 \x01(\t\x12\x10\n\x08latitude\x18\x03 \x01(\x01\x12\x11\n\tlongitude\x18\x04 \x01(\x01\x12\x10\n\x08\x61ltitude\x18\x05 \x01(\x01\x12\r\n\x05slice\x18\x06 \x01(\x01\x12\x0e\n\x06minAzi\x18\x07 \x01(\x01\x12\x0e\n\x06maxAzi\x18\x08 \x01(\x01\x12\x0e\n\x06minEle\x18\t \x01(\x01\x12\x0e\n\x06maxEle\x18\n \x01(\x01\x12\x0f\n\x07minDist\x18\x0b \x01(\x01\x12\x0f\n\x07maxDist\x18\x0c \x01(\x01\x12\x12\n\npointSlice\x18\r \x01(\x01\x12\x14\n\x0cpointCollect\x18\x0e \x01(\x05\x12\r\n\x05line0\x18\x0f \x01(\t\x12\r\n\x05line1\x18\x10 \x01(\t\x12\r\n\x05line2\x18\x11 \x01(\t\"e\n\rCalcReportRet\x12(\n\x04xxds\x18\x01 \x03(\x0b\x32\x1a.satllite.protobuf.agi.Xxd\x12*\n\x05tasks\x18\x02 \x03(\x0b\x32\x1b.satllite.protobuf.agi.Task\";\n\x03Xxd\x12\n\n\x02\x64t\x18\x01 \x01(\t\x12\x0b\n\x03lon\x18\x02 \x01(\x01\x12\x0b\n\x03lat\x18\x03 \x01(\x01\x12\x0e\n\x06height\x18\x04 \x01(\x01\"\xb2\x01\n\x04Task\x12\r\n\x05start\x18\x01 \x01(\t\x12\x0b\n\x03\x65nd\x18\x02 \x01(\t\x12\x10\n\x08startAzi\x18\x03 \x01(\x01\x12\x0e\n\x06\x65ndAzi\x18\x04 \x01(\x01\x12\x10\n\x08startEle\x18\x05 \x01(\x01\x12\x0e\n\x06maxEle\x18\x06 \x01(\x01\x12\x0f\n\x07minDist\x18\x07 \x01(\x01\x12\x0f\n\x07maxDist\x18\x08 \x01(\x01\x12(\n\x04obss\x18\t \x03(\x0b\x32\x1a.satllite.protobuf.agi.Obs\":\n\x03Obs\x12\n\n\x02\x64t\x18\x01 \x01(\t\x12\x0b\n\x03\x61zi\x18\x02 \x01(\x01\x12\x0b\n\x03\x65le\x18\x03 \x01(\x01\x12\r\n\x05range\x18\x04 \x01(\x01\x42\x0cZ\n../protogob\x06proto3')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'mod_agi_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'Z\n../protogo'
_CALCTLEREQ._serialized_start=41
_CALCTLEREQ._serialized_end=249
_CALCTLERET._serialized_start=251
_CALCTLERET._serialized_end=308
_CALCREPORTREQ._serialized_start=311
_CALCREPORTREQ._serialized_end=625
_CALCREPORTRET._serialized_start=627
_CALCREPORTRET._serialized_end=728
_XXD._serialized_start=730
_XXD._serialized_end=789
_TASK._serialized_start=792
_TASK._serialized_end=970
_OBS._serialized_start=972
_OBS._serialized_end=1030
# @@protoc_insertion_point(module_scope)
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: mod-return.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import builder as _builder
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2
import TDSCmd_pb2 as TDSCmd__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10mod-return.proto\x1a\x19google/protobuf/any.proto\x1a\x0cTDSCmd.proto\"\xdb\x01\n\rReturnElement\x12\x1a\n\x06result\x18\x01 \x01(\x0e\x32\n.CodeValue\x12\x0b\n\x03msg\x18\x02 \x01(\t\x12\r\n\x05\x65nMsg\x18\x03 \x01(\t\x12\"\n\x04\x64\x61ta\x18\x04 \x01(\x0b\x32\x14.google.protobuf.Any\x12\"\n\x04list\x18\x05 \x03(\x0b\x32\x14.google.protobuf.Any\x12\x11\n\tdstSiteNo\x18\x06 \x01(\t\x12\x11\n\tsrcSiteNo\x18\x07 \x01(\t\x12\x0f\n\x07noArray\x18\x08 \x03(\t\x12\x13\n\x0bsiteNoArray\x18\t \x03(\tB\x0cZ\n../protogob\x06proto3')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'mod_return_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'Z\n../protogo'
_RETURNELEMENT._serialized_start=62
_RETURNELEMENT._serialized_end=281
# @@protoc_insertion_point(module_scope)
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: mod-satellite.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import builder as _builder
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x13mod-satellite.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xe4\x03\n\x13RetSatelliteElement\x12\r\n\x05norad\x18\x02 \x01(\t\x12\x0c\n\x04\x63ode\x18\x03 \x01(\t\x12\x0e\n\x06\x63nName\x18\x04 \x01(\t\x12\x0e\n\x06\x65nName\x18\x05 \x01(\t\x12\x11\n\tavailable\x18\x06 \x01(\x08\x12\x10\n\x08priority\x18\x07 \x01(\x05\x12\x16\n\x0epriorityBySite\x18\x08 \x01(\x05\x12,\n\x04\x62\x61se\x18\t \x03(\x0b\x32\x1e.RetSatelliteElement.BaseEntry\x12(\n\x07\x64\x65tails\x18\n \x03(\x0b\x32\x17.RetSiteLevel3Satellite\x12\x34\n\x08\x65lements\x18\x0b \x03(\x0b\x32\".RetSatelliteElement.ElementsEntry\x12,\n\nworkParams\x18\x0c \x01(\x0b\x32\x18.RetSatelliteWorkElement\x12\x0b\n\x03off\x18\r \x01(\x08\x12,\n\x08\x63reateDt\x18\x0e \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x1a+\n\tBaseEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a/\n\rElementsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xbc\x01\n\x16RetSiteLevel3Satellite\x12\x0e\n\x06siteNo\x18\x01 \x01(\t\x12\x10\n\x08priority\x18\x02 \x01(\x05\x12\x11\n\tavailable\x18\x03 \x01(\x08\x12#\n\x0cobserveGrade\x18\x04 \x01(\x0e\x32\r.ObserveGrade\x12+\n\tworkParam\x18\x05 \x01(\x0b\x32\x18.RetSatelliteWorkElement\x12\x1b\n\x13workParamConfigName\x18\x06 \x01(\t\"\xa2\x01\n\rSatelliteList\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12*\n\x04sort\x18\x03 \x01(\x0e\x32\x1c.SatelliteList.satelliteSort\"F\n\rsatelliteSort\x12\x19\n\x15satelliteSort_default\x10\x00\x12\x1a\n\x16satelliteSort_forecast\x10\x01\"?\n\x0fSatelliteDetail\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12\r\n\x05norad\x18\x03 \x01(\t\"D\n\x16SatelliteElementUpdate\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12\x0b\n\x03tle\x18\x03 \x01(\t\"\xc8\x01\n\x13SatelliteBaseUpdate\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12\r\n\x05norad\x18\x03 \x01(\t\x12\x0e\n\x06\x63nName\x18\x04 \x01(\t\x12\x0c\n\x04\x63ode\x18\x05 \x01(\t\x12\x10\n\x08\x63odeName\x18\x06 \x01(\t\x12\x0f\n\x07\x63ountry\x18\x07 \x01(\t\x12\x11\n\torbitType\x18\x08 \x01(\t\x12\x0f\n\x07purpose\x18\t \x01(\t\x12\x0e\n\x06remark\x18\n \x01(\t\x12\x0e\n\x06\x65nName\x18\x0b \x01(\t\"A\n\x0cSatelliteDel\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12\x12\n\nnoradArray\x18\x03 \x03(\t\"6\n\x15SatellitePriorityList\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\"L\n\x17SatellitePriorityUpdate\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12\x12\n\nnoradArray\x18\x03 \x03(\t\"6\n\x14SatelliteElementLoad\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0f\n\x07idArray\x18\x02 \x03(\t\"\x90\x01\n\x1bSatelliteElementLoadAutoSet\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12\x0f\n\x07loadUrl\x18\x03 \x01(\t\x12\x0f\n\x07loadHMS\x18\x04 \x01(\t\x12\x15\n\rloadFrequency\x18\x06 \x01(\x05\x12\x19\n\x11tleStrategyStatus\x18\x08 \x01(\x08\"\xe9\x01\n\x15SatelliteDetailUpdate\x12\r\n\x05token\x18\x01 \x01(\x05\x12\r\n\x05norad\x18\x02 \x01(\t\x12\x0e\n\x06siteNo\x18\x03 \x01(\t\x12\x0e\n\x06\x63nName\x18\x04 \x01(\t\x12\x0c\n\x04\x63ode\x18\x05 \x01(\t\x12\x10\n\x08\x63odeName\x18\x06 \x01(\t\x12\x0f\n\x07\x63ountry\x18\x07 \x01(\t\x12\x11\n\torbitType\x18\x08 \x01(\t\x12\x0f\n\x07purpose\x18\t \x01(\t\x12\x0e\n\x06remark\x18\n \x01(\t\x12\x0e\n\x06\x65nName\x18\x0b \x01(\t\x12\x1d\n\x06params\x18\x0c \x03(\x0b\x32\r.DetailParams\"c\n\x0c\x44\x65tailParams\x12\x0e\n\x06siteNo\x18\x01 \x01(\t\x12\x11\n\tavailable\x18\x02 \x01(\x08\x12\x1c\n\x05grade\x18\x03 \x01(\x0e\x32\r.ObserveGrade\x12\x12\n\nworkConfig\x18\x04 \x01(\x05\"\xc7\x01\n\x17RetSatelliteWorkElement\x12\r\n\x05norad\x18\x01 \x01(\t\x12\x10\n\x08\x63onfigId\x18\x02 \x01(\x05\x12\x0e\n\x06remark\x18\x03 \x01(\t\x12\x12\n\nconfigName\x18\x04 \x01(\t\x12\x10\n\x08\x63\x61tegory\x18\x05 \x01(\t\x12\x1a\n\x06params\x18\x06 \x03(\x0b\x32\n.WorkParam\x12\x0b\n\x03off\x18\x07 \x01(\x08\x12,\n\x08\x63reateDt\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"7\n\x16SatelliteWorkParamList\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\"\x9a\x01\n\x18SatelliteWorkParamUpdate\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12\r\n\x05norad\x18\x03 \x01(\t\x12\x10\n\x08\x63onfigId\x18\x04 \x01(\x05\x12\x12\n\nconfigName\x18\x05 \x01(\t\x12\x0e\n\x06remark\x18\x06 \x01(\t\x12\x1a\n\x06params\x18\x07 \x03(\x0b\x32\n.WorkParam\"\xc5\x02\n\tWorkParam\x12\x0e\n\x06siteNo\x18\x01 \x01(\t\x12\x1c\n\x14XTrackerSigIntensity\x18\x06 \x01(\x05\x12\x1c\n\x14YTrackerSigIntensity\x18\x07 \x01(\x05\x12\x12\n\nXInitPhase\x18\x08 \x01(\x05\x12\x19\n\x11XPolarizationType\x18\t \x01(\x05\x12\x19\n\x11SPolarizationType\x18\n \x01(\x05\x12\x1c\n\x14XTrackerVoltageLimit\x18\x0b \x01(\x05\x12\x1c\n\x14STrackerVoltageLimit\x18\x0c \x01(\x05\x12\x1b\n\x13SUpPolarizationType\x18\r \x01(\x05\x12\x1b\n\x13XUpPolarizationType\x18\x0e \x01(\x05\x12\x16\n\x0eTrackingStatus\x18\x0f \x01(\x05\x12\x14\n\x0cTrackingBand\x18\x10 \x01(\x05\"X\n\x15SatelliteWorkParamDel\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12 \n\x08keyArray\x18\x03 \x03(\x0b\x32\x0e.NoradConfigId\"0\n\rNoradConfigId\x12\r\n\x05norad\x18\x01 \x01(\t\x12\x10\n\x08\x63onfigId\x18\x02 \x01(\x05\"T\n\x1fSatelliteWorkParamListForChoose\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12\x12\n\nnoradArray\x18\x03 \x03(\t*`\n\x0cObserveGrade\x12\x17\n\x13ObserveGradeDefault\x10\x00\x12\x11\n\rObserveGrade1\x10\x01\x12\x11\n\rObserveGrade2\x10\x02\x12\x11\n\rObserveGrade3\x10\x03\x42\x0cZ\n../protogob\x06proto3')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'mod_satellite_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'Z\n../protogo'
_RETSATELLITEELEMENT_BASEENTRY._options = None
_RETSATELLITEELEMENT_BASEENTRY._serialized_options = b'8\001'
_RETSATELLITEELEMENT_ELEMENTSENTRY._options = None
_RETSATELLITEELEMENT_ELEMENTSENTRY._serialized_options = b'8\001'
_OBSERVEGRADE._serialized_start=2948
_OBSERVEGRADE._serialized_end=3044
_RETSATELLITEELEMENT._serialized_start=57
_RETSATELLITEELEMENT._serialized_end=541
_RETSATELLITEELEMENT_BASEENTRY._serialized_start=449
_RETSATELLITEELEMENT_BASEENTRY._serialized_end=492
_RETSATELLITEELEMENT_ELEMENTSENTRY._serialized_start=494
_RETSATELLITEELEMENT_ELEMENTSENTRY._serialized_end=541
_RETSITELEVEL3SATELLITE._serialized_start=544
_RETSITELEVEL3SATELLITE._serialized_end=732
_SATELLITELIST._serialized_start=735
_SATELLITELIST._serialized_end=897
_SATELLITELIST_SATELLITESORT._serialized_start=827
_SATELLITELIST_SATELLITESORT._serialized_end=897
_SATELLITEDETAIL._serialized_start=899
_SATELLITEDETAIL._serialized_end=962
_SATELLITEELEMENTUPDATE._serialized_start=964
_SATELLITEELEMENTUPDATE._serialized_end=1032
_SATELLITEBASEUPDATE._serialized_start=1035
_SATELLITEBASEUPDATE._serialized_end=1235
_SATELLITEDEL._serialized_start=1237
_SATELLITEDEL._serialized_end=1302
_SATELLITEPRIORITYLIST._serialized_start=1304
_SATELLITEPRIORITYLIST._serialized_end=1358
_SATELLITEPRIORITYUPDATE._serialized_start=1360
_SATELLITEPRIORITYUPDATE._serialized_end=1436
_SATELLITEELEMENTLOAD._serialized_start=1438
_SATELLITEELEMENTLOAD._serialized_end=1492
_SATELLITEELEMENTLOADAUTOSET._serialized_start=1495
_SATELLITEELEMENTLOADAUTOSET._serialized_end=1639
_SATELLITEDETAILUPDATE._serialized_start=1642
_SATELLITEDETAILUPDATE._serialized_end=1875
_DETAILPARAMS._serialized_start=1877
_DETAILPARAMS._serialized_end=1976
_RETSATELLITEWORKELEMENT._serialized_start=1979
_RETSATELLITEWORKELEMENT._serialized_end=2178
_SATELLITEWORKPARAMLIST._serialized_start=2180
_SATELLITEWORKPARAMLIST._serialized_end=2235
_SATELLITEWORKPARAMUPDATE._serialized_start=2238
_SATELLITEWORKPARAMUPDATE._serialized_end=2392
_WORKPARAM._serialized_start=2395
_WORKPARAM._serialized_end=2720
_SATELLITEWORKPARAMDEL._serialized_start=2722
_SATELLITEWORKPARAMDEL._serialized_end=2810
_NORADCONFIGID._serialized_start=2812
_NORADCONFIGID._serialized_end=2860
_SATELLITEWORKPARAMLISTFORCHOOSE._serialized_start=2862
_SATELLITEWORKPARAMLISTFORCHOOSE._serialized_end=2946
# @@protoc_insertion_point(module_scope)
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: mod-site.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import builder as _builder
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
import mod_user_pb2 as mod__user__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0emod-site.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x0emod-user.proto\"\xb4\x03\n\x0eRetSiteElement\x12\n\n\x02no\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12&\n\x08operator\x18\x04 \x01(\x0b\x32\x14.RetAdminUserElement\x12\x0e\n\x06remark\x18\x05 \x01(\t\x12\x10\n\x08latitude\x18\x06 \x01(\x01\x12\x11\n\tlongitude\x18\x07 \x01(\x01\x12\x10\n\x08\x61ltitude\x18\x08 \x01(\x01\x12\x0e\n\x06parent\x18\t \x01(\t\x12+\n\x06params\x18\n \x03(\x0b\x32\x1b.RetSiteElement.ParamsEntry\x12+\n\x06\x65xtend\x18\x0b \x03(\x0b\x32\x1b.RetSiteElement.ExtendEntry\x12\x16\n\x0e\x61vailableArray\x18\x0c \x03(\t\x12\x0b\n\x03off\x18\r \x01(\x08\x12,\n\x08\x63reateDt\x18\x0e \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x1a-\n\x0bParamsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a-\n\x0b\x45xtendEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"<\n\x08SiteList\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12\x11\n\tavailable\x18\x03 \x01(\x08\"\x84\x02\n\nSiteUpdate\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x0e\n\x06remark\x18\x04 \x01(\t\x12\x10\n\x08latitude\x18\x05 \x01(\x01\x12\x11\n\tlongitude\x18\x06 \x01(\x01\x12\x10\n\x08\x61ltitude\x18\x07 \x01(\x01\x12\x0f\n\x07\x63ountry\x18\x08 \x01(\t\x12\r\n\x05place\x18\t \x01(\t\x12\x10\n\x08timeZone\x18\n \x01(\t\x12\x0f\n\x07voltage\x18\x0b \x01(\x01\x12\x12\n\ndeltaDelay\x18\x0c \x01(\x05\x12\x11\n\tbandwidth\x18\r \x01(\x01\x12\x18\n\x10networkOperators\x18\x0e \x01(\t\"\xc7\x01\n\x0fSiteParamUpdate\x12\r\n\x05token\x18\x01 \x01(\x05\x12\n\n\x02id\x18\x02 \x01(\x05\x12\r\n\x05slice\x18\x03 \x01(\x01\x12\x13\n\x0bminEleAngle\x18\x04 \x01(\x01\x12\x13\n\x0bmaxEleAngle\x18\x05 \x01(\x01\x12\x13\n\x0bminAziAngle\x18\x06 \x01(\x01\x12\x13\n\x0bmaxAziAngle\x18\x07 \x01(\x01\x12\x0f\n\x07minDist\x18\x08 \x01(\x01\x12\x0f\n\x07maxDist\x18\t \x01(\x01\x12\x14\n\x0ctaskDuration\x18\n \x01(\x01\x42\x0cZ\n../protogob\x06proto3')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'mod_site_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'Z\n../protogo'
_RETSITEELEMENT_PARAMSENTRY._options = None
_RETSITEELEMENT_PARAMSENTRY._serialized_options = b'8\001'
_RETSITEELEMENT_EXTENDENTRY._options = None
_RETSITEELEMENT_EXTENDENTRY._serialized_options = b'8\001'
_RETSITEELEMENT._serialized_start=68
_RETSITEELEMENT._serialized_end=504
_RETSITEELEMENT_PARAMSENTRY._serialized_start=412
_RETSITEELEMENT_PARAMSENTRY._serialized_end=457
_RETSITEELEMENT_EXTENDENTRY._serialized_start=459
_RETSITEELEMENT_EXTENDENTRY._serialized_end=504
_SITELIST._serialized_start=506
_SITELIST._serialized_end=566
_SITEUPDATE._serialized_start=569
_SITEUPDATE._serialized_end=829
_SITEPARAMUPDATE._serialized_start=832
_SITEPARAMUPDATE._serialized_end=1031
# @@protoc_insertion_point(module_scope)
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: mod-system.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import builder as _builder
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10mod-system.proto\"\xc6\x01\n\x15RetMoreSettingElement\x12\x0f\n\x07\x64\x65\x66\x61ult\x18\x01 \x01(\t\x12\x1c\n\x07setting\x18\x02 \x01(\x0b\x32\x0b.DataParams\x12\x1d\n\x08\x64\x61taSave\x18\x03 \x03(\x0b\x32\x0b.DataParams\x12\x1c\n\x07tleLoad\x18\x04 \x01(\x0b\x32\x0b.DataParams\x12\"\n\rforecastParam\x18\x05 \x03(\x0b\x32\x0b.DataParams\x12\x1d\n\x08taskAuto\x18\x06 \x03(\x0b\x32\x0b.DataParams\"d\n\nDataParams\x12\'\n\x06params\x18\x01 \x03(\x0b\x32\x17.DataParams.ParamsEntry\x1a-\n\x0bParamsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x1f\n\x0eMoreSettingSet\x12\r\n\x05token\x18\x01 \x01(\x05\"\xa1\x01\n\x12MoreSettingDataSet\x12\r\n\x05token\x18\x01 \x01(\x05\x12\n\n\x02no\x18\x02 \x01(\t\x12\x10\n\x08\x64\x61taType\x18\x03 \x01(\t\x12\x0e\n\x06hostIP\x18\x04 \x01(\t\x12\x10\n\x08hostPort\x18\x05 \x01(\x05\x12\x0e\n\x06userID\x18\x06 \x01(\t\x12\x0b\n\x03pwd\x18\x07 \x01(\t\x12\x11\n\tdirectory\x18\x08 \x01(\t\x12\x0c\n\x04size\x18\t \x01(\x05\"/\n\x12MoreSettingDataDel\x12\r\n\x05token\x18\x01 \x01(\x05\x12\n\n\x02no\x18\x02 \x01(\t\"H\n\x0eMoreSettingGet\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12\x17\n\x07labelId\x18\x03 \x01(\x0e\x32\x06.Label\"O\n\x15MoreSettingGetDefault\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12\x17\n\x07labelId\x18\x03 \x01(\x0e\x32\x06.Label\"S\n\x19MoreSettingRestoreDefault\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12\x17\n\x07labelId\x18\x03 \x01(\x0e\x32\x06.Label*\x86\x01\n\x05Label\x12\x11\n\rLabel_Default\x10\x00\x12\x16\n\x12Label_TaskForecast\x10\x01\x12\x12\n\x0eLabel_DataSave\x10\x02\x12\x11\n\rLabel_TleLoad\x10\x03\x12\x17\n\x13Label_ForecastParam\x10\x04\x12\x12\n\x0eLabel_TaskAuto\x10\x05\x42\x0cZ\n../protogob\x06proto3')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'mod_system_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'Z\n../protogo'
_DATAPARAMS_PARAMSENTRY._options = None
_DATAPARAMS_PARAMSENTRY._serialized_options = b'8\001'
_LABEL._serialized_start=810
_LABEL._serialized_end=944
_RETMORESETTINGELEMENT._serialized_start=21
_RETMORESETTINGELEMENT._serialized_end=219
_DATAPARAMS._serialized_start=221
_DATAPARAMS._serialized_end=321
_DATAPARAMS_PARAMSENTRY._serialized_start=276
_DATAPARAMS_PARAMSENTRY._serialized_end=321
_MORESETTINGSET._serialized_start=323
_MORESETTINGSET._serialized_end=354
_MORESETTINGDATASET._serialized_start=357
_MORESETTINGDATASET._serialized_end=518
_MORESETTINGDATADEL._serialized_start=520
_MORESETTINGDATADEL._serialized_end=567
_MORESETTINGGET._serialized_start=569
_MORESETTINGGET._serialized_end=641
_MORESETTINGGETDEFAULT._serialized_start=643
_MORESETTINGGETDEFAULT._serialized_end=722
_MORESETTINGRESTOREDEFAULT._serialized_start=724
_MORESETTINGRESTOREDEFAULT._serialized_end=807
# @@protoc_insertion_point(module_scope)
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: mod-task-exec.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import builder as _builder
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
import mod_task_pb2 as mod__task__pb2
from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x13mod-task-exec.proto\x1a\x0emod-task.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xa5\x02\n\x12RetTaskExecElement\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1d\n\x04task\x18\x02 \x01(\x0b\x32\x0f.RetTaskElement\x12+\n\x07startDt\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12)\n\x05\x65ndDt\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12/\n\x06\x65xtend\x18\x05 \x03(\x0b\x32\x1f.RetTaskExecElement.ExtendEntry\x12,\n\x08\x63reateDt\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x1a-\n\x0b\x45xtendEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x97\x01\n\x0cTaskExecList\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x12\n\ncodeSearch\x18\x02 \x01(\t\x12\x10\n\x08noSearch\x18\x03 \x01(\t\x12)\n\x05start\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\'\n\x03\x65nd\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xa1\x01\n\x16TaskExecAnalysisResult\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x12\n\ncodeSearch\x18\x03 \x01(\t\x12\x10\n\x08noSearch\x18\x04 \x01(\t\x12)\n\x05start\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\'\n\x03\x65nd\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x0cZ\n../protogob\x06proto3')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'mod_task_exec_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'Z\n../protogo'
_RETTASKEXECELEMENT_EXTENDENTRY._options = None
_RETTASKEXECELEMENT_EXTENDENTRY._serialized_options = b'8\001'
_RETTASKEXECELEMENT._serialized_start=73
_RETTASKEXECELEMENT._serialized_end=366
_RETTASKEXECELEMENT_EXTENDENTRY._serialized_start=321
_RETTASKEXECELEMENT_EXTENDENTRY._serialized_end=366
_TASKEXECLIST._serialized_start=369
_TASKEXECLIST._serialized_end=520
_TASKEXECANALYSISRESULT._serialized_start=523
_TASKEXECANALYSISRESULT._serialized_end=684
# @@protoc_insertion_point(module_scope)
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: mod-task.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import builder as _builder
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
import mod_satellite_pb2 as mod__satellite__pb2
import mod_site_pb2 as mod__site__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0emod-task.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x13mod-satellite.proto\x1a\x0emod-site.proto\"\xdb\x05\n\x0eRetTaskElement\x12\n\n\x02id\x18\x01 \x01(\t\x12\n\n\x02no\x18\x02 \x01(\t\x12\r\n\x05norad\x18\x03 \x01(\t\x12\'\n\tsatellite\x18\x04 \x01(\x0b\x32\x14.RetSatelliteElement\x12\x0e\n\x06siteNo\x18\x05 \x01(\t\x12\x1d\n\x04site\x18\x06 \x01(\x0b\x32\x0f.RetSiteElement\x12\x0c\n\x04type\x18\x07 \x01(\t\x12\x19\n\x05grade\x18\x08 \x01(\x0e\x32\n.TaskGrade\x12\x1b\n\x06status\x18\t \x01(\x0e\x32\x0b.TaskStatus\x12)\n\x05genDt\x18\n \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12+\n\x07startDt\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12)\n\x05\x65ndDt\x18\x0c \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x15\n\rstartAziAngle\x18\r \x01(\x01\x12\x13\n\x0b\x65ndAziAngle\x18\x0e \x01(\x01\x12\x15\n\rstartEleAngle\x18\x0f \x01(\x01\x12\x13\n\x0bmaxEleAngle\x18\x10 \x01(\x01\x12\x0e\n\x06\x63ircle\x18\x11 \x01(\x05\x12\x0f\n\x07minDist\x18\x12 \x01(\x01\x12\x0f\n\x07maxDist\x18\x13 \x01(\x01\x12\r\n\x05slice\x18\x14 \x01(\x05\x12+\n\x06\x65xtend\x18\x15 \x03(\x0b\x32\x1b.RetTaskElement.ExtendEntry\x12%\n\x03res\x18\x16 \x03(\x0b\x32\x18.RetTaskElement.ResEntry\x12\x0b\n\x03off\x18\x17 \x01(\x08\x12,\n\x08\x63reateDt\x18\x18 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x1a-\n\x0b\x45xtendEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a*\n\x08ResEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xe0\x01\n\x08TaskList\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12 \n\x0bstatusArray\x18\x03 \x03(\x0e\x32\x0b.TaskStatus\x12\x12\n\ncodeSearch\x18\x04 \x01(\t\x12\x10\n\x08noSearch\x18\x05 \x01(\t\x12\x19\n\x05grade\x18\x06 \x01(\x0e\x32\n.TaskGrade\x12)\n\x05start\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\'\n\x03\x65nd\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xda\x01\n\x0cTaskForecast\x12\r\n\x05token\x18\x01 \x01(\x05\x12(\n\x0c\x66orecastList\x18\x02 \x03(\x0b\x32\x12.SiteSatelliteList\x12\r\n\x05slice\x18\x03 \x01(\x01\x12\x13\n\x0bminEleAngle\x18\x04 \x01(\x01\x12)\n\x05start\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\'\n\x03\x65nd\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x19\n\x05grade\x18\x07 \x01(\x0e\x32\n.TaskGrade\"E\n\x11SiteSatelliteList\x12\x0e\n\x06siteNo\x18\x01 \x01(\t\x12\x0c\n\x04tles\x18\x02 \x01(\t\x12\x12\n\nnoradArray\x18\x03 \x03(\t\"#\n\x12RetForecastOneOver\x12\r\n\x05norad\x18\x01 \x01(\t\"L\n\x08TaskPlan\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12!\n\x08taskList\x18\x03 \x03(\x0b\x32\x0f.RetTaskElement\"\x9e\x01\n\x12TaskHandleConflict\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12\x1f\n\x08\x63onflict\x18\x03 \x01(\x0e\x32\r.ConflictType\x12\x11\n\tleastTime\x18\x04 \x01(\x03\x12\x12\n\nswitchTime\x18\x05 \x01(\x03\x12!\n\x08taskList\x18\x06 \x03(\x0b\x32\x0f.RetTaskElement\"b\n\nTaskIssued\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12\x12\n\nswitchTime\x18\x03 \x01(\x05\x12!\n\x08taskList\x18\x04 \x03(\x0b\x32\x0f.RetTaskElement\";\n\tTaskPause\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12\x0f\n\x07idArray\x18\x03 \x03(\t\">\n\x0cTaskRecovery\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12\x0f\n\x07idArray\x18\x03 \x03(\t\"9\n\x07TaskDel\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12\x0f\n\x07idArray\x18\x03 \x03(\t\":\n\x0bTaskConfirm\x12\x1b\n\x07operate\x18\x01 \x01(\x0e\x32\n.Operation\x12\x0e\n\x06taskId\x18\x02 \x01(\t\"=\n\x0eRetTaskConfirm\x12\x1b\n\x07operate\x18\x01 \x01(\x0e\x32\n.Operation\x12\x0e\n\x06taskId\x18\x02 \x01(\t\"\x85\x01\n\x0cRetTaskIndex\x12%\n\x04\x64\x61ta\x18\x01 \x03(\x0b\x32\x17.RetTaskIndex.DataEntry\x12!\n\x08taskList\x18\x02 \x03(\x0b\x32\x0f.RetTaskElement\x1a+\n\tDataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xf5\x01\n\x14TaskForecastParamSet\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12\r\n\x05slice\x18\x03 \x01(\x01\x12\x0f\n\x07maxDist\x18\x04 \x01(\x01\x12\x0f\n\x07minDist\x18\x05 \x01(\x01\x12\x13\n\x0bmaxAziAngle\x18\x06 \x01(\x01\x12\x13\n\x0bminAziAngle\x18\x07 \x01(\x01\x12\x13\n\x0bmaxEleAngle\x18\x08 \x01(\x01\x12\x13\n\x0bminEleAngle\x18\t \x01(\x01\x12\x11\n\tpointStep\x18\n \x01(\x05\x12\x15\n\rpointDuration\x18\x0b \x01(\x05\x12\x0f\n\x07\x64\x61tPath\x18\x0c \x01(\t\"\x8d\x02\n\x0bTaskAutoSet\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0e\n\x06siteNo\x18\x02 \x01(\t\x12\x14\n\x0c\x61utoStartHMS\x18\x03 \x01(\t\x12\x12\n\nautoEndHMS\x18\x04 \x01(\t\x12\x15\n\rautoFrequency\x18\x05 \x01(\x05\x12\x1e\n\x16taskAutoStrategyStatus\x18\x06 \x01(\x08\x12\x1f\n\x08\x63onflict\x18\x07 \x01(\x0e\x32\r.ConflictType\x12\x1e\n\x16\x63onflictStrategyStatus\x18\x08 \x01(\x08\x12\x11\n\tleastTime\x18\t \x01(\x03\x12\x12\n\nswitchTime\x18\n \x01(\x03\x12\x16\n\x0e\x63ollectionTime\x18\x0b \x01(\x03\"*\n\rTaskDetailDat\x12\r\n\x05token\x18\x01 \x01(\x05\x12\n\n\x02id\x18\x02 \x01(\t\"]\n\nRetTaskDat\x12&\n\x02\x64t\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\r\n\x05range\x18\x02 \x01(\x01\x12\x0b\n\x03\x65le\x18\x03 \x01(\x01\x12\x0b\n\x03\x61zi\x18\x04 \x01(\x01\",\n\x0fTaskDetailPoint\x12\r\n\x05token\x18\x01 \x01(\x05\x12\n\n\x02id\x18\x02 \x01(\t\"`\n\x0cRetTaskPoint\x12&\n\x02\x64t\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0b\n\x03lat\x18\x05 \x01(\t\x12\x0b\n\x03lon\x18\x06 \x01(\t\x12\x0e\n\x06height\x18\x07 \x01(\t*\x83\x01\n\nTaskStatus\x12\x0e\n\nStatusInit\x10\x00\x12\x0e\n\nStatusUndo\x10\x01\x12\x11\n\rStatusWaiting\x10\x02\x12\x0f\n\x0bStatusDoing\x10\x03\x12\x0e\n\nStatusDone\x10\x04\x12\x0f\n\x0bStatusPause\x10\x05\x12\x10\n\x0cStatusFailed\x10\n*P\n\tTaskGrade\x12\r\n\tGradeNone\x10\x00\x12\x0f\n\x0bGradeNormal\x10\x01\x12\x12\n\x0eGradeImportant\x10\x02\x12\x0f\n\x0bGradeUrgent\x10\x03*n\n\x0c\x43onflictType\x12\x18\n\x14\x43onflictType_Default\x10\x00\x12\x13\n\x0f\x43onflictType_Dt\x10\x01\x12\x14\n\x10\x43onflictType_Ele\x10\x02\x12\x19\n\x15\x43onflictType_Priority\x10\x03*s\n\tOperation\x12\x14\n\x10OperationDefault\x10\x00\x12\x13\n\x0fOperationIssued\x10\x01\x12\x12\n\x0eOperationPause\x10\x02\x12\x15\n\x11OperationRecovery\x10\x03\x12\x10\n\x0cOperationDel\x10\x04\x42\x0cZ\n../protogob\x06proto3')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'mod_task_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'Z\n../protogo'
_RETTASKELEMENT_EXTENDENTRY._options = None
_RETTASKELEMENT_EXTENDENTRY._serialized_options = b'8\001'
_RETTASKELEMENT_RESENTRY._options = None
_RETTASKELEMENT_RESENTRY._serialized_options = b'8\001'
_RETTASKINDEX_DATAENTRY._options = None
_RETTASKINDEX_DATAENTRY._serialized_options = b'8\001'
_TASKSTATUS._serialized_start=2964
_TASKSTATUS._serialized_end=3095
_TASKGRADE._serialized_start=3097
_TASKGRADE._serialized_end=3177
_CONFLICTTYPE._serialized_start=3179
_CONFLICTTYPE._serialized_end=3289
_OPERATION._serialized_start=3291
_OPERATION._serialized_end=3406
_RETTASKELEMENT._serialized_start=89
_RETTASKELEMENT._serialized_end=820
_RETTASKELEMENT_EXTENDENTRY._serialized_start=731
_RETTASKELEMENT_EXTENDENTRY._serialized_end=776
_RETTASKELEMENT_RESENTRY._serialized_start=778
_RETTASKELEMENT_RESENTRY._serialized_end=820
_TASKLIST._serialized_start=823
_TASKLIST._serialized_end=1047
_TASKFORECAST._serialized_start=1050
_TASKFORECAST._serialized_end=1268
_SITESATELLITELIST._serialized_start=1270
_SITESATELLITELIST._serialized_end=1339
_RETFORECASTONEOVER._serialized_start=1341
_RETFORECASTONEOVER._serialized_end=1376
_TASKPLAN._serialized_start=1378
_TASKPLAN._serialized_end=1454
_TASKHANDLECONFLICT._serialized_start=1457
_TASKHANDLECONFLICT._serialized_end=1615
_TASKISSUED._serialized_start=1617
_TASKISSUED._serialized_end=1715
_TASKPAUSE._serialized_start=1717
_TASKPAUSE._serialized_end=1776
_TASKRECOVERY._serialized_start=1778
_TASKRECOVERY._serialized_end=1840
_TASKDEL._serialized_start=1842
_TASKDEL._serialized_end=1899
_TASKCONFIRM._serialized_start=1901
_TASKCONFIRM._serialized_end=1959
_RETTASKCONFIRM._serialized_start=1961
_RETTASKCONFIRM._serialized_end=2022
_RETTASKINDEX._serialized_start=2025
_RETTASKINDEX._serialized_end=2158
_RETTASKINDEX_DATAENTRY._serialized_start=2115
_RETTASKINDEX_DATAENTRY._serialized_end=2158
_TASKFORECASTPARAMSET._serialized_start=2161
_TASKFORECASTPARAMSET._serialized_end=2406
_TASKAUTOSET._serialized_start=2409
_TASKAUTOSET._serialized_end=2678
_TASKDETAILDAT._serialized_start=2680
_TASKDETAILDAT._serialized_end=2722
_RETTASKDAT._serialized_start=2724
_RETTASKDAT._serialized_end=2817
_TASKDETAILPOINT._serialized_start=2819
_TASKDETAILPOINT._serialized_end=2863
_RETTASKPOINT._serialized_start=2865
_RETTASKPOINT._serialized_end=2961
# @@protoc_insertion_point(module_scope)
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: mod-user.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import builder as _builder
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0emod-user.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xf1\x01\n\x13RetAdminUserElement\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x13\n\x04role\x18\x02 \x01(\x0e\x32\x05.Role\x12\x10\n\x08username\x18\x03 \x01(\t\x12\x0b\n\x03pwd\x18\x04 \x01(\t\x12\x0b\n\x03off\x18\x05 \x01(\x05\x12\x30\n\x06\x65xtend\x18\x06 \x03(\x0b\x32 .RetAdminUserElement.ExtendEntry\x12,\n\x08\x63reateDt\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x1a-\n\x0b\x45xtendEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\".\n\x08UserList\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x13\n\x04role\x18\x02 \x01(\x0e\x32\x05.Role\"P\n\nUserCreate\x12\x10\n\x08username\x18\x01 \x01(\t\x12\x0b\n\x03pwd\x18\x02 \x01(\t\x12\x13\n\x04role\x18\x03 \x01(\x0e\x32\x05.Role\x12\x0e\n\x06remark\x18\x04 \x01(\t\"r\n\nUserUpdate\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x10\n\x08username\x18\x02 \x01(\t\x12\x0e\n\x06oldPwd\x18\x03 \x01(\t\x12\x0e\n\x06newPwd\x18\x04 \x01(\t\x12\x13\n\x04role\x18\x05 \x01(\x0e\x32\x05.Role\x12\x0e\n\x06remark\x18\x06 \x01(\t\")\n\x07UserDel\x12\r\n\x05token\x18\x01 \x01(\x05\x12\x0f\n\x07idArray\x18\x02 \x03(\x05\"&\n\x05Login\x12\x10\n\x08username\x18\x01 \x01(\t\x12\x0b\n\x03pwd\x18\x02 \x01(\t*6\n\x04Role\x12\r\n\tUser_None\x10\x00\x12\x0e\n\nUser_Admin\x10\x01\x12\x0f\n\x0bUser_Normal\x10\x02\x42\x0cZ\n../protogob\x06proto3')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'mod_user_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'Z\n../protogo'
_RETADMINUSERELEMENT_EXTENDENTRY._options = None
_RETADMINUSERELEMENT_EXTENDENTRY._serialized_options = b'8\001'
_ROLE._serialized_start=624
_ROLE._serialized_end=678
_RETADMINUSERELEMENT._serialized_start=52
_RETADMINUSERELEMENT._serialized_end=293
_RETADMINUSERELEMENT_EXTENDENTRY._serialized_start=248
_RETADMINUSERELEMENT_EXTENDENTRY._serialized_end=293
_USERLIST._serialized_start=295
_USERLIST._serialized_end=341
_USERCREATE._serialized_start=343
_USERCREATE._serialized_end=423
_USERUPDATE._serialized_start=425
_USERUPDATE._serialized_end=539
_USERDEL._serialized_start=541
_USERDEL._serialized_end=582
_LOGIN._serialized_start=584
_LOGIN._serialized_end=622
# @@protoc_insertion_point(module_scope)
import paho.mqtt.client as mqtt
from django.conf import settings
from .utils import parse_proto
from .signals import mqtt_message_received
from chat.consumers import send_websocket_message
from django.core.cache import cache
from device_data_op.models import TableXproAllDevinfo
# *******************************************************
from channels.layers import get_channel_layer, channel_layers
from asgiref.sync import async_to_sync
def send_websocket_message(message, group_name="chat_mqtt"):
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(
group_name,
{"type": "chat.message", "message": message}
)
# *******************************************************
def on_connect(mqtt_client, userdata, flags, rc):
if rc == 0:
print('Connected successfully')
mqtt_client.subscribe('django/mqtt')
mqtt_client.subscribe([('/1/0/0/6', 2),
('/1/1/0/6', 2),
('/1/1/1/6', 2)])
else:
print('Bad connection. Code:', rc)
......@@ -29,9 +20,34 @@ def on_message(mqtt_client, userdata, msg):
# 接收mqtt消息的代码
# mqtt_message_received.send(sender=None, message=msg.payload)
# print(f'Received message on topic: {msg.topic} with payload: {msg.payload}')
# data = parse_proto(msg.payload)
data = msg.payload.decode('utf-8')
data, device_name = parse_proto(msg.payload)
# data = msg.payload.decode('utf-8')
print(f'Received message on topic: {msg.topic} with payload: {data}')
send_message(data, device_name)
def send_message(data: dict, device_name: str):
"""
发送 websocket 消息
TODO: 通过不同的 port 发向不同的 group name
"""
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")
client = mqtt.Client()
......@@ -44,4 +60,4 @@ client.connect(
keepalive=settings.MQTT_KEEPALIVE
)
print('start mqtt')
client.loop_start()
\ No newline at end of file
client.loop_start()
import django.dispatch
mqtt_message_received = django.dispatch.Signal(providing_args=['message'])
from django.contrib import admin
from django.urls import path, include
from django.urls import path, re_path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('publish/', views.publish_message, name='publish'),
]
\ No newline at end of file
re_path(r'publish/$', views.publish_message, name='publish'),
re_path(r'^protocol/(?P<protocol_name>.+)/$', views.cmd_list),
re_path(r'^cmd/(?P<cmd_name>.+)/$', views.cmd_fields_list),
]
import json
from .auto_generate_python import TDSCmd_pb2, OAM_datastruct_pb2
from .auto_generate_python import TDSCmd_pb2, OAM_datastruct_pb2, Device_datastruct_pb2
from .auto_generate_python.Device_datastruct_pb2 import TDSXDC_Device_cmd
from google.protobuf.json_format import MessageToJson
def parse_proto(data: bytes) -> str:
def parse_proto(data: bytes) -> (dict, str):
"""
解析发送过来的 protobuf
:param data: protobuf 的二进制流
:return:
dict: 解析完成的 protobuf
str: 设备名
"""
cmd = TDSCmd_pb2.TDSCmd()
cmd.ParseFromString(data)
data = MessageToJson(cmd,
including_default_value_fields=True,
preserving_proto_field_name=True)
return json.dumps(json.loads(data), separators=(',', ':'))
device_cmd = TDSXDC_Device_cmd()
cmd.parameters[0].Unpack(device_cmd)
# data = MessageToJson(device_cmd,
# including_default_value_fields=True,
# preserving_proto_field_name=True)
# device_cmd_dict = json.loads(data)
# print(device_cmd_dict)
data = {item.fieldName: item.value
for item in device_cmd.fields}
# return json.dumps(json.loads(data), separators=(',', ':'))
return data, device_cmd.dev_name
def compose_protobuf_message(param: dict, dst_suid: int) -> bytes:
cmd = TDSCmd_pb2.TDSCmd()
cmd.interface_id = TDSCmd_pb2.IID_Device_Xpro_TX_cmd
cmd.dst_suid = dst_suid
cmd.src_suid = 0x1116_0000
cmd.priority = 100
cmd.ts.GetCurrentTime()
parameters = TDSXDC_Device_cmd()
parameters.DeviceID = param['device_id']
parameters.cmd_name = param['cmd_name']
for param_field in param['fields']:
field = parameters.fields.add()
field.fieldName = param_field['fieldname']
field.value = param_field['value']
cmd.parameters.add().Pack(parameters)
data = cmd.SerializeToString()
return data
from django.http import JsonResponse, HttpResponse
from django.middleware.csrf import get_token
from django.shortcuts import render, redirect
from django.dispatch import receiver
from rest_framework import status
from rest_framework.response import Response
from rest_framework.decorators import api_view
from .utils import compose_protobuf_message
from device_data_op.models import (TableDevCmdNamePoll,
TableAllDevCmdDefine,
TableXproAllDevinfo)
from device_data_op.serializers import (TableDevCmdNamePollSerializer,
TableAllDevCmdDefineSerializer)
from mqtt.mqtt import client as mqtt_client
from mqtt.signals import mqtt_message_received
MESSAGE = b""
@api_view(['GET'])
def cmd_list(request, protocol_name: str):
"""
返回传入协议的所有发出指令名
"""
cmd_lists = TableDevCmdNamePoll.objects.filter(protocol_name=protocol_name).all()
serializer = TableDevCmdNamePollSerializer(cmd_lists, many=True)
ret_data = [data['cmd_name'] for data in serializer.data
if data['cmd_type'] == 'TX']
return Response(data=ret_data, status=status.HTTP_200_OK)
@api_view(['GET'])
def cmd_fields_list(request, cmd_name: str):
"""
返回传入指令所需要的字段
"""
cmd_fields = TableAllDevCmdDefine.objects.filter(cmd_name=cmd_name).all()
serializer = TableAllDevCmdDefineSerializer(cmd_fields, many=True)
ret_data = [data['fieldname'] for data in serializer.data]
return Response(data=ret_data, status=status.HTTP_200_OK)
@api_view(['POST'])
def publish_message(request):
# request_data = json.loads(request.body)
topic = request.POST['topic']
msg = request.POST['msg']
rc, mid = mqtt_client.publish(topic, msg)
return JsonResponse({'code': rc})
"""
发送指令到 device
:param request:
{
"type": "device",
"station_id": "XX1",
"device_id": 1,
"cmd_name": "HY_ACU7M5_PositionSet",
"fields": [
{
"fieldname": "Xaxis",
"value": "120"
},
{
"fieldname": "Yaxis",
"value": "60"
}
]
}
"""
def index(request):
global MESSAGE
token = get_token(request)
return render(request, 'index.html', {'token': token, 'msg': MESSAGE.decode('utf-8')})
if request.data['station_id'] == "XX1":
topic = "/1/1/1/3"
dst_suid = 0x1113_0000
elif request.data['station_id'] == "XX0":
topic = "/1/1/0/3"
dst_suid = 0x1103_0000
else:
return Response(status=status.HTTP_400_BAD_REQUEST)
message = compose_protobuf_message(request.data, dst_suid)
@receiver(mqtt_message_received)
def show_message(sender, **kwargs):
global MESSAGE
print('Received message:', kwargs['message'])
MESSAGE = kwargs['message']
rc, mid = mqtt_client.publish(topic, message)
return Response(status=status.HTTP_200_OK)
# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand.
[[package]]
name = "asgiref"
version = "3.7.2"
description = "ASGI specs, helper code, and adapters"
optional = false
python-versions = ">=3.7"
files = [
{file = "asgiref-3.7.2-py3-none-any.whl", hash = "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e"},
{file = "asgiref-3.7.2.tar.gz", hash = "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed"},
]
[package.dependencies]
typing-extensions = {version = ">=4", markers = "python_version < \"3.11\""}
[package.extras]
tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"]
[[package]]
name = "attrs"
version = "23.1.0"
description = "Classes Without Boilerplate"
optional = false
python-versions = ">=3.7"
files = [
{file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"},
{file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"},
]
[package.extras]
cov = ["attrs[tests]", "coverage[toml] (>=5.3)"]
dev = ["attrs[docs,tests]", "pre-commit"]
docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"]
tests = ["attrs[tests-no-zope]", "zope-interface"]
tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
[[package]]
name = "autobahn"
version = "23.6.2"
description = "WebSocket client & server library, WAMP real-time framework"
optional = false
python-versions = ">=3.9"
files = [
{file = "autobahn-23.6.2.tar.gz", hash = "sha256:ec9421c52a2103364d1ef0468036e6019ee84f71721e86b36fe19ad6966c1181"},
]
[package.dependencies]
cryptography = ">=3.4.6"
hyperlink = ">=21.0.0"
setuptools = "*"
txaio = ">=21.2.1"
[package.extras]
all = ["PyGObject (>=3.40.0)", "argon2_cffi (>=20.1.0)", "attrs (>=20.3.0)", "base58 (>=2.1.0)", "bitarray (>=2.7.5)", "cbor2 (>=5.2.0)", "cffi (>=1.14.5)", "click (>=8.1.2)", "ecdsa (>=0.16.1)", "eth-abi (>=4.0.0)", "flatbuffers (>=22.12.6)", "hkdf (>=0.0.3)", "jinja2 (>=2.11.3)", "mnemonic (>=0.19)", "msgpack (>=1.0.2)", "passlib (>=1.7.4)", "py-ecc (>=5.1.0)", "py-eth-sig-utils (>=0.4.0)", "py-multihash (>=2.0.1)", "py-ubjson (>=0.16.1)", "pynacl (>=1.4.0)", "pyopenssl (>=20.0.1)", "python-snappy (>=0.6.0)", "pytrie (>=0.4.0)", "qrcode (>=7.3.1)", "rlp (>=2.0.1)", "service_identity (>=18.1.0)", "spake2 (>=0.8)", "twisted (>=20.3.0)", "ujson (>=4.0.2)", "web3[ipfs] (>=6.0.0)", "xbr (>=21.2.1)", "yapf (==0.29.0)", "zlmdb (>=21.2.1)", "zope.interface (>=5.2.0)"]
compress = ["python-snappy (>=0.6.0)"]
dev = ["backports.tempfile (>=1.0)", "bumpversion (>=0.5.3)", "codecov (>=2.0.15)", "flake8 (<5)", "humanize (>=0.5.1)", "mypy (>=0.610)", "passlib", "pep8-naming (>=0.3.3)", "pip (>=9.0.1)", "pyenchant (>=1.6.6)", "pyflakes (>=1.0.0)", "pyinstaller (>=4.2)", "pylint (>=1.9.2)", "pytest (>=3.4.2)", "pytest-aiohttp", "pytest-asyncio (>=0.14.0)", "pytest-runner (>=2.11.1)", "pyyaml (>=4.2b4)", "qualname", "sphinx (>=1.7.1)", "sphinx-autoapi (>=1.7.0)", "sphinx_rtd_theme (>=0.1.9)", "sphinxcontrib-images (>=0.9.1)", "tox (>=4.2.8)", "tox-gh-actions (>=2.2.0)", "twine (>=3.3.0)", "twisted (>=22.10.0)", "txaio (>=20.4.1)", "watchdog (>=0.8.3)", "wheel (>=0.36.2)", "yapf (==0.29.0)"]
encryption = ["pynacl (>=1.4.0)", "pyopenssl (>=20.0.1)", "pytrie (>=0.4.0)", "qrcode (>=7.3.1)", "service_identity (>=18.1.0)"]
nvx = ["cffi (>=1.14.5)"]
scram = ["argon2_cffi (>=20.1.0)", "cffi (>=1.14.5)", "passlib (>=1.7.4)"]
serialization = ["cbor2 (>=5.2.0)", "flatbuffers (>=22.12.6)", "msgpack (>=1.0.2)", "py-ubjson (>=0.16.1)", "ujson (>=4.0.2)"]
twisted = ["attrs (>=20.3.0)", "twisted (>=20.3.0)", "zope.interface (>=5.2.0)"]
ui = ["PyGObject (>=3.40.0)"]
xbr = ["base58 (>=2.1.0)", "bitarray (>=2.7.5)", "cbor2 (>=5.2.0)", "click (>=8.1.2)", "ecdsa (>=0.16.1)", "eth-abi (>=4.0.0)", "hkdf (>=0.0.3)", "jinja2 (>=2.11.3)", "mnemonic (>=0.19)", "py-ecc (>=5.1.0)", "py-eth-sig-utils (>=0.4.0)", "py-multihash (>=2.0.1)", "rlp (>=2.0.1)", "spake2 (>=0.8)", "twisted (>=20.3.0)", "web3[ipfs] (>=6.0.0)", "xbr (>=21.2.1)", "yapf (==0.29.0)", "zlmdb (>=21.2.1)"]
[[package]]
name = "automat"
version = "22.10.0"
description = "Self-service finite-state machines for the programmer on the go."
optional = false
python-versions = "*"
files = [
{file = "Automat-22.10.0-py2.py3-none-any.whl", hash = "sha256:c3164f8742b9dc440f3682482d32aaff7bb53f71740dd018533f9de286b64180"},
{file = "Automat-22.10.0.tar.gz", hash = "sha256:e56beb84edad19dcc11d30e8d9b895f75deeb5ef5e96b84a467066b3b84bb04e"},
]
[package.dependencies]
attrs = ">=19.2.0"
six = "*"
[package.extras]
visualize = ["Twisted (>=16.1.1)", "graphviz (>0.5.1)"]
[[package]]
name = "cffi"
version = "1.15.1"
description = "Foreign Function Interface for Python calling C code."
optional = false
python-versions = "*"
files = [
{file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"},
{file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"},
{file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"},
{file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"},
{file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"},
{file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"},
{file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"},
{file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"},
{file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"},
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"},
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"},
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"},
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"},
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"},
{file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"},
{file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"},
{file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"},
{file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"},
{file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"},
{file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"},
{file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"},
{file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"},
{file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"},
{file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"},
{file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"},
{file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"},
{file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"},
{file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"},
{file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"},
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"},
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"},
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"},
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"},
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"},
{file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"},
{file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"},
{file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"},
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"},
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"},
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"},
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"},
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"},
{file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"},
{file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"},
{file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"},
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"},
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"},
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"},
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"},
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"},
{file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"},
{file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"},
{file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"},
{file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"},
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"},
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"},
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"},
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"},
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"},
{file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"},
{file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"},
{file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"},
{file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"},
{file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"},
]
[package.dependencies]
pycparser = "*"
[[package]]
name = "channels"
version = "4.0.0"
description = "Brings async, event-driven capabilities to Django 3.2 and up."
optional = false
python-versions = ">=3.7"
files = [
{file = "channels-4.0.0-py3-none-any.whl", hash = "sha256:2253334ac76f67cba68c2072273f7e0e67dbdac77eeb7e318f511d2f9a53c5e4"},
{file = "channels-4.0.0.tar.gz", hash = "sha256:0ce53507a7da7b148eaa454526e0e05f7da5e5d1c23440e4886cf146981d8420"},
]
[package.dependencies]
asgiref = ">=3.5.0,<4"
daphne = {version = ">=4.0.0", optional = true, markers = "extra == \"daphne\""}
Django = ">=3.2"
[package.extras]
daphne = ["daphne (>=4.0.0)"]
tests = ["async-timeout", "coverage (>=4.5,<5.0)", "pytest", "pytest-asyncio", "pytest-django"]
[[package]]
name = "constantly"
version = "15.1.0"
description = "Symbolic constants in Python"
optional = false
python-versions = "*"
files = [
{file = "constantly-15.1.0-py2.py3-none-any.whl", hash = "sha256:dd2fa9d6b1a51a83f0d7dd76293d734046aa176e384bf6e33b7e44880eb37c5d"},
{file = "constantly-15.1.0.tar.gz", hash = "sha256:586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35"},
]
[[package]]
name = "cryptography"
version = "41.0.3"
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
optional = false
python-versions = ">=3.7"
files = [
{file = "cryptography-41.0.3-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:652627a055cb52a84f8c448185922241dd5217443ca194d5739b44612c5e6507"},
{file = "cryptography-41.0.3-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:8f09daa483aedea50d249ef98ed500569841d6498aa9c9f4b0531b9964658922"},
{file = "cryptography-41.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fd871184321100fb400d759ad0cddddf284c4b696568204d281c902fc7b0d81"},
{file = "cryptography-41.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84537453d57f55a50a5b6835622ee405816999a7113267739a1b4581f83535bd"},
{file = "cryptography-41.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:3fb248989b6363906827284cd20cca63bb1a757e0a2864d4c1682a985e3dca47"},
{file = "cryptography-41.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:42cb413e01a5d36da9929baa9d70ca90d90b969269e5a12d39c1e0d475010116"},
{file = "cryptography-41.0.3-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:aeb57c421b34af8f9fe830e1955bf493a86a7996cc1338fe41b30047d16e962c"},
{file = "cryptography-41.0.3-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6af1c6387c531cd364b72c28daa29232162010d952ceb7e5ca8e2827526aceae"},
{file = "cryptography-41.0.3-cp37-abi3-win32.whl", hash = "sha256:0d09fb5356f975974dbcb595ad2d178305e5050656affb7890a1583f5e02a306"},
{file = "cryptography-41.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:a983e441a00a9d57a4d7c91b3116a37ae602907a7618b882c8013b5762e80574"},
{file = "cryptography-41.0.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5259cb659aa43005eb55a0e4ff2c825ca111a0da1814202c64d28a985d33b087"},
{file = "cryptography-41.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:67e120e9a577c64fe1f611e53b30b3e69744e5910ff3b6e97e935aeb96005858"},
{file = "cryptography-41.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:7efe8041897fe7a50863e51b77789b657a133c75c3b094e51b5e4b5cec7bf906"},
{file = "cryptography-41.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ce785cf81a7bdade534297ef9e490ddff800d956625020ab2ec2780a556c313e"},
{file = "cryptography-41.0.3-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:57a51b89f954f216a81c9d057bf1a24e2f36e764a1ca9a501a6964eb4a6800dd"},
{file = "cryptography-41.0.3-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c2f0d35703d61002a2bbdcf15548ebb701cfdd83cdc12471d2bae80878a4207"},
{file = "cryptography-41.0.3-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:23c2d778cf829f7d0ae180600b17e9fceea3c2ef8b31a99e3c694cbbf3a24b84"},
{file = "cryptography-41.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:95dd7f261bb76948b52a5330ba5202b91a26fbac13ad0e9fc8a3ac04752058c7"},
{file = "cryptography-41.0.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:41d7aa7cdfded09b3d73a47f429c298e80796c8e825ddfadc84c8a7f12df212d"},
{file = "cryptography-41.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d0d651aa754ef58d75cec6edfbd21259d93810b73f6ec246436a21b7841908de"},
{file = "cryptography-41.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:ab8de0d091acbf778f74286f4989cf3d1528336af1b59f3e5d2ebca8b5fe49e1"},
{file = "cryptography-41.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a74fbcdb2a0d46fe00504f571a2a540532f4c188e6ccf26f1f178480117b33c4"},
{file = "cryptography-41.0.3.tar.gz", hash = "sha256:6d192741113ef5e30d89dcb5b956ef4e1578f304708701b8b73d38e3e1461f34"},
]
[package.dependencies]
cffi = ">=1.12"
[package.extras]
docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"]
docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"]
nox = ["nox"]
pep8test = ["black", "check-sdist", "mypy", "ruff"]
sdist = ["build"]
ssh = ["bcrypt (>=3.1.5)"]
test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"]
test-randomorder = ["pytest-randomly"]
[[package]]
name = "daphne"
version = "4.0.0"
description = "Django ASGI (HTTP/WebSocket) server"
optional = false
python-versions = ">=3.7"
files = [
{file = "daphne-4.0.0-py3-none-any.whl", hash = "sha256:a288ece46012b6b719c37150be67c69ebfca0793a8521bf821533bad983179b2"},
{file = "daphne-4.0.0.tar.gz", hash = "sha256:cce9afc8f49a4f15d4270b8cfb0e0fe811b770a5cc795474e97e4da287497666"},
]
[package.dependencies]
asgiref = ">=3.5.2,<4"
autobahn = ">=22.4.2"
twisted = {version = ">=22.4", extras = ["tls"]}
[package.extras]
tests = ["django", "hypothesis", "pytest", "pytest-asyncio"]
[[package]]
name = "django"
version = "3.2.19"
description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design."
optional = false
python-versions = ">=3.6"
files = [
{file = "Django-3.2.19-py3-none-any.whl", hash = "sha256:21cc991466245d659ab79cb01204f9515690f8dae00e5eabde307f14d24d4d7d"},
{file = "Django-3.2.19.tar.gz", hash = "sha256:031365bae96814da19c10706218c44dff3b654cc4de20a98bd2d29b9bde469f0"},
]
[package.dependencies]
asgiref = ">=3.3.2,<4"
pytz = "*"
sqlparse = ">=0.2.2"
[package.extras]
argon2 = ["argon2-cffi (>=19.1.0)"]
bcrypt = ["bcrypt"]
[[package]]
name = "djangorestframework"
version = "3.14.0"
description = "Web APIs for Django, made easy."
optional = false
python-versions = ">=3.6"
files = [
{file = "djangorestframework-3.14.0-py3-none-any.whl", hash = "sha256:eb63f58c9f218e1a7d064d17a70751f528ed4e1d35547fdade9aaf4cd103fd08"},
{file = "djangorestframework-3.14.0.tar.gz", hash = "sha256:579a333e6256b09489cbe0a067e66abe55c6595d8926be6b99423786334350c8"},
]
[package.dependencies]
django = ">=3.0"
pytz = "*"
[[package]]
name = "drf-yasg"
version = "1.21.7"
description = "Automated generation of real Swagger/OpenAPI 2.0 schemas from Django Rest Framework code."
optional = false
python-versions = ">=3.6"
files = [
{file = "drf-yasg-1.21.7.tar.gz", hash = "sha256:4c3b93068b3dfca6969ab111155e4dd6f7b2d680b98778de8fd460b7837bdb0d"},
{file = "drf_yasg-1.21.7-py3-none-any.whl", hash = "sha256:f85642072c35e684356475781b7ecf5d218fff2c6185c040664dd49f0a4be181"},
]
[package.dependencies]
django = ">=2.2.16"
djangorestframework = ">=3.10.3"
inflection = ">=0.3.1"
packaging = ">=21.0"
pytz = ">=2021.1"
pyyaml = ">=5.1"
uritemplate = ">=3.0.0"
[package.extras]
coreapi = ["coreapi (>=2.3.3)", "coreschema (>=0.0.4)"]
validation = ["swagger-spec-validator (>=2.1.0)"]
[[package]]
name = "hyperlink"
version = "21.0.0"
description = "A featureful, immutable, and correct URL for Python."
optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
files = [
{file = "hyperlink-21.0.0-py2.py3-none-any.whl", hash = "sha256:e6b14c37ecb73e89c77d78cdb4c2cc8f3fb59a885c5b3f819ff4ed80f25af1b4"},
{file = "hyperlink-21.0.0.tar.gz", hash = "sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b"},
]
[package.dependencies]
idna = ">=2.5"
[[package]]
name = "idna"
version = "3.4"
description = "Internationalized Domain Names in Applications (IDNA)"
optional = false
python-versions = ">=3.5"
files = [
{file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
{file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
]
[[package]]
name = "incremental"
version = "22.10.0"
description = "\"A small library that versions your Python projects.\""
optional = false
python-versions = "*"
files = [
{file = "incremental-22.10.0-py2.py3-none-any.whl", hash = "sha256:b864a1f30885ee72c5ac2835a761b8fe8aa9c28b9395cacf27286602688d3e51"},
{file = "incremental-22.10.0.tar.gz", hash = "sha256:912feeb5e0f7e0188e6f42241d2f450002e11bbc0937c65865045854c24c0bd0"},
]
[package.extras]
mypy = ["click (>=6.0)", "mypy (==0.812)", "twisted (>=16.4.0)"]
scripts = ["click (>=6.0)", "twisted (>=16.4.0)"]
[[package]]
name = "inflection"
version = "0.5.1"
description = "A port of Ruby on Rails inflector to Python"
optional = false
python-versions = ">=3.5"
files = [
{file = "inflection-0.5.1-py2.py3-none-any.whl", hash = "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2"},
{file = "inflection-0.5.1.tar.gz", hash = "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417"},
]
[[package]]
name = "packaging"
version = "23.1"
description = "Core utilities for Python packages"
optional = false
python-versions = ">=3.7"
files = [
{file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"},
{file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"},
]
[[package]]
name = "paho-mqtt"
version = "1.6.1"
description = "MQTT version 5.0/3.1.1 client class"
optional = false
python-versions = "*"
files = [
{file = "paho-mqtt-1.6.1.tar.gz", hash = "sha256:2a8291c81623aec00372b5a85558a372c747cbca8e9934dfe218638b8eefc26f"},
]
[package.extras]
proxy = ["PySocks"]
[[package]]
name = "protobuf"
version = "3.20.1"
description = "Protocol Buffers"
optional = false
python-versions = ">=3.7"
files = [
{file = "protobuf-3.20.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3cc797c9d15d7689ed507b165cd05913acb992d78b379f6014e013f9ecb20996"},
{file = "protobuf-3.20.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:ff8d8fa42675249bb456f5db06c00de6c2f4c27a065955917b28c4f15978b9c3"},
{file = "protobuf-3.20.1-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cd68be2559e2a3b84f517fb029ee611546f7812b1fdd0aa2ecc9bc6ec0e4fdde"},
{file = "protobuf-3.20.1-cp310-cp310-win32.whl", hash = "sha256:9016d01c91e8e625141d24ec1b20fed584703e527d28512aa8c8707f105a683c"},
{file = "protobuf-3.20.1-cp310-cp310-win_amd64.whl", hash = "sha256:32ca378605b41fd180dfe4e14d3226386d8d1b002ab31c969c366549e66a2bb7"},
{file = "protobuf-3.20.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9be73ad47579abc26c12024239d3540e6b765182a91dbc88e23658ab71767153"},
{file = "protobuf-3.20.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:097c5d8a9808302fb0da7e20edf0b8d4703274d140fd25c5edabddcde43e081f"},
{file = "protobuf-3.20.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e250a42f15bf9d5b09fe1b293bdba2801cd520a9f5ea2d7fb7536d4441811d20"},
{file = "protobuf-3.20.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cdee09140e1cd184ba9324ec1df410e7147242b94b5f8b0c64fc89e38a8ba531"},
{file = "protobuf-3.20.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:af0ebadc74e281a517141daad9d0f2c5d93ab78e9d455113719a45a49da9db4e"},
{file = "protobuf-3.20.1-cp37-cp37m-win32.whl", hash = "sha256:755f3aee41354ae395e104d62119cb223339a8f3276a0cd009ffabfcdd46bb0c"},
{file = "protobuf-3.20.1-cp37-cp37m-win_amd64.whl", hash = "sha256:62f1b5c4cd6c5402b4e2d63804ba49a327e0c386c99b1675c8a0fefda23b2067"},
{file = "protobuf-3.20.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:06059eb6953ff01e56a25cd02cca1a9649a75a7e65397b5b9b4e929ed71d10cf"},
{file = "protobuf-3.20.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:cb29edb9eab15742d791e1025dd7b6a8f6fcb53802ad2f6e3adcb102051063ab"},
{file = "protobuf-3.20.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:69ccfdf3657ba59569c64295b7d51325f91af586f8d5793b734260dfe2e94e2c"},
{file = "protobuf-3.20.1-cp38-cp38-win32.whl", hash = "sha256:dd5789b2948ca702c17027c84c2accb552fc30f4622a98ab5c51fcfe8c50d3e7"},
{file = "protobuf-3.20.1-cp38-cp38-win_amd64.whl", hash = "sha256:77053d28427a29987ca9caf7b72ccafee011257561259faba8dd308fda9a8739"},
{file = "protobuf-3.20.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6f50601512a3d23625d8a85b1638d914a0970f17920ff39cec63aaef80a93fb7"},
{file = "protobuf-3.20.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:284f86a6207c897542d7e956eb243a36bb8f9564c1742b253462386e96c6b78f"},
{file = "protobuf-3.20.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7403941f6d0992d40161aa8bb23e12575637008a5a02283a930addc0508982f9"},
{file = "protobuf-3.20.1-cp39-cp39-win32.whl", hash = "sha256:db977c4ca738dd9ce508557d4fce0f5aebd105e158c725beec86feb1f6bc20d8"},
{file = "protobuf-3.20.1-cp39-cp39-win_amd64.whl", hash = "sha256:7e371f10abe57cee5021797126c93479f59fccc9693dafd6bd5633ab67808a91"},
{file = "protobuf-3.20.1-py2.py3-none-any.whl", hash = "sha256:adfc6cf69c7f8c50fd24c793964eef18f0ac321315439d94945820612849c388"},
{file = "protobuf-3.20.1.tar.gz", hash = "sha256:adc31566d027f45efe3f44eeb5b1f329da43891634d61c75a5944e9be6dd42c9"},
]
[[package]]
name = "pyasn1"
version = "0.5.0"
description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
files = [
{file = "pyasn1-0.5.0-py2.py3-none-any.whl", hash = "sha256:87a2121042a1ac9358cabcaf1d07680ff97ee6404333bacca15f76aa8ad01a57"},
{file = "pyasn1-0.5.0.tar.gz", hash = "sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde"},
]
[[package]]
name = "pyasn1-modules"
version = "0.3.0"
description = "A collection of ASN.1-based protocols modules"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
files = [
{file = "pyasn1_modules-0.3.0-py2.py3-none-any.whl", hash = "sha256:d3ccd6ed470d9ffbc716be08bd90efbd44d0734bc9303818f7336070984a162d"},
{file = "pyasn1_modules-0.3.0.tar.gz", hash = "sha256:5bd01446b736eb9d31512a30d46c1ac3395d676c6f3cafa4c03eb54b9925631c"},
]
[package.dependencies]
pyasn1 = ">=0.4.6,<0.6.0"
[[package]]
name = "pycparser"
version = "2.21"
description = "C parser in Python"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
files = [
{file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"},
{file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
]
[[package]]
name = "pyopenssl"
version = "23.2.0"
description = "Python wrapper module around the OpenSSL library"
optional = false
python-versions = ">=3.6"
files = [
{file = "pyOpenSSL-23.2.0-py3-none-any.whl", hash = "sha256:24f0dc5227396b3e831f4c7f602b950a5e9833d292c8e4a2e06b709292806ae2"},
{file = "pyOpenSSL-23.2.0.tar.gz", hash = "sha256:276f931f55a452e7dea69c7173e984eb2a4407ce413c918aa34b55f82f9b8bac"},
]
[package.dependencies]
cryptography = ">=38.0.0,<40.0.0 || >40.0.0,<40.0.1 || >40.0.1,<42"
[package.extras]
docs = ["sphinx (!=5.2.0,!=5.2.0.post0)", "sphinx-rtd-theme"]
test = ["flaky", "pretend", "pytest (>=3.0.1)"]
[[package]]
name = "pytz"
version = "2023.3"
description = "World timezone definitions, modern and historical"
optional = false
python-versions = "*"
files = [
{file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"},
{file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"},
]
[[package]]
name = "pyyaml"
version = "6.0.1"
description = "YAML parser and emitter for Python"
optional = false
python-versions = ">=3.6"
files = [
{file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"},
{file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"},
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"},
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"},
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"},
{file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"},
{file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"},
{file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"},
{file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"},
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"},
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"},
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"},
{file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"},
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
{file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"},
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"},
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"},
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"},
{file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"},
{file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"},
{file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"},
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"},
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"},
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"},
{file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"},
{file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"},
{file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"},
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"},
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"},
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"},
{file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"},
{file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"},
{file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"},
{file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"},
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"},
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"},
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"},
{file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"},
{file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"},
{file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
]
[[package]]
name = "service-identity"
version = "23.1.0"
description = "Service identity verification for pyOpenSSL & cryptography."
optional = false
python-versions = ">=3.8"
files = [
{file = "service_identity-23.1.0-py3-none-any.whl", hash = "sha256:87415a691d52fcad954a500cb81f424d0273f8e7e3ee7d766128f4575080f383"},
{file = "service_identity-23.1.0.tar.gz", hash = "sha256:ecb33cd96307755041e978ab14f8b14e13b40f1fbd525a4dc78f46d2b986431d"},
]
[package.dependencies]
attrs = ">=19.1.0"
cryptography = "*"
pyasn1 = "*"
pyasn1-modules = "*"
[package.extras]
dev = ["pyopenssl", "service-identity[docs,idna,mypy,tests]"]
docs = ["furo", "myst-parser", "pyopenssl", "sphinx", "sphinx-notfound-page"]
idna = ["idna"]
mypy = ["idna", "mypy", "types-pyopenssl"]
tests = ["coverage[toml] (>=5.0.2)", "pytest"]
[[package]]
name = "setuptools"
version = "68.1.2"
description = "Easily download, build, install, upgrade, and uninstall Python packages"
optional = false
python-versions = ">=3.8"
files = [
{file = "setuptools-68.1.2-py3-none-any.whl", hash = "sha256:3d8083eed2d13afc9426f227b24fd1659489ec107c0e86cec2ffdde5c92e790b"},
{file = "setuptools-68.1.2.tar.gz", hash = "sha256:3d4dfa6d95f1b101d695a6160a7626e15583af71a5f52176efa5d39a054d475d"},
]
[package.extras]
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5,<=7.1.2)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
[[package]]
name = "six"
version = "1.16.0"
description = "Python 2 and 3 compatibility utilities"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
files = [
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
]
[[package]]
name = "sqlparse"
version = "0.4.4"
description = "A non-validating SQL parser."
optional = false
python-versions = ">=3.5"
files = [
{file = "sqlparse-0.4.4-py3-none-any.whl", hash = "sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3"},
{file = "sqlparse-0.4.4.tar.gz", hash = "sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c"},
]
[package.extras]
dev = ["build", "flake8"]
doc = ["sphinx"]
test = ["pytest", "pytest-cov"]
[[package]]
name = "twisted"
version = "22.10.0"
description = "An asynchronous networking framework written in Python"
optional = false
python-versions = ">=3.7.1"
files = [
{file = "Twisted-22.10.0-py3-none-any.whl", hash = "sha256:86c55f712cc5ab6f6d64e02503352464f0400f66d4f079096d744080afcccbd0"},
{file = "Twisted-22.10.0.tar.gz", hash = "sha256:32acbd40a94f5f46e7b42c109bfae2b302250945561783a8b7a059048f2d4d31"},
]
[package.dependencies]
attrs = ">=19.2.0"
Automat = ">=0.8.0"
constantly = ">=15.1"
hyperlink = ">=17.1.1"
idna = {version = ">=2.4", optional = true, markers = "extra == \"tls\""}
incremental = ">=21.3.0"
pyopenssl = {version = ">=21.0.0", optional = true, markers = "extra == \"tls\""}
service-identity = {version = ">=18.1.0", optional = true, markers = "extra == \"tls\""}
twisted-iocpsupport = {version = ">=1.0.2,<2", markers = "platform_system == \"Windows\""}
typing-extensions = ">=3.6.5"
"zope.interface" = ">=4.4.2"
[package.extras]
all-non-platform = ["PyHamcrest (>=1.9.0)", "appdirs (>=1.4.0)", "bcrypt (>=3.0.0)", "contextvars (>=2.4,<3)", "cryptography (>=2.6)", "cython-test-exception-raiser (>=1.0.2,<2)", "h2 (>=3.0,<5.0)", "hypothesis (>=6.0,<7.0)", "idna (>=2.4)", "priority (>=1.1.0,<2.0)", "pyasn1", "pyopenssl (>=21.0.0)", "pyserial (>=3.0)", "pywin32 (!=226)", "service-identity (>=18.1.0)"]
conch = ["appdirs (>=1.4.0)", "bcrypt (>=3.0.0)", "cryptography (>=2.6)", "pyasn1"]
conch-nacl = ["PyNaCl", "appdirs (>=1.4.0)", "bcrypt (>=3.0.0)", "cryptography (>=2.6)", "pyasn1"]
contextvars = ["contextvars (>=2.4,<3)"]
dev = ["coverage (>=6b1,<7)", "pydoctor (>=22.9.0,<22.10.0)", "pyflakes (>=2.2,<3.0)", "python-subunit (>=1.4,<2.0)", "readthedocs-sphinx-ext (>=2.1,<3.0)", "sphinx (>=5.0,<6)", "sphinx-rtd-theme (>=1.0,<2.0)", "towncrier (>=22.8,<23.0)", "twistedchecker (>=0.7,<1.0)"]
dev-release = ["pydoctor (>=22.9.0,<22.10.0)", "readthedocs-sphinx-ext (>=2.1,<3.0)", "sphinx (>=5.0,<6)", "sphinx-rtd-theme (>=1.0,<2.0)", "towncrier (>=22.8,<23.0)"]
gtk-platform = ["PyHamcrest (>=1.9.0)", "appdirs (>=1.4.0)", "bcrypt (>=3.0.0)", "contextvars (>=2.4,<3)", "cryptography (>=2.6)", "cython-test-exception-raiser (>=1.0.2,<2)", "h2 (>=3.0,<5.0)", "hypothesis (>=6.0,<7.0)", "idna (>=2.4)", "priority (>=1.1.0,<2.0)", "pyasn1", "pygobject", "pyopenssl (>=21.0.0)", "pyserial (>=3.0)", "pywin32 (!=226)", "service-identity (>=18.1.0)"]
http2 = ["h2 (>=3.0,<5.0)", "priority (>=1.1.0,<2.0)"]
macos-platform = ["PyHamcrest (>=1.9.0)", "appdirs (>=1.4.0)", "bcrypt (>=3.0.0)", "contextvars (>=2.4,<3)", "cryptography (>=2.6)", "cython-test-exception-raiser (>=1.0.2,<2)", "h2 (>=3.0,<5.0)", "hypothesis (>=6.0,<7.0)", "idna (>=2.4)", "priority (>=1.1.0,<2.0)", "pyasn1", "pyobjc-core", "pyobjc-framework-CFNetwork", "pyobjc-framework-Cocoa", "pyopenssl (>=21.0.0)", "pyserial (>=3.0)", "pywin32 (!=226)", "service-identity (>=18.1.0)"]
mypy = ["PyHamcrest (>=1.9.0)", "PyNaCl", "appdirs (>=1.4.0)", "bcrypt (>=3.0.0)", "contextvars (>=2.4,<3)", "coverage (>=6b1,<7)", "cryptography (>=2.6)", "cython-test-exception-raiser (>=1.0.2,<2)", "h2 (>=3.0,<5.0)", "hypothesis (>=6.0,<7.0)", "idna (>=2.4)", "mypy (==0.930)", "mypy-zope (==0.3.4)", "priority (>=1.1.0,<2.0)", "pyasn1", "pydoctor (>=22.9.0,<22.10.0)", "pyflakes (>=2.2,<3.0)", "pyopenssl (>=21.0.0)", "pyserial (>=3.0)", "python-subunit (>=1.4,<2.0)", "pywin32 (!=226)", "readthedocs-sphinx-ext (>=2.1,<3.0)", "service-identity (>=18.1.0)", "sphinx (>=5.0,<6)", "sphinx-rtd-theme (>=1.0,<2.0)", "towncrier (>=22.8,<23.0)", "twistedchecker (>=0.7,<1.0)", "types-pyOpenSSL", "types-setuptools"]
osx-platform = ["PyHamcrest (>=1.9.0)", "appdirs (>=1.4.0)", "bcrypt (>=3.0.0)", "contextvars (>=2.4,<3)", "cryptography (>=2.6)", "cython-test-exception-raiser (>=1.0.2,<2)", "h2 (>=3.0,<5.0)", "hypothesis (>=6.0,<7.0)", "idna (>=2.4)", "priority (>=1.1.0,<2.0)", "pyasn1", "pyobjc-core", "pyobjc-framework-CFNetwork", "pyobjc-framework-Cocoa", "pyopenssl (>=21.0.0)", "pyserial (>=3.0)", "pywin32 (!=226)", "service-identity (>=18.1.0)"]
serial = ["pyserial (>=3.0)", "pywin32 (!=226)"]
test = ["PyHamcrest (>=1.9.0)", "cython-test-exception-raiser (>=1.0.2,<2)", "hypothesis (>=6.0,<7.0)"]
tls = ["idna (>=2.4)", "pyopenssl (>=21.0.0)", "service-identity (>=18.1.0)"]
windows-platform = ["PyHamcrest (>=1.9.0)", "appdirs (>=1.4.0)", "bcrypt (>=3.0.0)", "contextvars (>=2.4,<3)", "cryptography (>=2.6)", "cython-test-exception-raiser (>=1.0.2,<2)", "h2 (>=3.0,<5.0)", "hypothesis (>=6.0,<7.0)", "idna (>=2.4)", "priority (>=1.1.0,<2.0)", "pyasn1", "pyopenssl (>=21.0.0)", "pyserial (>=3.0)", "pywin32 (!=226)", "pywin32 (!=226)", "service-identity (>=18.1.0)"]
[[package]]
name = "twisted-iocpsupport"
version = "1.0.4"
description = "An extension for use in the twisted I/O Completion Ports reactor."
optional = false
python-versions = "*"
files = [
{file = "twisted-iocpsupport-1.0.4.tar.gz", hash = "sha256:858096c0d15e33f15ac157f455d8f86f2f2cdd223963e58c0f682a3af8362d89"},
{file = "twisted_iocpsupport-1.0.4-cp310-cp310-win32.whl", hash = "sha256:afa2b630797f9ed2f27f3d9f55e3f72b4244911e45a8c82756f44babbf0b243e"},
{file = "twisted_iocpsupport-1.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:0058c963c8957bcd3deda62122e89953c9de1e867a274facc9b15dde1a9f31e8"},
{file = "twisted_iocpsupport-1.0.4-cp311-cp311-win32.whl", hash = "sha256:196f7c7ccad4ba4d1783b1c4e1d1b22d93c04275cd780bf7498d16c77319ad6e"},
{file = "twisted_iocpsupport-1.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:4e5f97bcbabdd79cbaa969b63439b89801ea560f11d42b0a387634275c633623"},
{file = "twisted_iocpsupport-1.0.4-cp312-cp312-win32.whl", hash = "sha256:6081bd7c2f4fcf9b383dcdb3b3385d75a26a7c9d2be25b6950c3d8ea652d2d2d"},
{file = "twisted_iocpsupport-1.0.4-cp312-cp312-win_amd64.whl", hash = "sha256:76f7e67cec1f1d097d1f4ed7de41be3d74546e1a4ede0c7d56e775c4dce5dfb0"},
{file = "twisted_iocpsupport-1.0.4-cp36-cp36m-win32.whl", hash = "sha256:3d306fc4d88a6bcf61ce9d572c738b918578121bfd72891625fab314549024b5"},
{file = "twisted_iocpsupport-1.0.4-cp36-cp36m-win_amd64.whl", hash = "sha256:391ac4d6002a80e15f35adc4ad6056f4fe1c17ceb0d1f98ba01b0f4f917adfd7"},
{file = "twisted_iocpsupport-1.0.4-cp37-cp37m-win32.whl", hash = "sha256:0c1b5cf37f0b2d96cc3c9bc86fff16613b9f5d0ca565c96cf1f1fb8cfca4b81c"},
{file = "twisted_iocpsupport-1.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:3c5dc11d72519e55f727320e3cee535feedfaee09c0f0765ed1ca7badff1ab3c"},
{file = "twisted_iocpsupport-1.0.4-cp38-cp38-win32.whl", hash = "sha256:cc86c2ef598c15d824a243c2541c29459881c67fc3c0adb6efe2242f8f0ec3af"},
{file = "twisted_iocpsupport-1.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:c27985e949b9b1a1fb4c20c71d315c10ea0f93fdf3ccdd4a8c158b5926edd8c8"},
{file = "twisted_iocpsupport-1.0.4-cp39-cp39-win32.whl", hash = "sha256:e311dfcb470696e3c077249615893cada598e62fa7c4e4ca090167bd2b7d331f"},
{file = "twisted_iocpsupport-1.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:4574eef1f3bb81501fb02f911298af3c02fe8179c31a33b361dd49180c3e644d"},
{file = "twisted_iocpsupport-1.0.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:872747a3b64e2909aee59c803ccd0bceb9b75bf27915520ebd32d69687040fa2"},
{file = "twisted_iocpsupport-1.0.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:c2712b778bacf1db434e3e065adfed3db300754186a29aecac1efae9ef4bcaff"},
{file = "twisted_iocpsupport-1.0.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7c66fa0aa4236b27b3c61cb488662d85dae746a6d1c7b0d91cf7aae118445adf"},
{file = "twisted_iocpsupport-1.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:300437af17396a945a58dcfffd77863303a8b6d9e65c6e81f1d2eed55b50d444"},
]
[[package]]
name = "txaio"
version = "23.1.1"
description = "Compatibility API between asyncio/Twisted/Trollius"
optional = false
python-versions = ">=3.7"
files = [
{file = "txaio-23.1.1-py2.py3-none-any.whl", hash = "sha256:aaea42f8aad50e0ecfb976130ada140797e9dcb85fad2cf72b0f37f8cefcb490"},
{file = "txaio-23.1.1.tar.gz", hash = "sha256:f9a9216e976e5e3246dfd112ad7ad55ca915606b60b84a757ac769bd404ff704"},
]
[package.extras]
all = ["twisted (>=20.3.0)", "zope.interface (>=5.2.0)"]
dev = ["pep8 (>=1.6.2)", "pyenchant (>=1.6.6)", "pytest (>=2.6.4)", "pytest-cov (>=1.8.1)", "sphinx (>=1.2.3)", "sphinx-rtd-theme (>=0.1.9)", "sphinxcontrib-spelling (>=2.1.2)", "tox (>=2.1.1)", "tox-gh-actions (>=2.2.0)", "twine (>=1.6.5)", "wheel"]
twisted = ["twisted (>=20.3.0)", "zope.interface (>=5.2.0)"]
[[package]]
name = "typing-extensions"
version = "4.7.1"
description = "Backported and Experimental Type Hints for Python 3.7+"
optional = false
python-versions = ">=3.7"
files = [
{file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"},
{file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"},
]
[[package]]
name = "uritemplate"
version = "4.1.1"
description = "Implementation of RFC 6570 URI Templates"
optional = false
python-versions = ">=3.6"
files = [
{file = "uritemplate-4.1.1-py2.py3-none-any.whl", hash = "sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e"},
{file = "uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0"},
]
[[package]]
name = "zope-interface"
version = "6.0"
description = "Interfaces for Python"
optional = false
python-versions = ">=3.7"
files = [
{file = "zope.interface-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f299c020c6679cb389814a3b81200fe55d428012c5e76da7e722491f5d205990"},
{file = "zope.interface-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ee4b43f35f5dc15e1fec55ccb53c130adb1d11e8ad8263d68b1284b66a04190d"},
{file = "zope.interface-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a158846d0fca0a908c1afb281ddba88744d403f2550dc34405c3691769cdd85"},
{file = "zope.interface-6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f72f23bab1848edb7472309e9898603141644faec9fd57a823ea6b4d1c4c8995"},
{file = "zope.interface-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48f4d38cf4b462e75fac78b6f11ad47b06b1c568eb59896db5b6ec1094eb467f"},
{file = "zope.interface-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:87b690bbee9876163210fd3f500ee59f5803e4a6607d1b1238833b8885ebd410"},
{file = "zope.interface-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f2363e5fd81afb650085c6686f2ee3706975c54f331b426800b53531191fdf28"},
{file = "zope.interface-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:af169ba897692e9cd984a81cb0f02e46dacdc07d6cf9fd5c91e81f8efaf93d52"},
{file = "zope.interface-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa90bac61c9dc3e1a563e5babb3fd2c0c1c80567e815442ddbe561eadc803b30"},
{file = "zope.interface-6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:89086c9d3490a0f265a3c4b794037a84541ff5ffa28bb9c24cc9f66566968464"},
{file = "zope.interface-6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:809fe3bf1a91393abc7e92d607976bbb8586512913a79f2bf7d7ec15bd8ea518"},
{file = "zope.interface-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:0ec9653825f837fbddc4e4b603d90269b501486c11800d7c761eee7ce46d1bbb"},
{file = "zope.interface-6.0-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:790c1d9d8f9c92819c31ea660cd43c3d5451df1df61e2e814a6f99cebb292788"},
{file = "zope.interface-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b39b8711578dcfd45fc0140993403b8a81e879ec25d53189f3faa1f006087dca"},
{file = "zope.interface-6.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eba51599370c87088d8882ab74f637de0c4f04a6d08a312dce49368ba9ed5c2a"},
{file = "zope.interface-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee934f023f875ec2cfd2b05a937bd817efcc6c4c3f55c5778cbf78e58362ddc"},
{file = "zope.interface-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:042f2381118b093714081fd82c98e3b189b68db38ee7d35b63c327c470ef8373"},
{file = "zope.interface-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:dfbbbf0809a3606046a41f8561c3eada9db811be94138f42d9135a5c47e75f6f"},
{file = "zope.interface-6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:424d23b97fa1542d7be882eae0c0fc3d6827784105264a8169a26ce16db260d8"},
{file = "zope.interface-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e538f2d4a6ffb6edfb303ce70ae7e88629ac6e5581870e66c306d9ad7b564a58"},
{file = "zope.interface-6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12175ca6b4db7621aedd7c30aa7cfa0a2d65ea3a0105393e05482d7a2d367446"},
{file = "zope.interface-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c3d7dfd897a588ec27e391edbe3dd320a03684457470415870254e714126b1f"},
{file = "zope.interface-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:b3f543ae9d3408549a9900720f18c0194ac0fe810cecda2a584fd4dca2eb3bb8"},
{file = "zope.interface-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d0583b75f2e70ec93f100931660328965bb9ff65ae54695fb3fa0a1255daa6f2"},
{file = "zope.interface-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:23ac41d52fd15dd8be77e3257bc51bbb82469cf7f5e9a30b75e903e21439d16c"},
{file = "zope.interface-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99856d6c98a326abbcc2363827e16bd6044f70f2ef42f453c0bd5440c4ce24e5"},
{file = "zope.interface-6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1592f68ae11e557b9ff2bc96ac8fc30b187e77c45a3c9cd876e3368c53dc5ba8"},
{file = "zope.interface-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4407b1435572e3e1610797c9203ad2753666c62883b921318c5403fb7139dec2"},
{file = "zope.interface-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:5171eb073474a5038321409a630904fd61f12dd1856dd7e9d19cd6fe092cbbc5"},
{file = "zope.interface-6.0.tar.gz", hash = "sha256:aab584725afd10c710b8f1e6e208dbee2d0ad009f57d674cb9d1b3964037275d"},
]
[package.dependencies]
setuptools = "*"
[package.extras]
docs = ["Sphinx", "repoze.sphinx.autointerface"]
test = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
[metadata]
lock-version = "2.0"
python-versions = "^3.9"
content-hash = "f761714ff60db8e9ad08e4266a9bcf848b31c742a1f739f2add93363930fe3ce"
# Generated by Django 3.2.19 on 2023-08-21 01:52
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('protocol_version_manage', '0002_test'),
]
operations = [
migrations.RenameModel(
old_name='AllProtocolChangeLog',
new_name='AllProtocolVersion',
),
migrations.DeleteModel(
name='Test',
),
migrations.RenameField(
model_name='allprotocolversion',
old_name='log',
new_name='vesrions_path',
),
migrations.AlterModelTable(
name='allprotocolversion',
table='AllProtocolVersion',
),
]
# Generated by Django 3.2.19 on 2023-08-21 02:19
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('protocol_version_manage', '0003_auto_20230821_0952'),
]
operations = [
migrations.RemoveField(
model_name='allprotocolversion',
name='id',
),
migrations.RemoveField(
model_name='currentdevversion',
name='id',
),
migrations.AlterField(
model_name='allprotocolversion',
name='protocol_name',
field=models.TextField(primary_key=True, serialize=False),
),
migrations.AlterField(
model_name='currentdevversion',
name='protocol_name',
field=models.TextField(primary_key=True, serialize=False),
),
]
# Generated by Django 3.2.19 on 2023-08-21 05:22
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('protocol_version_manage', '0004_auto_20230821_1019'),
]
operations = [
migrations.RenameField(
model_name='allprotocolversion',
old_name='vesrions_path',
new_name='version_paths',
),
]
......@@ -22,11 +22,41 @@ class AllDevCmdDefineAndVersion(models.Model):
lua_script_out = models.TextField() # Field name made lowercase.
version = models.TextField()
def __eq__(self, __value: object) -> bool:
if not isinstance(__value, AllDevCmdDefineAndVersion):
return False
if (self.cmd_name == __value.cmd_name and
self.cmd_type == __value.cmd_type and
self.fieldindex == __value.fieldindex and
self.fieldname == __value.fieldname and
self.fieldsize == __value.fieldsize and
self.value == __value.value and
self.minvalue == __value.minvalue and
self.maxvalue == __value.maxvalue and
self.datatype == __value.datatype and
self.operation_in == __value.operation_in and
self.operation_in_num == __value.operation_in_num and
self.operation_out == __value.operation_out and
self.operation_out_num == __value.operation_out_num and
self.operabo_in == __value.operabo_in and
self.operabo_out == __value.operabo_out and
self.lua_script_in == __value.lua_script_in and
self.lua_script_out == __value.lua_script_out):
return True
return False
class Meta:
db_table = 'AllDevCmdDefineAndVersion'
class AllProtocolDefinAndVersion(models.Model):
"""
version 格式
版本号的列表
["20230708", "20230709", "20230710"]
"""
id = models.AutoField(primary_key=True) # Field name made lowercase.
protocol_name = models.TextField() # Field name made lowercase.
cmd_name = models.TextField() # Field name made lowercase.
......@@ -36,13 +66,26 @@ class AllProtocolDefinAndVersion(models.Model):
cmd_explain = models.TextField() # Field name made lowercase.
version = models.TextField()
def __eq__(self, __value: object) -> bool:
if not isinstance(__value, AllProtocolDefinAndVersion):
return False
if (self.protocol_name == __value.protocol_name and
self.cmd_name == __value.cmd_name and
self.cmd_type == __value.cmd_type and
self.encode == __value.encode and
self.timing_cmd_cycle_period == __value.timing_cmd_cycle_period and
self.cmd_explain == __value.cmd_explain):
return True
return False
class Meta:
db_table = 'AllProtocolDefinAndVersion'
class CurrentDevVersion(models.Model):
id = models.AutoField(primary_key=True) # Field name made lowercase.
protocol_name = models.TextField() # Field name made lowercase.
protocol_name = models.TextField(primary_key=True) # Field name made lowercase.
version = models.TextField()
class Meta:
......@@ -50,9 +93,16 @@ class CurrentDevVersion(models.Model):
class AllProtocolVersion(models.Model):
id = models.AutoField(primary_key=True)
protocol_name = models.TextField()
vesrions_path = models.TextField()
"""
versions_path 格式
版本号:版本原始文件所在的路径
{
"vesrion": "20230708",
"path": "/path/to/file"
}
"""
protocol_name = models.TextField(primary_key=True)
version_paths = models.TextField()
class Meta:
db_table = 'AllProtocolVersion'
......
from .models import (CurrentDevVersion, AllDevCmdDefineAndVersion,
AllProtocolDefinAndVersion, AllProtocolVersion)
from rest_framework import serializers
class AllProtocolVersionSerializer(serializers.ModelSerializer):
class Meta:
model = AllProtocolVersion
fields = '__all__'
class AllDevCmdDefineAndVersionSerializer(serializers.ModelSerializer):
class Meta:
model = AllDevCmdDefineAndVersion
fields = '__all__'
class AllProtocolDefinAndVersionSerializer(serializers.ModelSerializer):
class Meta:
model = AllProtocolDefinAndVersion
fields = '__all__'
class CurrentDevVersionSerializer(serializers.ModelSerializer):
class Meta:
model = CurrentDevVersion
fields = '__all__'
import json
from device_data_op.models import TableAllDevCmdDefine, TableDevCmdNamePoll
from device_data_op.serializers import TableAllDevCmdDefineSerializer, TableDevCmdNamePollSerializer
from django.db.models import QuerySet
from rest_framework.response import Response
from rest_framework import status
from .models import (AllDevCmdDefineAndVersion, AllProtocolDefinAndVersion,
AllProtocolVersion, CurrentDevVersion)
from .serializers import (AllDevCmdDefineAndVersionSerializer, AllProtocolDefinAndVersionSerializer,
AllProtocolVersionSerializer, CurrentDevVersionSerializer)
INIT_VERSION = "init"
def init_protocol_version_manage(protocol_name: str) -> None:
"""
将协议版本信息初始化,即先将 device 已经在用的表的数据添加到数据库表中
:param protocol_name: 协议名
"""
protocol_cmds = TableDevCmdNamePoll.objects.filter(protocol_name=protocol_name).all()
protocol_cmds_serializer = TableDevCmdNamePollSerializer(protocol_cmds, many=True)
all_protocol_objects: list[AllProtocolDefinAndVersion] = []
for protocol in protocol_cmds_serializer.data:
protocol['version'] = json.dumps([INIT_VERSION])
del protocol['id']
all_protocol_objects.append(AllProtocolDefinAndVersion(**protocol))
AllProtocolDefinAndVersion.objects.bulk_create(all_protocol_objects)
cmd_fields: list[QuerySet] = []
for protocol in protocol_cmds:
cmd_fields.extend(TableAllDevCmdDefine.objects.filter(cmd_name=protocol.cmd_name).all())
cmd_fields_serializer = TableAllDevCmdDefineSerializer(cmd_fields, many=True)
all_cmd_fields_objects: list[AllDevCmdDefineAndVersion] = []
for cmd_field in cmd_fields_serializer.data:
cmd_field['version'] = json.dumps([INIT_VERSION])
del cmd_field['id']
all_cmd_fields_objects.append(AllDevCmdDefineAndVersion(**cmd_field))
AllDevCmdDefineAndVersion.objects.bulk_create(all_cmd_fields_objects)
version_path = {
"version": INIT_VERSION
}
AllProtocolVersion.objects.create(protocol_name=protocol_name,
version_paths=json.dumps([version_path]))
CurrentDevVersion.objects.create(protocol_name=protocol_name,
version=INIT_VERSION)
def update_device_protocol_and_cmds(protocol_name: str, version: str) -> Response:
"""
根据协议名和版本号更新协议版本信息
通过协议名和版本号将 AllProtocolDefinAndVersion 和 AllDevCmdDefineAndVersion 中符合
要求的数据更新到 TableDevCmdNamePoll 和 TableAllDevCmdDefine 中
:param protocol_name: 协议名
:param version: 版本号
:return: 当前版本,协议相关的数据
"""
# 更新版本号
CurrentDevVersion.objects.filter(protocol_name=protocol_name).update(version=version)
# 更新协议版本信息
all_protocol = AllProtocolDefinAndVersion.objects.filter(protocol_name=protocol_name).all()
current_version_protocols = [protocol for protocol in all_protocol
if version in json.loads(protocol.version)]
cmd_fields = []
for current_version_protocol in current_version_protocols:
cmd_name = current_version_protocol.cmd_name
cmd_fields.extend([item for item in AllDevCmdDefineAndVersion.objects.filter(cmd_name=cmd_name).all()
if version in json.loads(item.version)])
current_version_protocol_serializer = AllProtocolDefinAndVersionSerializer(current_version_protocols, many=True)
cmd_fields_serializer = AllDevCmdDefineAndVersionSerializer(cmd_fields, many=True)
# 更新 device 所使用的命令表数据
try:
TableAllDevCmdDefine.objects.filter(cmd_name__in=[cmd.cmd_name
for cmd in TableDevCmdNamePoll.objects.filter(protocol_name=protocol_name).all()]).delete()
TableAllDevCmdDefine.objects.bulk_create([TableAllDevCmdDefine(
**{k: v for k, v in cmd_field.items() if k not in ['id', 'version']})
for cmd_field in cmd_fields_serializer.data])
except Exception as e:
print(e)
return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
# 更新 device 所使用的协议表数据
try:
TableDevCmdNamePoll.objects.filter(protocol_name=protocol_name).delete()
TableDevCmdNamePoll.objects.bulk_create([TableDevCmdNamePoll(
**{k: v for k, v in protocol.items() if k not in ['id', 'version']})
for protocol in current_version_protocol_serializer.data])
except Exception as e:
print(e)
return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
# 返回数据
cmds = []
for protocol in current_version_protocol_serializer.data:
protocol['fields'] = sorted([item for item in cmd_fields_serializer.data
if item['cmd_name'] == protocol['cmd_name']],
key=lambda item: item['fieldindex'])
cmds.append(protocol)
res_data = {
'current_version': version,
'protocol': protocol_name,
'cmds': cmds
}
return Response(data=res_data, status=status.HTTP_200_OK)
def add_protocol_version_manage(protocol_name: str, version: str, cmds: list) -> Response:
"""
添加协议版本信息
:param protocol_name: 协议名
:param version: 版本号
:param cmds: 协议相关的命令
:return: 当前版本,协议相关的数据
"""
# 给协议添加新的版本号
all_protocol_version_manage = AllProtocolVersion.objects.filter(protocol_name=protocol_name).first()
version_paths = json.loads(all_protocol_version_manage.version_paths)
version_paths.append({"version": version})
all_protocol_version_manage.version_paths = json.dumps(version_paths)
all_protocol_version_manage.save()
try:
# 更新协议下的指令
for cmd in cmds:
# 获取指令字段
fields = cmd.pop('fields')
# 处理协议指令
_cmd = AllProtocolDefinAndVersion.objects.filter(protocol_name=protocol_name, cmd_name=cmd['cmd_name']).first()
new_cmd = AllProtocolDefinAndVersion(**cmd)
if _cmd == new_cmd:
# 如果指令已经存在,则更新版本号
version_list = json.loads(_cmd.version)
version_list.append(version) if version not in version_list else version_list
_cmd.version = json.dumps(version_list)
_cmd.save()
else:
# 指令不存在,则存储指令信息
new_cmd.version = json.dumps([version])
new_cmd.save()
# 处理指令
for field in fields:
_field = AllDevCmdDefineAndVersion.objects.filter(cmd_name=cmd['cmd_name'], fieldname=field['fieldname']).first()
new_field = AllDevCmdDefineAndVersion(**field)
if _field == new_field:
# 如果指令字段已经存在,则更新版本号
version_list = json.loads(_field.version)
version_list.append(version) if version not in version_list else version_list
_field.version = json.dumps(version_list)
_field.save()
else:
# 指令字段不存在,则存储指令信息
new_field.version = json.dumps([version])
new_field.save()
except Exception as e:
print(e)
return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
return Response(status=status.HTTP_200_OK)
def update_protocol_version_manage(protocol_name: str, version: str, cmds: list) -> Response:
"""
更新协议版本信息
:param protocol_name: 协议名
:param version: 版本号
:param cmds: 协议相关的命令
:return: 当前版本,协议相关的数据
"""
# 给协议添加新的版本号
all_protocol_version_manage = AllProtocolVersion.objects.filter(protocol_name=protocol_name).first()
version_paths = json.loads(all_protocol_version_manage.version_paths)
true_version = False
for version_path in version_paths:
if version_path['version'] == version:
true_version = True
break
if not true_version:
return Response(status=status.HTTP_400_BAD_REQUEST)
try:
for cmd in cmds:
# 获取指令字段
fields = cmd.pop('fields')
# 处理协议指令
_cmds = AllProtocolDefinAndVersion.objects.filter(protocol_name=protocol_name, cmd_name=cmd['cmd_name']).all()
new_cmd = AllProtocolDefinAndVersion(**cmd)
updated = False
for _cmd in _cmds:
# 遍历相同协议下相同名称不同版本的指令
vesrion_list = json.loads(_cmd.version)
if version in vesrion_list:
if _cmd == new_cmd:
updated = True
break
else:
# 该指令还有其他协议版本,新建指令信息
if len(vesrion_list) > 1:
# 删除原先指令版本信息
vesrion_list.remove(version)
_cmd.version = json.dumps(vesrion_list)
_cmd.save()
# 创建新的
new_cmd.version = json.dumps([version])
new_cmd.save()
else:
# 更新信息
_cmd.cmd_type = cmd['cmd_type']
_cmd.encode = cmd['encode']
_cmd.timing_cmd_cycle_period = cmd['timing_cmd_cycle_period']
_cmd.cmd_explain = cmd['cmd_explain']
_cmd.save()
updated = True
if not updated:
# 如果没有相关指令,则存储指令信息
new_cmd.version = json.dumps([version])
new_cmd.save()
# 处理指令字段
for field in fields:
_fields = AllDevCmdDefineAndVersion.objects.filter(cmd_name=cmd['cmd_name'], fieldname=field['fieldname']).all()
new_field = AllDevCmdDefineAndVersion(**field)
updated = False
for _field in _fields:
# 遍历相同协议下相同名称不同版本的指令字段
version_list = json.loads(_field.version)
if version in version_list:
if _field == new_field:
updated = True
break
else:
# 该指令字段还有其他协议版本,新建指令信息
if len(version_list) > 1:
# 删除原先指令版本信息
version_list.remove(version)
_field.version = json.dumps(version_list)
_field.save()
# 创建新的
new_field.version = json.dumps([version])
new_field.save()
else:
# 更新信息
_field.cmd_type = field['cmd_type']
_field.fieldindex = field['fieldindex']
_field.fieldsize = field['fieldsize']
_field.value = field['value']
_field.minvalue = field['minvalue']
_field.maxvalue = field['maxvalue']
_field.datatype = field['datatype']
_field.operation_in = field['operation_in']
_field.operation_in_num = field['operation_in_num']
_field.operation_out = field['operation_out']
_field.operation_out_num = field['operation_out_num']
_field.operabo_in = field['operabo_in']
_field.operabo_out = field['operabo_out']
_field.lua_script_in = field['lua_script_in']
_field.lua_script_out = field['lua_script_out']
_field.save()
updated = True
if not updated:
# 如果没有相关指令字段,则存储指令信息
new_field.version = json.dumps([version])
new_field.save()
except Exception as e:
print(e)
return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
return Response(status=status.HTTP_200_OK)
from django.urls import re_path
from . import views
urlpatterns = [
re_path(r'^protocol_version_manage/init/$', views.init),
re_path(r'^protocol_version_manage/change_protocol_version/$', views.change_protocol_version),
re_path(r'^protocol_version_manage/add_protocol_version/$', views.add_protocol_version),
re_path(r'^protocol_version_manage/update_protocol_version/$', views.update_protocol_version),
re_path(r'^protocol_version_manage/file_upload/$', views.raw_file_upload),
re_path(r'^protocol_version_manage/file_download/(?P<protocol_name>.+)/(?P<version>.+)/$',
views.raw_file_download),
re_path(r'^all_protocol_version/$', views.AllProtocolVersionViewSet.as_view({'get': 'list'})),
]
from django.shortcuts import render
from rest_framework.decorators import api_view
import os
import json
import urllib.parse
from django.conf import settings
from django.http import FileResponse
from rest_framework.decorators import api_view, parser_classes
from rest_framework.parsers import MultiPartParser
from rest_framework.response import Response
from rest_framework import status
# Create your views here.
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import ListModelMixin
from .models import (AllDevCmdDefineAndVersion, AllProtocolDefinAndVersion,
AllProtocolVersion, CurrentDevVersion)
from .serializers import (AllDevCmdDefineAndVersionSerializer, AllProtocolDefinAndVersionSerializer,
AllProtocolVersionSerializer, CurrentDevVersionSerializer)
from .services import (init_protocol_version_manage, update_device_protocol_and_cmds,
add_protocol_version_manage, update_protocol_version_manage)
@api_view(['POST'])
def init(request):
"""
初始化协议版本信息(用的很少,大概)
"""
protocol_name = request.data.get('protocol_name')
if protocol_name is None:
return Response(status=status.HTTP_400_BAD_REQUEST)
all_protocol_version = AllProtocolVersion.objects.filter(protocol_name=protocol_name).first()
try:
if all_protocol_version is None:
# 该协议为空,即没有协议版本信息
init_protocol_version_manage(protocol_name)
all_protocol_version = AllProtocolVersion.objects.filter(protocol_name=protocol_name).first()
# 该协议不为空,即有协议版本信息
current_protocol_version = CurrentDevVersion.objects.filter(protocol_name=protocol_name).first()
data = json.loads(all_protocol_version.version_paths)
res_data = {
'version_paths': data,
'current_version': current_protocol_version.version
}
except:
return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
return Response(data=res_data, status=status.HTTP_200_OK)
@api_view(['POST'])
def change_protocol_version(request):
version = request.data.get('version')
protocol_name = request.data.get('protocol_name')
if protocol_name is None or version is None:
return Response(status=status.HTTP_400_BAD_REQUEST)
return update_device_protocol_and_cmds(protocol_name, version)
@api_view(['POST'])
def add_protocol_version(request):
version = request.data.get('version')
protocol_name = request.data.get('protocol_name')
cmds = request.data.get('cmds')
if (protocol_name is None or
cmds is None or
version is None):
return Response(status=status.HTTP_400_BAD_REQUEST)
return add_protocol_version_manage(protocol_name, version, cmds)
@api_view(['POST'])
def update_protocol_version(request):
version = request.data.get('version')
protocol_name = request.data.get('protocol_name')
cmds = request.data.get('cmds')
if (protocol_name is None or
version is None or
cmds is None):
return Response(status=status.HTTP_400_BAD_REQUEST)
return update_protocol_version_manage(protocol_name, version, cmds)
class AllProtocolVersionViewSet(GenericViewSet, ListModelMixin):
queryset = AllProtocolVersion.objects.all()
serializer_class = AllProtocolVersionSerializer
@api_view(['POST'])
@parser_classes([MultiPartParser])
def raw_file_upload(request):
file_obj = request.FILES.get('file')
protocol_name = request.data.get('protocol_name')
version = request.data.get('version')
if protocol_name is None or version is None:
return Response(status=status.HTTP_400_BAD_REQUEST)
# 构建文件夹路径和文件路径
folder_path = os.path.join(settings.BASE_DIR, 'protocol_raw_files', protocol_name, version)
if not os.path.exists(folder_path):
os.makedirs(folder_path)
file_path = os.path.join(folder_path, file_obj.name)
# 更新协议版本信息,将文件路径保存下来
protocol_versions = AllProtocolVersion.objects.filter(protocol_name=protocol_name).first()
version_path_list = json.loads(protocol_versions.version_paths)
for version_path in version_path_list:
if version_path['version'] == version:
if version_path.get('path', None) is not None:
try:
os.remove(version_path['path'])
except Exception as e:
print(e)
return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
version_path['path'] = file_path
break
# 将上传来的文件保存下来
try:
with open(file_path, 'wb') as f:
for chunk in file_obj.chunks():
f.write(chunk)
except Exception as e:
print(e)
return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
# 将路径保存下来
protocol_versions.version_paths = json.dumps(version_path_list)
protocol_versions.save()
return Response(data={'path': file_path}, status=status.HTTP_200_OK)
@api_view(['GET'])
@parser_classes([MultiPartParser])
def raw_file_download(request, protocol_name, version):
try:
protocol_versions = AllProtocolVersion.objects.filter(protocol_name=protocol_name).first()
for version_path in json.loads(protocol_versions.version_paths):
if version_path['version'] == version:
file_path = version_path['path']
break
file_name = urllib.parse.quote(os.path.basename(file_path))
response = FileResponse(open(file_path, 'rb'))
except Exception as e:
print(e)
return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
response['Content-Disposition'] = 'attachment; filename=' + file_name
response['Content-Type'] = 'multipart/form-data'
response['filename'] = file_name
return response
[tool.poetry]
name = "vue-django"
version = "0.1.0"
description = ""
authors = ["ZutJoe <zhout50@163.com>"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.9"
django = "3.2.19"
djangorestframework = "^3.14.0"
channels = {extras = ["daphne"], version = "^4.0.0"}
drf-yasg = "^1.21.7"
paho-mqtt = "^1.6.1"
protobuf = "3.20.1"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
......@@ -35,6 +35,7 @@ INSTALLED_APPS = [
'chat',
'device_data_op',
'protocol_version_manage',
'device_communication',
'django.contrib.admin',
'django.contrib.auth',
......@@ -51,7 +52,6 @@ INSTALLED_APPS = [
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
......@@ -145,12 +145,14 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
ASGI_APPLICATION = 'vue_django.asgi.application'
MQTT_SERVER = '192.168.0.89'
# mqtt 设置
MQTT_SERVER = '192.168.0.176'
MQTT_PORT = 1883
MQTT_KEEPALIVE = 60
MQTT_USER = ""
MQTT_PASSWORD = ""
# channel 的 websocket 设置
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels.layers.InMemoryChannelLayer',
......@@ -175,5 +177,5 @@ CORS_ALLOW_HEADERS = [
'token'
]
CORS_ALLOWED_ORIGINS = [
"http://localhost:5173", # 您的前端应用地址
"http://127.0.0.1:5173", # 您的前端应用地址
]
......@@ -15,7 +15,7 @@ Including another URLconf
"""
from django.contrib import admin
from django.urls import path, include, re_path
from .views import index, test
from .views import index, test, upload, download
from django.conf import settings
from django.views.static import serve
......@@ -35,11 +35,14 @@ schema_view = get_schema_view(
urlpatterns = [
path('admin/', admin.site.urls),
path("", index),
# path("test/", test),
path("test/upload/", upload),
path("test/download/", download),
path("mqtt/", include("mqtt.urls")),
path("chat/", include("chat.urls")),
path("op/", include("device_data_op.urls")),
path("api/", include("download_db.urls")),
path("api/", include("protocol_version_manage.urls")),
path("api/", include("device_communication.urls")),
re_path(r'^assets/(?P<path>.*)/$', serve, {'document_root': settings.STATIC_ROOT}),
......
import os
import urllib.parse
from django.conf import settings
from django.http import FileResponse
from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework.decorators import api_view, parser_classes
from rest_framework.response import Response
from rest_framework.parsers import MultiPartParser
from rest_framework import status
def index(request):
......@@ -11,3 +19,41 @@ def index(request):
def test(request):
if request.method == 'GET':
return Response({"message": "Hello, World!"})
@api_view(['POST'])
@parser_classes([MultiPartParser])
def upload(request):
file_obj = request.FILES.get('file')
protocol_name = request.data.get('protocol_name')
version = request.data.get('version')
print(protocol_name)
print(version)
print(file_obj.name)
folder_path = os.path.join(settings.BASE_DIR, 'protocol_raw_files', protocol_name, version)
if not os.path.exists(folder_path):
os.makedirs(folder_path)
with open(f'./protocol_raw_files/{protocol_name}/{version}/{file_obj.name}', 'wb+') as destination:
for chunk in file_obj.chunks():
destination.write(chunk)
return Response(status=status.HTTP_200_OK)
@api_view(['GET'])
def download(request):
protocol_name = request.GET.get('protocol_name')
version = request.GET.get('version')
file_path = os.path.join(settings.BASE_DIR, 'protocol_raw_files', protocol_name, version)
for root, _, files in os.walk(file_path):
file_path = os.path.join(root, files[1])
# 适配中文
file_name = urllib.parse.quote(os.path.basename(file_path))
response = FileResponse(open(file_path, 'rb'))
response['Content-Disposition'] = 'inline; filename=' + file_name
response['Content-Type'] = 'multipart/form-data'
response['filename'] = file_name
return response
return Response(status=status.HTTP_200_OK)
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