diff --git a/UI/AreaTabWidget.py b/UI/AreaTabWidget.py index 21db2cc..7fc44ce 100644 --- a/UI/AreaTabWidget.py +++ b/UI/AreaTabWidget.py @@ -96,7 +96,7 @@ class AreaTabWidget(QMainWindow): areas = json.loads(areas) area = areas[index] type = area["type"] - print(area, type,'ssss') + # print(area, type,'ssss') if index != -1: @@ -110,7 +110,7 @@ class AreaTabWidget(QMainWindow): def addAreaWidget(self, widgetList, loacl = True, init = False): dataType = widgetList[0].currentText() - print(widgetList) + # print(widgetList) order = self.dataTypeTranslate(widgetList[1].currentText()) byteLineEdit = widgetList[2].text() areaLayout = widgetList[3] @@ -226,7 +226,7 @@ class AreaTabWidget(QMainWindow): return self.dataTypeDict[order] def wirteValue(self, editBtn): - # deviceName = self.areaTabWidget.parent().parent().parent().parent().parent().windowTitle() + deviceName = self.areaTabWidget.parent().parent().parent().parent().parent().windowTitle() # index = self.areaTabWidget.currentIndex() valueList = [] @@ -237,7 +237,8 @@ class AreaTabWidget(QMainWindow): widgetList[0].setText(widgetList[1].text()) if isinstance(widgetList[1], QLineEdit): - valueList.append(int(widgetList[1].text())) + valueList.append(float(widgetList[1].text())) + self.mainwindow.devicesManange.writeAreas(deviceName = deviceName, values = valueList) diff --git a/model/ProjectModel/AreaManage.py b/model/ProjectModel/AreaManage.py index f5fe4a1..170a8ea 100644 --- a/model/ProjectModel/AreaManage.py +++ b/model/ProjectModel/AreaManage.py @@ -19,6 +19,8 @@ class Area(): type = None addressList = [] order = 'ABCD' + nums = None + forceValue = 0 def __init__(self): pass diff --git a/model/ProjectModel/DeviceManage.py b/model/ProjectModel/DeviceManage.py index 1b2e121..ef55b62 100644 --- a/model/ProjectModel/DeviceManage.py +++ b/model/ProjectModel/DeviceManage.py @@ -3,8 +3,11 @@ import json from utils.DBModels.DeviceModels import DeviceDB from model.ProjectModel.AreaManage import Area import numpy as np +from protocol.ModBus.ByteOrder import * +import struct - +#从站 "AI" "DI"可强制 +#主站 "AO" "DO"可强制 class Device(): inputAreas = [] outputAreas = [] @@ -25,6 +28,7 @@ class Device(): area.order = order area.bytes = bytes area.length = self.getLength(nums, bytes) + area.nums = nums if type in ["AI", "DI"]: area.startAddress = 0 if not self.inputEndAddress else self.inputEndAddress + 1 area.endAddress = area.startAddress + area.length @@ -88,8 +92,8 @@ class Device(): - def writeAreas(self): - pass + + @classmethod def delAreas(self, deviceName, id): @@ -131,7 +135,7 @@ class DevicesManange(): def addDevice(self, proType, masterSlaveModel, deviceName): device = Device() device.type = proType - device.masterSlaveModel = masterSlaveModel + device.masterOrSlave = masterSlaveModel device.deviceName = deviceName masterSlaveModel = masterSlaveModel @@ -173,6 +177,40 @@ class DevicesManange(): for devicesDict in [self.paMasterDevices, self.paSlaveDevices, self.dpMasterDevices, self.dpSlaveDevices]: if deviceName in devicesDict: return devicesDict[deviceName] + + def writeAreas(self, deviceName, values): + bytes = b"" + device = self.getDevice(deviceName) + if device.type == "DP" and device.masterOrSlave == "主站": + curProDict = self.dpMasterDevices + areas = device.outputAreas + elif device.type == "DP" and device.masterOrSlave == "从站": + curProDict = self.dpSlaveDevices + areas = device.inputAreas + elif device.type == "PA" and device.masterOrSlave == "主站": + areas = device.outputAreas + curProDict = self.paMasterDevices + elif device.type == "PA" and device.masterOrSlave == "从站": + areas = device.inputAreas + curProDict = self.paSlaveDevices + + for area, value in zip(areas, values): + area.forceValue = value + + for device in curProDict.values(): + forceAreas = device.outputAreas if device.masterOrSlave == "主站" else device.inputAreas + for area in forceAreas: + if area.type in ["AI", "AO"]: + byte = floatToBytes([area.forceValue], area.bytes, order = area.order) + elif area.type in ["DI", "DO"]: + byte = coilsToBytes([int(x) for x in [area.forceValue]], area.bytes) + order = '<'if order.byte in ['ABCD', 'DCBA'] else '>' + else: + if len(bytes) % 2 != 0: + bytes += struct.pack('b', 0) + + values = struct.pack('') + print(len(bytes)) @classmethod def addAreas(self, type, order, bytes, deviceName): diff --git a/protocol/ModBus/ByteOrder.py b/protocol/ModBus/ByteOrder.py index 8696fef..15e1d2a 100644 --- a/protocol/ModBus/ByteOrder.py +++ b/protocol/ModBus/ByteOrder.py @@ -1,5 +1,17 @@ import struct +def reorderBytes(byteStream, format): + if format == 'ABCD': + return byteStream + elif format == 'DCBA': + return byteStream[::-1] + elif format == 'BADC': + return bytes([byteStream[1], byteStream[0], byteStream[3], byteStream[2]]) + elif format == 'CDAB': + return bytes([byteStream[2], byteStream[3], byteStream[0], byteStream[1]]) + else: + raise ValueError("Invalid format") + # 大端模式 def floatToABCD(value): valueByte = struct.unpack('>HH',struct.pack('>f', value)) @@ -38,3 +50,33 @@ def BADCToFloat(value): def CDABToFloat(value): valueByte = struct.unpack('' + # 获取values的长度 + valuesNums = len(values) + # 将values转换为字节流 + valueByte = struct.pack(f"!{'f' * valuesNums}", *values) + valueByte = reorderBytes(valueByte, format = order) + print(ABCDToFloat(struct.unpack('!HH', valueByte))) +# {'B' * (length - 4 * valuesNums) *[0] * (length - 4 * valuesNums) + # 返回转换后的字节流 + # return valueByte + +def coilsToBytes(values, length): + decimalNumbers = [] + binaryNumber = ''.join([str(x) for x in list(reversed(values))]) + zeroNeeded = 0 if len(binaryNumber) % 8 == 0 else 8 - (len(binaryNumber) % 8) + binaryNumber = '0' * zeroNeeded + binaryNumber + for i in range(0, len(binaryNumber), 8): + eightValues = binaryNumber[i:i+8] + decimalNumbers.append(int(eightValues, 2)) + valueByte = struct.pack("B" * length, *decimalNumbers, *[0] * (length - len(decimalNumbers))) + return valueByte + +# print(coilsToBytes([1] * 2, 3)) +floatToBytes([3.14], 5, 'ABCD') + +