'''
Create a Modbus TCP server (slave) which can be requested for data or set with
specific values by a host device.
'''
# system packages
import time
import network
# import modbus server classes
from tcp import ModbusTCP
# ===============================================
# connect to a network
station = network.WLAN(network.STA_IF)
if station.active() and station.isconnected():
station.disconnect()
time.sleep(1)
station.active(False)
time.sleep(1)
station.active(True)
# station.connect('SSID', 'PASSWORD')
station.connect('Wokwi-GUEST', '')
time.sleep(1)
while True:
print('Waiting for WiFi connection...')
if station.isconnected():
print('Connected to WiFi.')
print(station.ifconfig())
break
time.sleep(2)
# ===============================================
# TCP Slave setup
tcp_port = 502
local_ip = station.ifconfig()[0]
# ModbusTCP can get TCP requests from a client device to provide/set data
server = ModbusTCP()
# check whether server has been bound to an IP and port
is_bound = server.get_bound_status()
if not is_bound:
server.bind(local_ip=local_ip, local_port=tcp_port)
letras = ["B", "C", "D", "E"]
max_len = 5 # max length of any register sub-group
# define register values as a dictionary
register_definitions = {
"COILS": {
0: {
"register": 0,
"val": [0, 0, 0],
"key": ["PM", "PP", "PA"]
},
max_len: {
"register": max_len,
"val": [0],
"key": ["Set Receta"]
}
},
"HREGS": {
0: {
"register": 0,
"val": [2, 3, 4, 5],
"key": [f"Receta Tipo {letra}" for letra in letras]
},
max_len: {
"register": max_len,
"val": [4, 3, 2, 1],
"key": [f"Receta Numero {letra}" for letra in letras]
}
},
"ISTS": {
0: {
"register": 0,
"val": [0, 0],
"key": ["Marcha", "Emerge"]
}
},
"IREGS": {
0: {
"register": 0,
"val": [2, 2, 2, 2],
"key": [f"Receta Tipo {letra}" for letra in letras]
},
max_len: {
"register": max_len,
"val": [1, 1, 1, 1],
"key": [f"Receta Numero {letra}" for letra in letras]
}
}
}
print('Setting up registers ...')
# use the defined values of each register type provided by register_definitions
server.setup_registers(register_definitions)
print('Register setup done')
print('Serving as TCP server on {}:{}'.format(local_ip, tcp_port))
# Show registers
def show_regs():
print("> Reading REGISTERS...")
reg_dic = server._register_dict
print(reg_dic)
for reg_type in reg_dic:
print(f"> Showing {reg_type}...")
reg_def = register_definitions[reg_type]
for addr, item in reg_dic[reg_type].items():
init_addr = max_len * (addr // max_len)
index = addr - init_addr
val = item["val"]
key = reg_def[init_addr]["key"][index]
print(f"{key}: {val}")
# Show modified registers
def show_mod_regs():
reg_dic = server._register_dict
mod_regs = {}
for reg_type in reg_dic:
reg_def = register_definitions[reg_type]
for addr, item in reg_dic[reg_type].items():
init_addr = max_len * (addr // max_len)
index = addr - init_addr
group = reg_def[init_addr]
val = item["val"]
if group["val"][index] != val:
group["val"] = val
key = group["key"][index]
mod_regs[reg_type] = m_r = {}
m_r[key] = val
if mod_regs:
print(mod_regs)
show_regs()
# Modificar algunos registros una vez
print(server._register_dict["ISTS"][0]["val"])
# server._register_dict["ISTS"][0]["val"] = 1
show_mod_regs()
while True:
try:
server.process()
# show_mod_regs()
except KeyboardInterrupt:
print('KeyboardInterrupt, stopping TCP server...')
break
except Exception as e:
print('Exception during execution: {}'.format(e))
print("Finished providing/accepting data as server")