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

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