You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
290 lines
10 KiB
Python
290 lines
10 KiB
Python
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
|
|
|