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.

298 lines
11 KiB
Python

2 years ago
import collections
2 years ago
import json
from utils.DBModels.DeviceModels import DeviceDB
2 years ago
from model.ProjectModel.AreaManage import Area
import numpy as np
2 years ago
from protocol.ModBus.ByteOrder import *
2 years ago
from protocol.ModBus.TCPMaster import *
2 years ago
import struct
2 years ago
2 years ago
#从站 "AI" "DI"可强制
#主站 "AO" "DO"可强制
2 years ago
class Device():
2 years ago
inputStartAddress = None
inputEndAddress = None
outputStartAddress = None
outputEndAddress = None
2 years ago
protocolType = None
masterOrSlave = None
2 years ago
deviceName = None
2 years ago
def __init__(self):
2 years ago
self.inputAreas = []
self.outputAreas = []
2 years ago
2 years ago
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)
2 years ago
area.nums = nums
2 years ago
if type in ["AI", "DI"]:
area.startAddress = 0 if not self.inputEndAddress else self.inputEndAddress + 1
2 years ago
area.endAddress = area.startAddress + area.length
2 years ago
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)
2 years ago
# print(self.inputAreas)
2 years ago
# print(area.addressList, area.startAddress, area.endAddress, self.outputAreas)
2 years ago
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()
2 years ago
2 years ago
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:
2 years ago
area.startAddress = areas[index - 1].endAddress + 1
2 years ago
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
2 years ago
endAddress = 0
2 years ago
2 years ago
def editArea(self, index, type, order, bytes):
2 years ago
if type in ["DI", "AI"]:
2 years ago
self.inputAreas[index].type = type
2 years ago
self.inputAreas[index].order = order
self.inputAreas[index].bytes = bytes
elif type in ["AO", "DO"]:
2 years ago
self.outputAreas[index].type = type
2 years ago
self.outputAreas[index].order = order
self.outputAreas[index].bytes = bytes
# self.recalculateAddress()
2 years ago
def getArea(self, index):
return self.areas[index]
def getLength(self, nums, bytes):
2 years ago
length = int(nums) * int(bytes)
2 years ago
# length = length / 2
return length - 1
2 years ago
2 years ago
2 years ago
2 years ago
@classmethod
2 years ago
def delAreas(self, deviceName, id):
2 years ago
jsonCon = json.loads(DeviceDB.getByName(deviceName=deviceName).areaJson)
2 years ago
jsonCon.pop(id)
2 years ago
if jsonCon == []:
areaJson = None
DeviceDB.update(areaJson=areaJson).where(DeviceDB.deviceName == deviceName).execute()
else:
2 years ago
for index, areajsonId in enumerate(jsonCon):
areajsonId["id"] = index + 1
2 years ago
areaJson = json.dumps(jsonCon)
2 years ago
2 years ago
DeviceDB.update(areaJson=areaJson).where(DeviceDB.deviceName == deviceName).execute()
2 years ago
@classmethod
2 years ago
def getAreaJson(self, deviceNames):
deviceName = deviceNames
jsonConsStr = DeviceDB.getByName(deviceName=deviceName).areaJson
if jsonConsStr is None:
return
else:
jsonCons = json.loads(jsonConsStr)
return jsonCons
2 years ago
2 years ago
class DevicesManange():
def __init__(self):
2 years ago
self.dpMasterDevices = collections.OrderedDict()
self.dpSlaveDevices = collections.OrderedDict() # 有序字典 (OrderedDict)
self.paMasterDevices = collections.OrderedDict()
self.paSlaveDevices = collections.OrderedDict()
2 years ago
self.dpSlaveModbus = TcpMaster(host = '192.168.2.10', port = 502)
self.paSlaveModbus = TcpMaster(host = '192.168.4.10', port = 502)
2 years ago
2 years ago
2 years ago
def addDevice(self, proType, masterSlaveModel, deviceName):
device = Device()
device.type = proType
2 years ago
device.masterOrSlave = masterSlaveModel
2 years ago
device.deviceName = deviceName
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:
2 years ago
device.inputStartAddress = 0
device.outputStartAddress = 0
2 years ago
else:
2 years ago
device.inputStartAddress = list(curProDict.values())[-1].inputEndAddress + 1
device.outputStartAddress = list(curProDict.values())[-1].outputEndAddress + 1
2 years ago
curProDict[deviceName] = device
2 years ago
2 years ago
def initDevices(self):
pass
2 years ago
def delDevice(self, deviceName):
2 years ago
for devicesDict in [self.paMasterDevices, self.paSlaveDevices, self.dpMasterDevices, self.dpSlaveDevices]:
if deviceName in devicesDict:
2 years ago
del devicesDict[deviceName]
2 years ago
self.recalculateAddress()
2 years ago
def recalculateAddress(self):
for devicesDict in [self.paMasterDevices, self.paSlaveDevices, self.dpMasterDevices, self.dpSlaveDevices]:
for index, (deviceName, device) in enumerate(devicesDict.items()):
2 years ago
device.inputStartAddress = 0 if index == 0 else list(devicesDict.values())[index - 1].inputEndAddress + 1
device.outputStartAddress = 0 if index == 0 else list(devicesDict.values())[index - 1].outputEndAddress + 1
2 years ago
device.recalculateAddress()
2 years ago
# previousDevice = device
2 years ago
def getDevice(self, deviceName):
for devicesDict in [self.paMasterDevices, self.paSlaveDevices, self.dpMasterDevices, self.dpSlaveDevices]:
if deviceName in devicesDict:
return devicesDict[deviceName]
2 years ago
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
2 years ago
modbusM = self.dpSlaveModbus
2 years ago
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
2 years ago
modbusM = self.paSlaveModbus
2 years ago
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:
2 years ago
# print(area.type)
2 years ago
if area.type in ["AI", "AO"]:
2 years ago
byte = floatToBytes(area.forceValue, area.bytes, order = area.order)
2 years ago
elif area.type in ["DI", "DO"]:
2 years ago
if device.type == "PA" and device.masterOrSlave == "从站" and len(area.forceValue) == 16:
area.forceValue = area.forceValue[8:] + area.forceValue[:8]
byte = coilsToBytes([int(x) for x in area.forceValue], area.bytes)
bytes += byte
else:
if len(bytes) % 2 != 0:
bytes += struct.pack('B', 0)
values = struct.unpack('!' + 'H' * int(len(bytes) / 2), bytes)
modbusM.writeMultipleRegister(slaveId = 1, address = 0, outputValue = values)
# print(struct.unpack('>f', struct.pack('!HH', *values[:2])))
2 years ago
2 years ago
@classmethod
2 years ago
def addAreas(self, type, order, bytes, deviceName):
2 years ago
if DeviceDB.getByName(deviceName=deviceName).areaJson is None:
jsonCon = ([{
"id": 1,
"type": type,
2 years ago
"order": order,
2 years ago
"bytes": bytes,
2 years ago
2 years ago
}])
else:
jsonCon = json.loads(DeviceDB.getByName(deviceName=deviceName).areaJson)
id = jsonCon[-1]["id"] + 1
jsonCon.append({
"id": id,
"type": type,
2 years ago
"order": order,
2 years ago
"bytes": bytes,
})
areaJson = json.dumps(jsonCon)
DeviceDB.update(areaJson=areaJson).where(DeviceDB.deviceName == deviceName).execute()
2 years ago
2 years ago
@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()
2 years ago
@classmethod
def getAreaID(self, deviceNames):
deviceName = deviceNames
jsonConsStr = DeviceDB.getByName(deviceName=deviceName).areaJson
if jsonConsStr is None:
2 years ago
return
else:
2 years ago
jsonCons = json.loads(jsonConsStr)
id = []
for jsonCon in jsonCons:
id.append(jsonCon["id"])
return id
2 years ago
2 years ago
@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
2 years ago
def editDevies(self):
pass
2 years ago
@classmethod
2 years ago
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])
2 years ago
return l