The approach to differentiate the message did not work for my purpose: commands sent from Fhem are a set message requests return as set message Status message of the node (set message) returns as set message with Ack I.e. all are set messages (no differentiation possible) Because I use a counter to limit the resending of the status message from the node I used this counter to get to the destination. In short: If the reception was successful the counter goes to 0, the request to <0 and the send to >0. Here is my sketch, it is for switching several time controlled relays, for clarity I have removed the debug messages: /** * The MySensors Arduino library handles the wireless radio link and protocol * between your home built sensors/actuators and HA controller of choice. * The sensors forms a self healing radio network with optional repeaters. Each * repeater and gateway builds a routing tables in EEPROM which keeps track of the * network topology allowing messages to be routed to nodes. * * Created by Henrik Ekblad <henrik.ekblad@mysensors.org> * Copyright (C) 2013-2018 Sensnology AB * Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors * * Documentation: http://www.mysensors.org * Support Forum: http://forum.mysensors.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * ******************************* * * DESCRIPTION * The RS485 Gateway prints data received from sensors on the serial link. * The gateway accepts input on seral which will be sent out on * the RS485 link. * * Wire connections (OPTIONAL): * - Inclusion button should be connected between digital pin 3 and GND * - RX/TX/ERR leds need to be connected between +5V (anode) and digital pin 6/5/4 with resistor 270-330R in a series * * LEDs (OPTIONAL): * - RX (green) - blink fast on radio message received. In inclusion mode will blink fast only on presentation received * - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly * - ERR (red) - fast blink on error during transmission error or receive crc error * * If your Arduino board has additional serial ports * you can use to connect the RS485 module. * Otherwise, the gateway uses AltSoftSerial to handle two serial * links on one Arduino. Use the following pins for RS485 link * * Board Transmit Receive PWM Unusable * ----- -------- ------- ------------ * Teensy 3.0 & 3.1 21 20 22 * Teensy 2.0 9 10 (none) * Teensy++ 2.0 25 4 26, 27 * Arduino Uno 9 8 10 * Arduino Leonardo 5 13 (none) * Arduino Mega 46 48 44, 45 * Wiring-S 5 6 4 * Sanguino 13 14 12 * */ #define SN "MultiTimerRelay" #define SV "1.0" // Enable debug prints to serial monitor #define MY_DEBUG // Enable RS485 transport layer #define MY_RS485 // Define this to enables DE-pin management on defined pin //#define MY_RS485_DE_PIN 2 // Set RS485 baud rate to use #define MY_RS485_BAUD_RATE 19200 // Enable this if RS485 is connected to a hardware serial port #define MY_RS485_HWSERIAL Serial #define MY_NODE_ID 2 // Id of the Node #define MY_TRANSPORT_WAIT_READY_MS 30000 //loop is beginning at 3000ms whitout connection #include <MySensors.h> //++++++++ Relays +++++++++ #define RELAY_ON 1 // switch around for ACTIVE LOW / ACTIVE HIGH relay #define RELAY_OFF 0 #define noRelays 3 // min 2 const int relayPin[] = {7, 8, 9}; // switch around pins to your desire uint32_t relayTime[] = {0, 0, 0}; // on time for Relay to set from Fhem volatile uint32_t startTime[] = {0, 0, 0}; // time to switch Relay on int relayAckCountR[noRelays]; // ACK retry counter relay int relayAckCountT[noRelays]; // ACK retry counter time const uint32_t timeFactor = 1000UL; // to send minutes = 60000UL or seconds = 1000UL; UL says compiler is unsigned long!!! class Relay // relay class, store all relevant data (equivalent to struct) { public: int relayPin; // physical pin number of relay boolean relayState; // relay status (also stored in EEPROM) uint32_t relayTime; // on time for Relay uint32_t startTime; // time to switch Relay on int relayAckCountR; // ACK retry counter relay int relayAckCountT; // ACK retry counter time }; Relay Relays[noRelays]; MyMessage msgRelay[noRelays]; MyMessage msgTime[noRelays]; void before() { } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo(SN, SV); //++++++++ Relays +++++++++ for (int i = 0; i < noRelays; i++) { present(i, S_DIMMER); // present sensor to gateway wait(20); } } void setup() { //++++++++ Relays +++++++++ for (int i = 0; i < noRelays; i++) { Relays[i].relayPin = relayPin[i]; // assign physical pins Relays[i].startTime = startTime[i]; // assign time to switch relay on Relays[i].relayTime = relayTime[i]; // assign time for relay on msgRelay[i].sensor = i; // initialize messages msgRelay[i].type = V_STATUS; msgTime[i].sensor = i; msgTime[i].type = V_PERCENTAGE; pinMode(Relays[i].relayPin, OUTPUT); Relays[i].relayState = RELAY_OFF; // set all relaysState off digitalWrite(Relays[i].relayPin, Relays[i].relayState ? RELAY_ON : RELAY_OFF); // write all relays off //send(msgRelay[i].set(Relays[i].relayState ? true : false)); wait(20); } for (int i = 0; i < noRelays; i++) { request(i, V_STATUS); // Set relay to last known state Relays[i].relayAckCountR = -1; // for the control of the request wait(100); request(i, V_PERCENTAGE); // Set relay to last known state Relays[i].relayAckCountT = -1; // for the control of the request wait(100); } } void loop() { //++++++++ Relays +++++++++ uint32_t currentTime = millis(); //Zeitsteuerung der Relays for (byte i = 0; i < noRelays; i++) { if ( Relays[i].relayState == RELAY_ON && (currentTime - Relays[i].startTime > Relays[i].relayTime)) { digitalWrite(Relays[i].relayPin, !Relays[i].relayState ? RELAY_ON : RELAY_OFF); Relays[i].relayState = !Relays[i].relayState; send(msgRelay[i].set(Relays[i].relayState ? true : false), true); // Send value to gw with ACK Relays[i].relayTime = 0; Relays[i].relayAckCountR = 3; wait(100); send(msgTime[i].set(Relays[i].relayTime), true); // Send value to gw with ACK Relays[i].relayAckCountT = 3; wait(100); } } for (int i = 0; i < noRelays; i++) { if (Relays[i].relayAckCountR < 0) { wait(200); request(i, V_STATUS); // Set relay to last known state Relays[i].relayAckCountR = 0; wait(100); } if (Relays[i].relayAckCountT < 0) { wait(200); request(i, V_PERCENTAGE); // Set relay to last known state Relays[i].relayAckCountT = 0; wait(100); } if (Relays[i].relayAckCountR > 0) { wait(200); send(msgRelay[i].set(Relays[i].relayState ? true : false), true); // Send value to gw with ACK wait(100); } if (Relays[i].relayAckCountT > 0) { wait(200); send(msgTime[i].set(Relays[i].relayTime), true); // Send value to gw with ACK wait(100); } } } void receive(const MyMessage &message) { //++++++++ Relays +++++++++ if (message.type == V_STATUS && Relays[message.sensor].relayAckCountR <= 0) { Relays[message.sensor].relayAckCountR = 0; if (message.sensor < noRelays) { // check if message is valid for relays..... previous line [[[ if (message.sensor <=noRelays){ ]]] Relays[message.sensor].relayState = message.getBool(); digitalWrite(Relays[message.sensor].relayPin, Relays[message.sensor].relayState ? RELAY_ON : RELAY_OFF); // and set relays accordingly //saveState( message.sensor, Relays[message.sensor].relayState ); // save sensor state in EEPROM (location == sensor number) } if (Relays[message.sensor].relayState == RELAY_ON) { Relays[message.sensor].startTime = millis(); } } else if (message.isAck() && message.type == V_STATUS && Relays[message.sensor].relayAckCountR > 0) { Relays[message.sensor].relayAckCountR = 0; } else if (!message.isAck() && message.type == V_STATUS && Relays[message.sensor].relayAckCountR > 0) { Relays[message.sensor].relayAckCountR--; } else if (message.type == V_PERCENTAGE && Relays[message.sensor].relayAckCountT <= 0) { if (message.sensor < noRelays) { // check if message is valid for relays..... previous line [[[ if (message.sensor <=noRelays){ ]]] Relays[message.sensor].relayTime = (message.getByte() * timeFactor); // calculate to millis } } else if (message.isAck() && message.type == V_PERCENTAGE && Relays[message.sensor].relayAckCountT > 0) { Relays[message.sensor].relayAckCountT = 0; } else if (!message.isAck() && message.type == V_PERCENTAGE && Relays[message.sensor].relayAckCountT > 0) { Relays[message.sensor].relayAckCountT --; } }