Commit 444d7d510ea2b7cee7b55eb7c38fdfda1be490c5

Authored by xp.Huang
2 parents 4cdd65c6 968d7ba7

Merge branch 'perf/attribute-distribution' into 'main_dev'

Perf: 修改设备物模型数据自定义和ModBUS属性下发方式

See merge request yunteng/thingskit-front!781
@@ -166,6 +166,7 @@ export interface DeviceRecord { @@ -166,6 +166,7 @@ export interface DeviceRecord {
166 id: string; 166 id: string;
167 creator: string; 167 creator: string;
168 createTime: string; 168 createTime: string;
  169 + codeType?: string;
169 name: string; 170 name: string;
170 tenantId: string; 171 tenantId: string;
171 transportType: string; 172 transportType: string;
@@ -199,6 +200,8 @@ export interface DeviceModelOfMatterAttrs { @@ -199,6 +200,8 @@ export interface DeviceModelOfMatterAttrs {
199 identifier: string; 200 identifier: string;
200 accessMode: string; 201 accessMode: string;
201 detail: StructJSON; 202 detail: StructJSON;
  203 + deviceDetail?: DeviceRecord;
  204 + extensionDesc?: any;
202 } 205 }
203 206
204 export interface DeviceStateLogModel { 207 export interface DeviceStateLogModel {
@@ -238,7 +238,7 @@ @@ -238,7 +238,7 @@
238 const handleSendCommandModal = (data: DataSource) => { 238 const handleSendCommandModal = (data: DataSource) => {
239 openSendCommandModal(true, { 239 openSendCommandModal(true, {
240 mode: DataActionModeEnum.READ, 240 mode: DataActionModeEnum.READ,
241 - record: { ...toRaw(data.detail) }, 241 + record: { ...toRaw(data.detail), deviceDetail: props.deviceDetail as any },
242 } as ModalParamsType); 242 } as ModalParamsType);
243 }; 243 };
244 244
  1 +import { FormSchema } from '/@/components/Form';
  2 +
  3 +const InsertString = (t, c, n) => {
  4 + const r: string | number[] = [];
  5 +
  6 + for (let i = 0; i * 2 < t.length; i++) {
  7 + r.push(t.substr(i * 2, n));
  8 + }
  9 + return r.join(c);
  10 +};
  11 +const FillString = (t, c, n, b) => {
  12 + if (t == '' || c.length != 1 || n <= t.length) {
  13 + return t;
  14 + }
  15 + const l = t.length;
  16 +
  17 + for (let i = 0; i < n - l; i++) {
  18 + if (b == true) {
  19 + t = c + t;
  20 + } else {
  21 + t += c;
  22 + }
  23 + }
  24 + return t;
  25 +};
  26 +const SingleToHex = (t) => {
  27 + if (t == '') {
  28 + return '';
  29 + }
  30 + t = parseFloat(t);
  31 +
  32 + if (isNaN(t) == true) {
  33 + return 'Error';
  34 + }
  35 + if (t == 0) {
  36 + return '00000000';
  37 + }
  38 + let s, e, m;
  39 +
  40 + if (t > 0) {
  41 + s = 0;
  42 + } else {
  43 + s = 1;
  44 +
  45 + t = 0 - t;
  46 + }
  47 + m = t.toString(2);
  48 +
  49 + if (m >= 1) {
  50 + if (m.indexOf('.') == -1) {
  51 + m = m + '.0';
  52 + }
  53 + e = m.indexOf('.') - 1;
  54 + } else {
  55 + e = 1 - m.indexOf('1');
  56 + }
  57 + if (e >= 0) {
  58 + m = m.replace('.', '');
  59 + } else {
  60 + m = m.substring(m.indexOf('1'));
  61 + }
  62 + if (m.length > 24) {
  63 + m = m.substr(0, 24);
  64 + } else {
  65 + m = FillString(m, '0', 24, false);
  66 + }
  67 + m = m.substring(1);
  68 +
  69 + e = (e + 127).toString(2);
  70 +
  71 + e = FillString(e, '0', 8, true);
  72 +
  73 + let r = parseInt(s + e + m, 2).toString(16);
  74 +
  75 + r = FillString(r, '0', 8, true);
  76 +
  77 + return InsertString(r, ' ', 2).toUpperCase();
  78 +};
  79 +
  80 +const FormatHex = (t, n, ie) => {
  81 + const r: string[] = [];
  82 +
  83 + let s = '';
  84 +
  85 + let c = 0;
  86 +
  87 + for (let i = 0; i < t.length; i++) {
  88 + if (t.charAt(i) != ' ') {
  89 + s += t.charAt(i);
  90 +
  91 + c += 1;
  92 +
  93 + if (c == n) {
  94 + r.push(s);
  95 +
  96 + s = '';
  97 +
  98 + c = 0;
  99 + }
  100 + }
  101 + if (ie == false) {
  102 + if (i == t.length - 1 && s != '') {
  103 + r.push(s);
  104 + }
  105 + }
  106 + }
  107 + return r.join('\n');
  108 +};
  109 +const FormatHexBatch = (t, n, ie) => {
  110 + const a = t.split('\n');
  111 +
  112 + const r: string[] = [];
  113 +
  114 + for (let i = 0; i < a.length; i++) {
  115 + r[i] = FormatHex(a[i], n, ie);
  116 + }
  117 + return r.join('\n');
  118 +};
  119 +const SingleToHexBatch = (t) => {
  120 + const a = t.split('\n');
  121 +
  122 + const r: string[] = [];
  123 +
  124 + for (let i = 0; i < a.length; i++) {
  125 + r[i] = SingleToHex(a[i]);
  126 + }
  127 + return r.join('\r\n');
  128 +};
  129 +
  130 +const formSchemasConfig = (schemas, actionType): FormSchema[] => {
  131 + const { identifier, functionName } = schemas;
  132 + console.log(identifier, 'identifier', actionType, 'actionType');
  133 + if (actionType == '06') {
  134 + return [
  135 + {
  136 + field: identifier,
  137 + label: functionName,
  138 + component: 'InputNumber',
  139 + rules: [{ required: true, message: '请输入值' }],
  140 + componentProps: {
  141 + precision: 0,
  142 + placeholder: `请输入整数`,
  143 + },
  144 + },
  145 + ];
  146 + } else if (actionType == '05') {
  147 + return [
  148 + {
  149 + field: identifier,
  150 + label: functionName,
  151 + component: 'InputNumber',
  152 + rules: [{ required: true, message: '请输入值' }],
  153 + componentProps: {
  154 + min: 0,
  155 + max: 1,
  156 + precision: 0,
  157 + placeholder: `请输入0或1`,
  158 + },
  159 + },
  160 + ];
  161 + } else {
  162 + return [
  163 + {
  164 + field: identifier,
  165 + label: functionName,
  166 + component: 'InputNumber',
  167 + rules: [{ required: true, message: '请输入值' }],
  168 + componentProps: {
  169 + placeholder: `请输入值`,
  170 + formatter: (e) =>
  171 + `${e}`.replace(/\B(?=(\d{3})+(?!\d))/g, '').replace(/^(-)*(\d+)\.(\d\d).*$/, '$1$2.$3'),
  172 + },
  173 + },
  174 + ];
  175 + }
  176 +};
  177 +
  178 +export {
  179 + InsertString,
  180 + FillString,
  181 + SingleToHex,
  182 + FormatHex,
  183 + FormatHexBatch,
  184 + SingleToHexBatch,
  185 + formSchemasConfig,
  186 +};
@@ -10,6 +10,9 @@ @@ -10,6 +10,9 @@
10 import { sendCommandOneway } from '/@/api/dataBoard'; 10 import { sendCommandOneway } from '/@/api/dataBoard';
11 import { useMessage } from '/@/hooks/web/useMessage'; 11 import { useMessage } from '/@/hooks/web/useMessage';
12 import { unref } from 'vue'; 12 import { unref } from 'vue';
  13 + import { genModbusCommand } from '/@/api/task';
  14 + import { TaskTypeEnum } from '/@/views/task/center/config';
  15 + import { SingleToHex, formSchemasConfig } from './config';
13 16
14 defineEmits(['register']); 17 defineEmits(['register']);
15 const props = defineProps<{ deviceId: string; deviceName: string }>(); 18 const props = defineProps<{ deviceId: string; deviceName: string }>();
@@ -24,45 +27,93 @@ @@ -24,45 +27,93 @@
24 27
25 const keys = ref<string[]>([]); 28 const keys = ref<string[]>([]);
26 29
27 - const [register] = useModalInner((params: ModalParamsType<DeviceModelOfMatterAttrs>) => { 30 + const modBUSForm = ref<any>({});
  31 + const isShowModBUS = ref<Boolean>(false);
  32 + const formField = ref('');
  33 +
  34 + const [register] = useModalInner(async (params: ModalParamsType<DeviceModelOfMatterAttrs>) => {
28 const { record } = params; 35 const { record } = params;
29 - const { name, detail, identifier } = record; 36 + const { name, detail, identifier, deviceDetail, extensionDesc } = record;
30 const { dataType } = detail; 37 const { dataType } = detail;
31 const { type } = dataType || {}; 38 const { type } = dataType || {};
  39 + const { codeType } = deviceDetail || {};
  40 + const { registerAddress, actionType } = extensionDesc || {};
  41 + formField.value = identifier;
32 42
33 let schemas = [{ dataType: dataType, identifier, functionName: name } as StructJSON]; 43 let schemas = [{ dataType: dataType, identifier, functionName: name } as StructJSON];
34 44
35 if (type === DataTypeEnum.IS_STRUCT) { 45 if (type === DataTypeEnum.IS_STRUCT) {
36 schemas = dataType?.specs as StructJSON[]; 46 schemas = dataType?.specs as StructJSON[];
37 } 47 }
  48 + if (codeType == TaskTypeEnum.MODBUS) {
  49 + isShowModBUS.value = true;
  50 + modBUSForm.value = {
  51 + crc: 'CRC_16_LOWER',
  52 + deviceCode: '01',
  53 + method: actionType,
  54 + registerAddress,
  55 + registerNumber: 1,
  56 + registerValues: [],
  57 + };
  58 + setProps({ schemas: formSchemasConfig(schemas[0], actionType) });
  59 + } else {
  60 + isShowModBUS.value = false;
  61 + const formSchemas = genForm(schemas);
  62 + keys.value = schemas.map((item) => {
  63 + return item.identifier!;
  64 + });
  65 + setProps({ schemas: formSchemas });
  66 + }
38 67
39 - const formSchemas = genForm(schemas);  
40 -  
41 - keys.value = schemas.map((item) => {  
42 - return item.identifier!;  
43 - });  
44 - setProps({ schemas: formSchemas });  
45 resetFields(); 68 resetFields();
46 }); 69 });
47 70
  71 + const getArray = (values) => {
  72 + const str = values.replace(/\s+/g, '');
  73 + const array: any = [];
  74 +
  75 + for (let i = 0; i < str.length; i += 4) {
  76 + const chunk = parseInt(str.substring(i, i + 4), 16);
  77 + array.push(chunk);
  78 + }
  79 + return array;
  80 + };
  81 +
48 const { createMessage } = useMessage(); 82 const { createMessage } = useMessage();
49 const loading = ref(false); 83 const loading = ref(false);
50 const handleSend = async () => { 84 const handleSend = async () => {
51 try { 85 try {
52 loading.value = true; 86 loading.value = true;
53 if (!props.deviceId) return; 87 if (!props.deviceId) return;
54 - const _value = getFieldsValue();  
55 - const value = unref(keys).reduce((prev, next) => {  
56 - return { ...prev, [next]: _value[next] };  
57 - }, {}); 88 + const sendValue = ref({});
  89 + if (unref(isShowModBUS)) {
  90 + //判断tcp类型 标识符是自定义还是ModBus
  91 + const oldValue = getFieldsValue()[unref(formField)];
  92 + const newValue = getArray(SingleToHex(oldValue));
  93 +
  94 + modBUSForm.value.registerValues =
  95 + unref(modBUSForm).method != '16' ? [newValue[0]] : newValue;
  96 + modBUSForm.value.registerNumber = unref(modBUSForm).method != '16' ? 1 : 2;
  97 +
  98 + sendValue.value = await genModbusCommand(unref(modBUSForm));
  99 + } else {
  100 + const _value = getFieldsValue();
  101 +
  102 + sendValue.value = unref(keys).reduce((prev, next) => {
  103 + return { ...prev, [next]: _value[next] };
  104 + }, {});
  105 + }
  106 +
58 await sendCommandOneway({ 107 await sendCommandOneway({
59 deviceId: props.deviceId, 108 deviceId: props.deviceId,
60 value: { 109 value: {
61 persistent: true, 110 persistent: true,
62 method: 'methodThingskit', 111 method: 'methodThingskit',
63 - params: {  
64 - ...value,  
65 - }, 112 + params: unref(isShowModBUS)
  113 + ? unref(sendValue)
  114 + : {
  115 + ...unref(sendValue),
  116 + },
66 }, 117 },
67 }); 118 });
68 createMessage.success('属性下发成功~'); 119 createMessage.success('属性下发成功~');
@@ -69,7 +69,6 @@ @@ -69,7 +69,6 @@
69 return hexToDec(props.minValue); 69 return hexToDec(props.minValue);
70 } 70 }
71 } 71 }
72 -  
73 if (unref(inputType) === AddressTypeEnum.DEC) 72 if (unref(inputType) === AddressTypeEnum.DEC)
74 return `0x${decToHex(unref(getInputValue)!) 73 return `0x${decToHex(unref(getInputValue)!)
75 .toString() 74 .toString()