Gracias por todas estas pruebas, has encontrado varios problemas, y al menos uno es un error de nuestro lado. Lo reviso en orden.
1. La diferencia entre las dos acciones
En el código, Enviar un mensaje MQTT y Enviar un mensaje Zigbee2mqtt hacen exactamente lo mismo: tu texto pasa por el motor de variables y luego se publica tal cual. La única diferencia es el cliente MQTT utilizado: la acción MQTT publica en el broker configurado en el servicio MQTT, la acción Zigbee2mqtt publica en la conexión propia del servicio Zigbee2mqtt (por defecto el Mosquitto dedicado a Z2M, mqtt://localhost:1884).
Si tu Z2M funciona fuera de Gladys con tu propio broker, la acción Zigbee2mqtt se envía potencialmente al vacío: nadie escucha, y como el registro de publicación está en nivel debug, no ves nada en ninguna parte. No has perdido nada. También hay que señalar: esta acción no añade ningún prefijo zigbee2mqtt/, hay que escribir el tema completo zigbee2mqtt/relais_03/set — el marcador de posición gladys/my-topic es engañoso, lo vamos a corregir.
En resumen: en tu configuración, quédate con Enviar un mensaje MQTT, es la mejor opción.
2. El ×10 y el RangeError
Aquí no es Gladys ni un error de Z2M: es el protocolo Zigbee. El comando ZCL genOnOff.onWithTimedOff expresa ontime y offwaittime en décimas de segundo, en un entero de 16 bits. Zigbee2MQTT hace on_time × 10, y el límite es 65535.
En otras palabras, el máximo absoluto es 6553 segundos, es decir, 1 h 49 min. Tus 3 h nunca pasarán en un solo comando, sin importar el camino utilizado. Por eso tu 10800 también fallaba con la acción Zigbee2mqtt, además del problema del broker.
3. Las variables en el payload
El campo mensaje acepta variables, pero con dos limitaciones importantes:
- la sintaxis es
{{ }} (escribe {{ en el campo, aparece la autocompletar), y la variable debe provenir de una acción Obtener el último estado colocada antes, en un grupo anterior;
- ningún cálculo es posible en este campo. A diferencia de
Definir un valor o las condiciones, no hay un motor de fórmulas aquí: {{0.0.last_value}}*3600 se enviará literalmente como 3*3600, no como 10800.
Y cuando la variable no se resuelve, se reemplaza con una cadena vacía, lo que produce un JSON roto del tipo {"state":"ON","on_time":,"off_wait_time":0} — de ahí el rechazo en el lado de Z2M. Deberíamos registrar claramente el payload realmente publicado, es una verdadera laguna de depuración. Mientras tanto, para ver lo que realmente se envía:
mosquitto_sub -h <tu_broker> -t 'zigbee2mqtt/relais_03/set' -v
Para hacer tu multiplicación, hay que sacarla del payload: una acción Definir un valor en modo fórmula en una característica de número MQTT (pompe_on_time), con la fórmula {{...}}*3600, luego un Obtener el último estado en esta característica, y finalmente {{x.y.last_value}} en el JSON.
4. Atención, un error de nuestro lado en las fórmulas
Al verificar este punto, descubrí que nuestro motor de fórmulas se instancia sin la función subtract: la resta no funciona. La fórmula {{0.0.last_value}} - 5 que te di antes levanta una excepción, que se traga silenciosamente (la acción falla, la escena continúa, nada pasa). Mis disculpas, era falso.
Mientras tanto, el contorno es escribir {{0.0.last_value}} + -5, que sí funciona. +, *, /, round() y mod están bien.
Ticket creado: Scene formula engine: subtraction is not supported (`Function subtract missing in provided namespace "math"`) · Issue #2823 · GladysAssistant/Gladys · GitHub
5. Lo que te recomiendo al final: el conteo + perro guardián
Dado el límite de 1 h 49, el buen enfoque combina las dos ideas, y es incluso mejor de lo que propuse al principio, porque sigue siendo irrompible en caso de corte de Gladys.
Crea una característica de número MQTT pompe_minutes_restantes.
Escena « Iniciar la bomba »:
Definir un valor: pompe_minutes_restantes = 180
Enviar un mensaje MQTT en zigbee2mqtt/relais_03/set: {"state":"ON","on_time":900,"off_wait_time":0}
Escena « Supervisión de la bomba », desencadenador programado en intervalo cada 10 minutos:
Obtener el último estado de pompe_minutes_restantes
Si / De lo contrario en > 0:
- entonces:
Definir un valor = {{0.0.last_value}} + -10, luego republicar {"state":"ON","on_time":900,"off_wait_time":0}
- de lo contrario: publicar
{"state":"OFF"}
El principio: el relé nunca recibe más que una autorización de 15 minutos, que la escena de supervisión renueva mientras el conteo es positivo. Como resultado, si Gladys se corta para una actualización, un reinicio o un fallo, la bomba se detiene sola después de un máximo de 15 minutos, y al reiniciar el conteo se reanuda donde estaba ya que se almacena en la base. Más ningún Esperar, y nada que reparar al arrancar.
Mantén bien off_wait_time en 0: es un tiempo de guarda durante el cual el módulo rechaza los nuevos comandos on with timed off, impediría el rearme.
6. Tu escena de supervisión cada minuto
No es necesario. El NodOn sube su cambio de estado a Z2M cuando se corta solo, por lo que una escena con el desencadenador Un dispositivo cambia de estado en la característica del relé, condición « está apagado », es suficiente para enviarte tu notificación de fin.
Creo los tickets para la resta faltante, el registro del payload publicado y el marcador de posición del tema Z2M.
https://github.com/GladysAssistant/Gladys/issues/2825
https://github.com/GladysAssistant/Gladys/issues/2826