Files
mht-siemens/solution/client/plc_client.py
T
2026-06-23 18:22:14 +02:00

155 lines
6.2 KiB
Python

import snap7
import struct
import time
import os
# Configurazione PLC
PLC_IP = '192.168.124.43'
RACK = 0
SLOT = 2
# Codici Colore ANSI
GREEN = "\033[92m"
RED = "\033[91m"
RESET = "\033[0m"
class SiemensClient:
def __init__(self, ip, rack, slot):
self.client = snap7.client.Client()
self.rack = rack
self.slot = slot
self.ip = ip
def connect(self):
try:
self.client.connect(self.ip, self.rack, self.slot)
print(f"Connesso a {self.ip}")
return True
except Exception as e:
print(f"Errore di connessione: {e}")
return False
def read_db100(self):
data = self.client.db_read(100, 0, 192)
status_bytes = data[0:4]
acquisizione = (status_bytes[0] & 0x01) != 0
pronti = (status_bytes[1] & 0x80) != 0
params = {}
params['x_iniziale'] = struct.unpack('>f', data[4:8])[0]
params['x_finale'] = struct.unpack('>f', data[8:12])[0]
params['limite_sup'] = struct.unpack('>f', data[12:16])[0]
params['limite_inf'] = struct.unpack('>f', data[16:20])[0]
params['tipo_lettura'] = struct.unpack('>f', data[20:24])[0]
params['conteggio'] = struct.unpack('>f', data[24:28])[0]
params['param_arco'] = struct.unpack('>f', data[28:32])[0]
params['param_extra1'] = struct.unpack('>f', data[32:36])[0]
params['param_extra2'] = struct.unpack('>f', data[36:40])[0]
params['param_extra3'] = struct.unpack('>f', data[40:44])[0]
params['x_live'] = struct.unpack('>f', data[56:60])[0]
params['y_live'] = struct.unpack('>f', data[60:64])[0]
def parse_s7_string(raw_data):
if len(raw_data) < 2: return ""
length = struct.unpack('<H', raw_data[:2])[0]
content = raw_data[2:2+length]
return content.decode('ascii', errors='replace').replace('\x00', ' ').strip()
strings = {
"Comm": parse_s7_string(data[64:96]),
"Art": parse_s7_string(data[96:128]),
"IdCont": parse_s7_string(data[128:160]),
"Altro": parse_s7_string(data[160:192])
}
return {
"status": {"acquisizione": acquisizione, "pronti": pronti},
"params": params,
"strings": strings
}
def read_db101(self):
try:
data = self.client.db_read(101, 0, 160)
values = struct.unpack('>40f', data)
return values
except Exception as e:
print(f"Errore lettura DB101: {e}")
return None
def disconnect(self):
self.client.disconnect()
def clear_screen():
os.system('cls' if os.name == 'nt' else 'clear')
if __name__ == "__main__":
plc = SiemensClient(PLC_IP, RACK, SLOT)
if plc.connect():
try:
while True:
clear_screen()
db100_data = plc.read_db100()
print("=" * 60)
print(f" PLC MONITOR - {PLC_IP} ")
print("=" * 60)
print(f" STATO: Acquisizione={db100_data['status']['acquisizione']} | Pronti={db100_data['status']['pronti']}")
print("-" * 60)
print(f" VALORI LIVE:")
print(f" X_Live (DBD56): {db100_data['params']['x_live']:>10.4f}")
print(f" Y_Live (DBD60): {db100_data['params']['y_live']:>10.4f}")
print("-" * 60)
print(f" DATI STRINGHE:")
print(f" Commessa: {db100_data['strings']['Comm']}")
print(f" Articolo: {db100_data['strings']['Art']}")
print(f" IdCont: {db100_data['strings']['IdCont']}")
print(f" Altro: {db100_data['strings']['Altro']}")
print("-" * 60)
# Gestione DB101 con grafico a barre centrato
db101_raw = plc.read_db101()
if db101_raw:
# Prendi i primi 20 valori
data_subset = db101_raw[:20]
print(f" VISUALIZZAZIONE DB101 (Primi 20):")
if data_subset:
# Scala fissa basata sui tuoi dati (-2..+2)
scale_max = 2.0
for i, val in enumerate(data_subset):
# Calcola larghezza barra (max 15 caratteri per lato del centro)
bar_len = int((abs(val) / scale_max) * 15)
bar_len = min(bar_len, 15)
bar = "" * bar_len
if val > 0:
# Cresce verso destra: [ |███████████████]
# Padding a sinistra, barra a destra del |
left_side = "-" * 15
right_side = bar + "-" * (15 - bar_len)
color = GREEN
line = f" [{i+1:02d}] {left_side}|{color}{right_side}{RESET} {val:>8.4f}"
elif val < 0:
# Cresce verso sinistra: [███████████████--| ] -> WRONG
# DEVE ESSERE: [-------█████████████| ] -> CORRETTO
# Padding a sinistra, barra a sinistra del |
left_side = "-" * (15 - bar_len) + bar
right_side = "-" * 15
color = RED
line = f" [{i+1:02d}] {color}{left_side}{RESET}|{right_side} {val:>8.4f}"
else:
# Valore zero: [ | ]
line = f" [{i+1:02d}] {'-' * 15}|{'-' * 15} {val:>8.4f}"
print(line)
print("-" * 60)
time.sleep(0.5)
except KeyboardInterrupt:
print("\nInterruzione utente.")
finally:
plc.disconnect()