-
Notifications
You must be signed in to change notification settings - Fork 216
Description
Hello,
I am finding an issue, where, my master, on the startup, creates the network, adds the node, etc. and then, when I pass from INITIALIZING, to PRE-OPERATIONAL state, the slave, doesnt begin the heartbeat. I've checked the nmt module, and it should do It, but the thing is that It does not.
def _startup(self, bms) -> None:
bms.nmt.state = 'PRE-OPERATIONAL'
time.sleep(1)
bms.nmt.state = 'OPERATIONAL'
time.sleep(1)
Here, i set the bms (slave), state to pre-operational. The sleep is because if not, or it does not set it, or im not able to print it on the slave. Adding the sleep, I can see that it sets it to PRE-OPERATIONAL. In fact, I see that it goes from initialized, to pre-operational, to operational.
However, the thing is that when I check if I recieve the heartbeat, in the next code snippet, well, i don't receive It. Seems like the start_heartbeat method doesn't launch.
def nmt_manager(self, bms) -> None:
"""Monitoriza el estado del BMS mediante heartbeats."""
logger.info("Iniciando monitorización de NMT (Heartbeat)...")
while True:
try:
# Esperar heartbeat (timeout un poco mayor que el intervalo esperado de 1s)
bms.nmt.wait_for_heartbeat(timeout=2.0)
logger.info(f"Heartbeat recibido. Estado BMS: {bms.nmt.state}")
except Exception as e:
logger.warning(f"No se ha recibido heartbeat del BMS: {e}")
Also, the heartbeat doesn't start, if, when starting the slave (a bms simulator, on the same machine), I do this:
self.node = canopen.LocalNode(self.BMS_NODE_ID, self.DICT_EDS)
# Forzar el intervalo de heartbeat a 1000ms (1s) directamente
self.set_value(0x1017, 1, 500, "Intervalo de heartbeat")
self.network.add_node(self.node)
I know, that the start_hearbeat method is launched, either on passing from INITIALIZED from PRE-OPERATIONAL, or, via writing the producer heartbeat time(1017h). And i know that the write is a callback, but, doesn't work if the writing it's made before the node added to the network?
To make the heartbeat work, I had to do this:
def _startup(self, bms) -> None:
bms.nmt.state = 'PRE-OPERATIONAL'
time.sleep(1)
bms.sdo[0x1017].raw = 500
bms.nmt.state = 'OPERATIONAL'
time.sleep(1)
Adding the writing of the record 1017 on startup.
My setup is local, using vcan on my own linux. But can virtual channel seems to work perfectly fine.
Writing this because I don't know if it's a bug, or I am wrong somewhere.