mycontroller-org / mycontroller-v1-legacy

The Open Source Controller
http://www.MyController.org
Apache License 2.0
148 stars 90 forks source link

ACK messages sent prevent "default" relay node code working #479

Closed seant100 closed 5 years ago

seant100 commented 5 years ago

MyController is sending ACK messages that look like "set" commands in the receive function of a node.

from the raw gateway logs I see this as an example

2018-10-30 15:32:12,785 Tx: mygateway1-in/2/10/1/1/2 [1]
2018-10-30 15:32:13,491 Tx: mygateway1-in/2/10/1/1/2 [0]
2018-10-30 15:32:14,017 Tx: mygateway1-in/2/10/1/1/2 [0]
2018-10-30 15:32:14,609 Tx: mygateway1-in/2/10/1/1/2 [0]

Here I set a relay ON as per first line. Then the next 3 log lines show MyController is sending an ACK request 3 times which the default / standard way for MySensors to receive a relay on/off signal essentially then turns the relay off.

So, basically, I turn on a relay then MyController sends the ACK message and a second or so later the relay turns off.

It also seems to be sending these ACK messages regardless of whether ACK is set in the gateway settings page.

The default example MySensors relay code does not check for an ACK message.

The only way to get relays working now is to change the default MySensors example receive function to include a check for "message is Ack"

Example : Standard MySensors relay code is something like this

void receive(const MyMessage &message)
{
        if (message.type == V_STATUS) {
             //code here to get status and turn on or off relay
        }
}

As a work-around for MyController sending the ACK messages I have to now use something like this

void receive(const MyMessage &message)
{
  bool ack = mGetAck(message);

  if (!ack) {
        if (message.type == V_STATUS) {
        }
  }
}
jkandasa commented 5 years ago

@seant100 MyController will not change the payload, It tries to send a payload with ack request(if ack enabled). If there is no response(ack) from the node, resends again after Ack wait time.

In my setup, I see as follows,

2018-10-30 18:06:00,044 Tx: in_rfm69/15/1/1/1/2 [1]
2018-10-30 18:06:00,523 Rx: out_rfm69/15/1/1/1/2 [1]

Note: I do not change anything in MySensors code. using as is. Can you verify have you enabled any other rules/scripts to the specific relay? They may send something based on a condition? can you double check with another relay with a different node?

seant100 commented 5 years ago

@jkandasa There should be no rule that triggered. And if there was it would be a normal message, not an ACK message. So, as per my workaround the message is an "ACK" message and hence the need to identify it as an ACK message in the receive function. It is not a normal set state message being sent. From the logs this is definitely being sent from MyController.

seant100 commented 5 years ago

@jkandasa I will be building a new relay node soon, if time allows ! Then I can also check with a new relay node.

seant100 commented 5 years ago

@jkandasa It seems the problem is MySensors. I checked another example called "SecureActuator" and that example contains a check for ACK messages. So it seems MySensors example for "RelayActuator" is not correct. This is therefore not an issue with MyController !

Code from "RelayActuator" is : No mention or check here for ACK messages

void receive(const MyMessage &message)
{
    // We only expect one type of message from controller. But we better check anyway.
    if (message.type==V_STATUS) {
        // Change relay state
        digitalWrite(message.sensor-1+RELAY_PIN, message.getBool()?RELAY_ON:RELAY_OFF);
        // Store state in eeprom
        saveState(message.sensor, message.getBool());
        // Write some debug info
        Serial.print("Incoming change for sensor:");
        Serial.print(message.sensor);
        Serial.print(", New status: ");
        Serial.println(message.getBool());
    }
}

Code from Examples > SecureActuator - Here they specifically state to ignore ACK messages for controlling relay

void receive(const MyMessage &message)
{
    // We only expect one type of message from controller. But we better check anyway.
    // And acks are not accepted as control messages
    if (message.type==V_LOCK_STATUS && message.sensor<=NOF_LOCKS && !mGetAck(message)) {
        // Change relay state
        digitalWrite(message.sensor-1+LOCK_1, message.getBool()?LOCK_LOCK:LOCK_UNLOCK);
        // Store state in eeprom
        saveState(message.sensor, message.getBool());
        // Write some debug info
        Serial.print("Incoming change for lock:");
        Serial.print(message.sensor);
        Serial.print(", New status: ");
        Serial.println(message.getBool());
    }
}

Sorry for putting up issue here. I will maybe put up something on MySensors about the problem with their examples