ALLTERCO/shelly-script-examples

Router_watchdog only execute one cycle

Closed this issue · 6 comments

KDYR commented

Trying the script on a Plus 1 with firmware 20230308-091529/0.14.1-g22a4cb7.
For test purposes I entered two addresses, that fails when doing the GET....
I left the CONFIG.numberOfFails as the example: 3
After third failed GET, the relay toggles alright but it seems the eventhandler is not working, because the function pingEndpoints isn't executed again.
This is the log:

Failed to fetch https://youseee.dk
Rotating through endpoints
Too many fails, resetting...
shelly_timer_script_:73 JS_Timer 0x3ffd9360 is gone
mg_rpc.c:314 Switch.Set via loopback
shelly_notification:161 Status change of switch:0: {"id":0,"output":false,"source":"loopback","timer_duration":30.00,"timer_started_at":1680713946.03}
shelly_notification:161 Status change of switch:0: {"id":0,"output":true,"source":"timer","timer_duration":null,"timer_started_at":null}

Btw: Although the description says the script relies on ping'ing, the GET is successful also when the server does not respond to pings. Is the functionality rather depending on successful name server lookup?

KDYR commented

Homing in on the problem, I think.
This is the original code for the eventhandler:

Shelly.addEventHandler(function (event) {
//timeout has expired and we have turned back power
  if (
    event.name === "switch" &&
    event.info.source === "timer" &&
    event.info.output === true
  ) {
    print("Start watchdog timer");
    pingTimer = Timer.set(CONFIG.pingTime * 1000, true, pingEndpoints);
  }
});

I added some code for the purpose of debugging (indicated with // to the far right):

Shelly.addEventHandler(function (event) {
// timeout has expired and we have turned back power
        print("Event as JSON string:");            //
        print("=====================");            //
        print(JSON.stringify(event));              //
        print("Properties of event:");             //
        print("====================");             //
        for (let prop in event) {                  //
          print(prop, ' - ', typeof (prop));       //
        };                                         //
        print("Properties of event.info:");        //
        print("=========================");        //
        for (let prop in event.info) {             //
          print(prop, ' - ', typeof (prop));       //
        };                                         //
        print("_________________________");        //
    if (
    event.name === "switch" &&
    event.info.source === "timer" &&
    event.info.output === true
  ) {
    print("Start watchdog timer");
    pingTimer = Timer.set(CONFIG.pingTime * 1000, true, pingEndpoints);
  }
});

This is the output:

Event as JSON string:
=====================
{"info":{"ts":1680902207.430000,"state":false,"event":"toggle","id":0,"component":"switch:0"},"now":1680902207.434407,"id":0,"name":"switch","component":"switch:0"}
Properties of event:
====================
info - string
now - string
id - string
name - string
component - string
Properties of event.info:
=========================
ts - string
state - string
event - string
id - string
component - string
_________________________

However, the code makes reference of event.info.source and event.info.output of which none seems to exist in the scripting environment ...?

In the console window we also see ("Full Log" enabled):

shelly_notification:161 Status change of switch:0: {"id":0,"output":false,"source":"loopback","timer_duration":30.00,"timer_started_at":1680901156.28}

...and here we do se the source and output properties.

Thank you. We had a breaking change in the way we report status notifications. You are right that events don't have these fields any more, it's rather part of the status notification.

An update has been provided. I'll be grateful if you test on your side.

KDYR commented

The revised code seems to work - thx!
A couple of comments:

  • What is the purpose of the return statement in line 68? Is it needed?
  • Are you really relying on 'ping'? I tried to insert a couple of sites that accept https connections, but do not respond to ping connections, and they DO give error -114

Edit: there was a not too much. ARGH

The revised code seems to work - thx! A couple of comments:

  • What is the purpose of the return statement in line 68? Is it needed?
  • Are you really relying on 'ping'? I tried to insert a couple of sites that accept https connections, but do not respond to ping connections, and they do not give error -114

I tested the script mysqlf and there was no action handling because timeout in latest firmware is error_code -104 instead of -114

KDYR commented

I tested the script mysqlf and there was no action handling because timeout in latest firmware is error_code -104 instead of -114

For test purposes I used sites that do not exist, and they give "-114", but maybe an existing, unresponsive site gives another error, and that I did not test.
I agree that for purposes like in this script it is generally better to test for "any error" than for a specific error. I.e.
if (error_code less than X) or if (error_code greater than X) depending on the concept for error codes.

  • What is the purpose of the return statement in line 68? Is it needed?

It is not needed. It's remnant from the initial implementation. I will resolve it with a direct change to master.

I will close this thread now.