Restart my router on error (with manual trigger and inhibit)

Tags: #<Tag:0x00007f6173633888> #<Tag:0x00007f61736336f8> #<Tag:0x00007f6173633608>

I’d like to share with you a functionality I wrote with OpenHAB 2.2 for restarting my router.
My internet provider gave me a crappy router that sometimes deadlocks itself, it doesn’t even reply to ping in this case.

I want to:

  • detect that “no ping reply” state
  • restart the router in that case (unplug and re-plug)

And I want to also

  • be able to trigger the restart manually
  • be able to completely turn off the router (just in case)

That’s how I’ve done it:
Define a network thing (requires network binding)
things/ethernet.things

Thing network:pingdevice:IT_Router [hostname="192.168.0.1", refreshInterval=5000]

Define an item that represents the online state of the router: items/ethernet.items

Switch IT_Router_Online "Router [%s]" (GP_Persist_Change) {channel="network:pingdevice:IT_Router:online"}

Define two virtual items for the rule
items/virtual_trigger.items

Switch VT_Router_TriggerRestart "Trigger Router restart"
Switch VT_Router_InhibitRestart "Inhibit Router restart [%s]"

Define the switch item that get’s toggled for router restart - I connected it to Raspberry GPIO, this pin is high even on restart/reset case, so its “always on” which perfectly fits my use case
items/gpio.items

Switch IT_Router_Switch "Router" (GP_Conn_RPI, GP_Type_Relays) {gpio="pin:5 initialValue:high"} // is high at booting

sitemap (just in case you need it)

Frame label="Router restart" {
	Switch item=IT_Router_Switch
	Text   item=IT_Router_Online
	Switch item=VT_Router_TriggerRestart
	Text   item=VT_Router_InhibitRestart
}

Here comes my magic rule
rules/router.rules

rule "Restart router on failure"
when 
    Item IT_Router_Online changed to OFF
    or Item VT_Router_TriggerRestart changed to ON
then
    logInfo("router.rules", "Restart router rule called")
    if(IT_Router_Switch.state == ON && VT_Router_InhibitRestart.state != ON) {
        // turn on inhibit, turn off router
        VT_Router_InhibitRestart.sendCommand(ON)
        IT_Router_Switch.sendCommand(OFF)

        // reset trigger, if restart was caused by trigger
        if(VT_Router_TriggerRestart.state == ON) {
            VT_Router_TriggerRestart.sendCommand(OFF)
        }

        // create timer for further action (turn on and reset inhibit)
        createTimer(now.plusSeconds(1))[|IT_Router_Switch.sendCommand(ON)]
        createTimer(now.plusSeconds(13))[|VT_Router_InhibitRestart.sendCommand(OFF)]
    }
end

The virtual item VT_Router_InhibitRestart is needed because I don’t want to re-trigger the restart when I manually trigger that rule and OpenHAB then (after ping timeout) sees the router offline.

That’s how it looks in log when I do a manual trigger: (without the logging line in rule)

==> /var/log/openhab2/events.log <==
2018-02-10 14:03:27.031 [ome.event.ItemCommandEvent] - Item 'VT_Router_TriggerRestart' received command ON
2018-02-10 14:03:27.053 [vent.ItemStateChangedEvent] - VT_Router_TriggerRestart changed from OFF to ON
2018-02-10 14:03:27.978 [ome.event.ItemCommandEvent] - Item 'VT_Router_InhibitRestart' received command ON
2018-02-10 14:03:27.994 [ome.event.ItemCommandEvent] - Item 'IT_Router_Switch' received command OFF
2018-02-10 14:03:27.999 [ome.event.ItemCommandEvent] - Item 'VT_Router_TriggerRestart' received command OFF
2018-02-10 14:03:28.004 [vent.ItemStateChangedEvent] - VT_Router_TriggerRestart changed from ON to OFF
2018-02-10 14:03:28.010 [vent.ItemStateChangedEvent] - VT_Router_InhibitRestart changed from OFF to ON
2018-02-10 14:03:28.013 [vent.ItemStateChangedEvent] - IT_Router_Switch changed from ON to OFF
2018-02-10 14:03:28.995 [ome.event.ItemCommandEvent] - Item 'IT_Router_Switch' received command ON
2018-02-10 14:03:29.004 [vent.ItemStateChangedEvent] - IT_Router_Switch changed from OFF to ON
2018-02-10 14:03:34.788 [vent.ItemStateChangedEvent] - IT_Router_Online changed from ON to OFF
2018-02-10 14:03:34.796 [me.event.ThingUpdatedEvent] - Thing 'network:pingdevice:IT_Router' has been updated.
2018-02-10 14:03:41.014 [ome.event.ItemCommandEvent] - Item 'VT_Router_InhibitRestart' received command OFF
2018-02-10 14:03:41.023 [vent.ItemStateChangedEvent] - VT_Router_InhibitRestart changed from ON to OFF
2018-02-10 14:04:09.921 [vent.ItemStateChangedEvent] - IT_Router_Online changed from OFF to ON
2018-02-10 14:04:09.934 [me.event.ThingUpdatedEvent] - Thing 'network:pingdevice:IT_Router' has been updated.
4 Likes

great. Thats kinda how I did it (also a router that sometimes gives up), but yours is more sophisticated

I know I’m going to sound dumb here (great first post, moony!) but which line in any of this does anything to the router other than check to see that it’s doing anything?

(sorry to ask, not expecting or feeling entitled to an answer, just curious!)

If I understand your question correctly, the Network binding does this automatically.

Here you can see that it will ping it every 5 sec.

And this is the Switch that will change ON/OFF regarding the ping result.

Thanks @rkrisi for your explanation, it’s totally correct - but if I get the question correct Moony is asking another thing.

@madmanmoon Welcome here! Don’t feel dumb for your question.
Look at rules/router.rules, these two lines actually do restart the router:

        IT_Router_Switch.sendCommand(OFF)
        createTimer(now.plusSeconds(1))[|IT_Router_Switch.sendCommand(ON)]

They switch off power supply to the router, and turn it on again one second later.
I have a relay in power supply (connected to a GPIO pin of my Raspberry Pi - but this detail doesn’t matter), which OpenHAB can turn off and on.

Ah, OK, thanks, peoples.

So it’s not a command to the actual router that is turning it off, more a power switch that is being turned off / on. Cheers, folks. :thumbsupall: