import collections 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 = [] inputStartAddress = None inputEndAddress = None outputStartAddress = None outputEndAddress = None protocolType = None masterOrSlave = None deviceName = None def __init__(self): pass def addArea(self, type, nums, bytes, order = 'ABCD'): area = Area() bytes = int(bytes) area.type = type 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 self.inputEndAddress = area.endAddress area.addressList = np.arange(area.startAddress, area.endAddress + 1, area.bytes).tolist() self.inputAreas.append(area) elif type in ["DO" , "AO"]: area.startAddress = 0 if not self.outputEndAddress else self.outputEndAddress + 1 area.endAddress = area.startAddress + area.length self.outputEndAddress = area.endAddress area.addressList = np.arange(area.startAddress, area.endAddress + 1, area.bytes).tolist() self.outputAreas.append(area) print(area.addressList, area.startAddress, self.inputEndAddress) def delArea(self, index, type): if type in ["DI", "AI"]: self.inputAreas.pop(index) elif type in ["AO", "DO"]: self.outputAreas.pop(index) # self.recalculateAddress() def recalculateAddress(self): endAddress = 0 for inputOrOutput, areas in enumerate([self.inputAreas, self.outputAreas]): for index, area in enumerate(areas): if index == 0 and inputOrOutput == 0: area.startAddress = self.inputStartAddress elif index == 0 and inputOrOutput == 1: area.startAddress = self.outputStartAddress else: area.startAddress = areas[index - 1].endAddress area.endAddress = area.startAddress + area.length area.addressList = np.arange(area.startAddress, area.endAddress + 1, area.bytes).tolist() endAddress = area.endAddress else: if inputOrOutput == 0: self.inputEndAddress = endAddress elif inputOrOutput == 1: self.outputEndAddress = endAddress def editArea(self, index, type, order, bytes): if type in ["DI", "AI"]: self.inputAreas[index].type = type self.inputAreas[index].order = order self.inputAreas[index].bytes = bytes elif type in ["AO", "DO"]: self.outputAreas[index].type = type self.outputAreas[index].order = order self.outputAreas[index].bytes = bytes # self.recalculateAddress() def getArea(self, index): return self.areas[index] def getLength(self, nums, bytes): length = int(nums) * int(bytes) length = length / 2 return length @classmethod def delAreas(self, deviceName, id): jsonCon = json.loads(DeviceDB.getByName(deviceName=deviceName).areaJson) jsonCon.pop(id) if jsonCon == []: areaJson = None DeviceDB.update(areaJson=areaJson).where(DeviceDB.deviceName == deviceName).execute() else: for index, areajsonId in enumerate(jsonCon): areajsonId["id"] = index + 1 areaJson = json.dumps(jsonCon) DeviceDB.update(areaJson=areaJson).where(DeviceDB.deviceName == deviceName).execute() @classmethod def getAreaJson(self, deviceNames): deviceName = deviceNames jsonConsStr = DeviceDB.getByName(deviceName=deviceName).areaJson if jsonConsStr is None: return else: jsonCons = json.loads(jsonConsStr) return jsonCons class DevicesManange(): def __init__(self): self.dpMasterDevices = collections.OrderedDict() self.dpSlaveDevices = collections.OrderedDict() # 有序字典 (OrderedDict) self.paMasterDevices = collections.OrderedDict() self.paSlaveDevices = collections.OrderedDict() def addDevice(self, proType, masterSlaveModel, deviceName): device = Device() device.type = proType device.masterOrSlave = masterSlaveModel device.deviceName = deviceName masterSlaveModel = masterSlaveModel if proType == "DP" and masterSlaveModel == "主站": curProDict = self.dpMasterDevices elif proType == "DP" and masterSlaveModel == "从站": curProDict = self.dpSlaveDevices elif proType == "PA" and masterSlaveModel == "主站": curProDict = self.paMasterDevices elif proType == "PA" and masterSlaveModel == "从站": curProDict = self.paSlaveDevices if len(curProDict) == 0: device.inputStartAddress = 0 device.outputStartAddress = 0 else: device.inputStartAddress = curProDict.values[-1].inputEndAddress + 1 device.outputStartAddress = curProDict.values[-1].outputEndAddress + 1 curProDict[deviceName] = device def initDevices(self): pass def delDevice(self, deviceName): for devicesDict in [self.paMasterDevices, self.paSlaveDevices, self.dpMasterDevices, self.dpSlaveDevices]: if deviceName in devicesDict: del devicesDict[deviceName] self.recalculateAddress() def recalculateAddress(self): for devicesDict in [self.paMasterDevices, self.paSlaveDevices, self.dpMasterDevices, self.dpSlaveDevices]: for index, (deviceName, device) in enumerate(devicesDict.items()): device.startAddress = 0 if index == 0 else previousDevice.endAddress + 1 device.recalculateAddress() previousDevice = device def getDevice(self, deviceName): 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): if DeviceDB.getByName(deviceName=deviceName).areaJson is None: jsonCon = ([{ "id": 1, "type": type, "order": order, "bytes": bytes, }]) else: jsonCon = json.loads(DeviceDB.getByName(deviceName=deviceName).areaJson) id = jsonCon[-1]["id"] + 1 jsonCon.append({ "id": id, "type": type, "order": order, "bytes": bytes, }) areaJson = json.dumps(jsonCon) DeviceDB.update(areaJson=areaJson).where(DeviceDB.deviceName == deviceName).execute() @classmethod def updataAreas(self, type, order, bytes, deviceName, index): if DeviceDB.getByName(deviceName=deviceName) is None: return False else: jsonCon = json.loads(DeviceDB.getByName(deviceName=deviceName).areaJson) for area in jsonCon: if index == area["id"]: area["type"] = type area["order"] = order area["bytes"] = bytes areaJson = json.dumps(jsonCon) DeviceDB.update(areaJson=areaJson).where(DeviceDB.deviceName == deviceName).execute() @classmethod def getAreaID(self, deviceNames): deviceName = deviceNames jsonConsStr = DeviceDB.getByName(deviceName=deviceName).areaJson if jsonConsStr is None: return else: jsonCons = json.loads(jsonConsStr) id = [] for jsonCon in jsonCons: id.append(jsonCon["id"]) return id @classmethod def getChannelLength(self, deviceName): number = 0 if DeviceDB.getByName(deviceName=deviceName).areaJson is None: return number else: numbers = json.loads(DeviceDB.getByName(deviceName=deviceName).areaJson) for i in numbers: number += int(i['nums']) return number def editDevies(self): pass @classmethod def getAllDevice(self): # 查询所有设备 devices = DeviceDB.get_all() if devices is 'error': return l = [] for x in devices: l.append([x.deviceName, x.proType, x.masterSlaveModel, x.areaJson]) return l