Added tracking lost script for LYS8 PLC's
This commit is contained in:
240
Scripts/LYS8_Tracking_Statistics.py
Normal file
240
Scripts/LYS8_Tracking_Statistics.py
Normal file
@@ -0,0 +1,240 @@
|
||||
#region Parameters
|
||||
plcs = {
|
||||
'PLC020': {
|
||||
'ip': '10.210.52.33',
|
||||
'port': 4840
|
||||
},
|
||||
'PLC030': {
|
||||
'ip': '10.210.52.51',
|
||||
'port': 4840
|
||||
},
|
||||
'PLC040': {
|
||||
'ip': '10.210.52.69',
|
||||
'port': 4840
|
||||
},
|
||||
#'PLC050': {
|
||||
# 'ip': '10.210.52.87',
|
||||
# 'port': 4840
|
||||
#}
|
||||
}
|
||||
|
||||
global unitFields, unitTrackingDB, unitStatusDB
|
||||
unitFields = ['"UnitID"',
|
||||
'"EMID"',
|
||||
'"UniqueID"',
|
||||
'"Track_Type"',
|
||||
'"Track_Rec_Cnt"',
|
||||
'"Track_Lost_Cnt"',
|
||||
'"Track_Stray_Cnt"',
|
||||
'"Track_Tolerance"']
|
||||
unitTrackingDB = '"DBI_Tracking_Statistic"'
|
||||
unitStatusDB = '"DBI_Unit_Status"."Status_Units"'
|
||||
#endregion
|
||||
|
||||
#region Script
|
||||
from opcua import Client
|
||||
from opcua import ua
|
||||
import pandas as pd
|
||||
|
||||
class OPCUA:
|
||||
connected = False
|
||||
|
||||
def __init__(self, ip, port):
|
||||
self.ip = ip
|
||||
self.port = port
|
||||
self.client = Client(f"opc.tcp://{ip}:{port}")
|
||||
|
||||
# Set logger
|
||||
#self.logger = logging.getLogger('PLC')
|
||||
|
||||
# Set console
|
||||
#self.console = Console()
|
||||
|
||||
#def setLogLevel(self, level):
|
||||
# self.logger.setLevel(level)
|
||||
|
||||
def connect(self):
|
||||
try:
|
||||
self.client.connect()
|
||||
#self.logger.info(f'Connected to {self.ip}:{self.port} via OPC UA')
|
||||
print(f'Connected to {self.ip}:{self.port} via OPC UA')
|
||||
self.connected = True
|
||||
except Exception as e:
|
||||
#self.logger.error(f'Failed to connect -> {e}')
|
||||
print(f'Failed to connect -> {e}')
|
||||
|
||||
def disconnect(self):
|
||||
try:
|
||||
if self.connected:
|
||||
self.client.disconnect()
|
||||
self.connected = False
|
||||
#self.logger.info(f'Disconnected from {self.ip}:{self.port}')
|
||||
print(f'Disconnected from {self.ip}:{self.port}')
|
||||
except Exception as e:
|
||||
#self.logger.error(f'Failed to disconnect -> {e} via OPC UA')
|
||||
print(f'Failed to disconnect -> {e} via OPC UA')
|
||||
|
||||
def getOrderNumber(self):
|
||||
if self.connected:
|
||||
return self.getValue('ns=3;s=OrderNumber')
|
||||
return None
|
||||
|
||||
def getValue(self, tag):
|
||||
if self.connected:
|
||||
node = self.client.get_node('ns=3;s=' + tag)
|
||||
return node.get_value()
|
||||
return None
|
||||
|
||||
def getValues(self, tags):
|
||||
if self.connected:
|
||||
nodes = []
|
||||
for tag in tags:
|
||||
nodes.append(self.client.get_node('ns=3;s=' + tag))
|
||||
|
||||
return self.client.get_values(nodes)
|
||||
return None
|
||||
|
||||
def getWordBits(self, tag):
|
||||
if self.connected:
|
||||
node = self.client.get_node('ns=3;s=' + tag)
|
||||
value = node.get_value()
|
||||
return list(bin(value)[2:].zfill(16)[::-1])
|
||||
return [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
|
||||
def getDateTime(self, tag):
|
||||
if self.connected:
|
||||
node = self.client.get_node('ns=3;s=' + tag)
|
||||
raw = node.get_value()
|
||||
day = (hex(raw[2])[2:]).zfill(2)
|
||||
month = (hex(raw[1])[2:]).zfill(2)
|
||||
year = (hex(raw[0])[2:]).zfill(2)
|
||||
hour = (hex(raw[3])[2:]).zfill(2)
|
||||
minutes = (hex(raw[4])[2:]).zfill(2)
|
||||
seconds = (hex(raw[5])[2:]).zfill(2)
|
||||
|
||||
return f'{day}-{month}-{year} {hour}:{minutes}:{seconds}'
|
||||
return None
|
||||
|
||||
def setValue(self, tag, value):
|
||||
if self.connected:
|
||||
node = self.client.get_node('ns=3;s=' + tag)
|
||||
if type(value) == bool:
|
||||
node.set_value(ua.DataValue(ua.Variant(value, ua.VariantType.Boolean)))
|
||||
if type(value) == int:
|
||||
node.set_value(ua.DataValue(ua.Variant(value, ua.VariantType.Byte)))
|
||||
|
||||
def setByte(self, tag, value):
|
||||
if self.connected:
|
||||
node = self.client.get_node('ns=3;s=' + tag)
|
||||
node.set_value(ua.DataValue(ua.Variant(value, ua.VariantType.Byte)))
|
||||
|
||||
def getNodes(self, tag):
|
||||
if self.connected:
|
||||
node = self.client.get_node('ns=3;s=' + tag)
|
||||
return node.get_children()
|
||||
return None
|
||||
|
||||
def csvdata_to_dataframe(data, separator=','):
|
||||
return pd.DataFrame([x.split(separator) for x in data.split('\n')])
|
||||
|
||||
def read_plc(name, ip, port=4840):
|
||||
global dataset, unitFields, unitTrackingDB, unitStatusDB
|
||||
|
||||
# Verify input parameters
|
||||
if unitFields is None or unitTrackingDB is None or unitStatusDB is None:
|
||||
print("Missing parameters")
|
||||
return
|
||||
|
||||
if name is None or ip is None or port is None:
|
||||
print("Missing PLC parameters")
|
||||
return
|
||||
|
||||
# Setup OPC UA connection
|
||||
opcPlc = OPCUA(ip, port)
|
||||
opcPlc.connect()
|
||||
|
||||
if opcPlc.connected == False:
|
||||
return
|
||||
|
||||
try:
|
||||
units = []
|
||||
Unit_Name = []
|
||||
Unit_ID = []
|
||||
EM_ID = []
|
||||
UniqueID = []
|
||||
Track_Type = []
|
||||
Track_Rec_Cnt = []
|
||||
Track_Lost_Cnt = []
|
||||
Track_Stray_Cnt = []
|
||||
Track_Tolerance = []
|
||||
|
||||
# Get all units
|
||||
for node in opcPlc.getNodes(unitTrackingDB):
|
||||
unitName = node.nodeid.Identifier.split('.')[-1]
|
||||
if not unitName in ['"Header"', '"header"', '"top_10"', '"Top_10"', '"top10"', '"Top10"']:
|
||||
units.append(unitName)
|
||||
|
||||
# Get data from PLC
|
||||
for unit in units:
|
||||
nodes = []
|
||||
unit_nr = int(unit.split('_')[1])
|
||||
|
||||
# Create node list
|
||||
nodes.append(f'{unitStatusDB}[{unit_nr}]."Unit_Name"')
|
||||
for field in unitFields:
|
||||
nodes.append(f'{unitTrackingDB}.{unit}.{field}')
|
||||
|
||||
# Get values
|
||||
values = opcPlc.getValues(nodes)
|
||||
|
||||
# Sort values
|
||||
Unit_Name.append(str(values[0]).replace('"',''))
|
||||
Unit_ID.append(str(values[1]).replace('"',''))
|
||||
EM_ID.append(str(values[2]).replace('"',''))
|
||||
UniqueID.append(str(values[3]).replace('"',''))
|
||||
Track_Type.append(str(values[4]).replace('"',''))
|
||||
Track_Rec_Cnt.append(str(values[5]).replace('"',''))
|
||||
Track_Lost_Cnt.append(str(values[6]).replace('"',''))
|
||||
Track_Stray_Cnt.append(str(values[7]).replace('"',''))
|
||||
Track_Tolerance.append(str(values[8]).replace('"',''))
|
||||
|
||||
# Create table with all data
|
||||
table = {
|
||||
'PLC_Name': name,
|
||||
'Unit_Name': Unit_Name,
|
||||
'Unit_ID': Unit_ID,
|
||||
'EMID': EM_ID,
|
||||
'UniqueID': UniqueID,
|
||||
'Track_Type': Track_Type,
|
||||
'Track_Rec_Cnt': Track_Rec_Cnt,
|
||||
'Track_Lost_Cnt': Track_Lost_Cnt,
|
||||
'Track_Stray_Cnt': Track_Stray_Cnt,
|
||||
'Track_Tolerance': Track_Tolerance
|
||||
}
|
||||
|
||||
# Write data to CSV
|
||||
pd.DataFrame(table).to_csv(f'{name}.csv')
|
||||
|
||||
# Add raw data to dataset
|
||||
with open(f'{name}.csv') as f:
|
||||
dataset += f.read()
|
||||
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
finally:
|
||||
opcPlc.disconnect()
|
||||
|
||||
if __name__ == "__main__":
|
||||
global dataset
|
||||
dataset = ''
|
||||
|
||||
for plcName in plcs:
|
||||
ip = plcs[plcName]['ip']
|
||||
port = plcs[plcName]['port']
|
||||
read_plc(plcName, ip, port)
|
||||
|
||||
# convert data to dataframe
|
||||
df = csvdata_to_dataframe(dataset)
|
||||
|
||||
|
||||
#endregion
|
||||
Reference in New Issue
Block a user