[OBSOLETE] Host Pinger (IP based Online State / Presence)

Thanks for the great work!

I tested it by rebooting the Raspberry Pi, unplugging the cable modem, and reconnecting the cable modem after 10 minutes. I received SMS messages and notifications from ST after the ISP changed.

Here is the log. The initial message still shows V2.0.

—SmartThings Host Pinger V2.0—

Loading config…
Loaded
DebugLevel is set to 1
Running …
05-Mar-18 17:30 [OFFLINE] 192.168.100.1
Failed to send request to SmartThings: Error: NameResolutionFailure [RETRYING…]
05-Mar-18 17:30 [OFFLINE] 192.168.0.1
Failed to send request to SmartThings: Error: NameResolutionFailure [RETRYING…]
05-Mar-18 17:31 [ONLINE] 192.168.100.1
Failed to send request to SmartThings: Error: NameResolutionFailure [RETRYING…]
05-Mar-18 17:31 [OFFLINE] 192.168.0.1
Failed to send request to SmartThings: Error: NameResolutionFailure [RETRYING…]
05-Mar-18 17:31 [ONLINE] 192.168.100.1
Failed to send request to SmartThings: Error: NameResolutionFailure [RETRYING…]
05-Mar-18 17:31 [OFFLINE] 192.168.0.1
Failed to send request to SmartThings: Error: NameResolutionFailure [RETRYING…]
05-Mar-18 17:32 [ONLINE] 192.168.100.1
Successfully sent to SmartThings
05-Mar-18 17:32 [OFFLINE] 192.168.0.1
Successfully sent to SmartThings
05-Mar-18 17:40 [WENT OFFLINE] 192.168.100.1
Failed to send request to SmartThings: Error: ConnectFailure (Network is unreachable) [RETRYING…]
05-Mar-18 17:41 [WENT OFFLINE] 192.168.100.1
Failed to send request to SmartThings: The request timed out [RETRYING…]
05-Mar-18 17:43 [ONLINE] 192.168.0.1
Successfully sent to SmartThings
05-Mar-18 17:43 [WENT OFFLINE] 192.168.100.1
Successfully sent to SmartThings
05-Mar-18 17:50 [ONLINE] 192.168.100.1
Successfully sent to SmartThings
05-Mar-18 17:50 [WENT OFFLINE] 192.168.0.1
Successfully sent to SmartThings

So just to double check, all working as expected? Apart from me forgetting to update the version number in the logging? :slight_smile:

Yes, everything is working. Again, thank you!

Yesterday Samsung sent out an email saying the current ST app would be replaced soon. Hopefully everything will continue working after Samsung merged its smart home apps.

1 Like

It’s inevitable loads of stuff in the app will stop working, but shouldn’t impact already installed apps…

NEW - Host Pinger Arduino / ESP8266 EDITION

I’m running this on an Wemos D1 Mini (ESP8266) which is tiny, very low power, connects to Wifi and only costs 2-3 £ or $, connect it to a USB power supply and you have an always on method of pinging devices and sending to SmartThings without running the EXE on a dedicated PC…

I am not running this in a real world scenario so can’t confirm on reliability, as I have only just written the code and I’m not at home right now to leave it going… but if anyone wants to give it a go you will need to add the details in the settings section, load the sketch to your device using the Arduino IDE and it should then start running, output will be to the serial monitor…

By the way this is the first thing I have written for Arduino so any changes or suggestions welcome… feel free to put in a pull request…

Tagging @Jason_Brown as I expect you may be interested…

EDIT: V1.1 now loaded with change so WiFi AP is not broadcast

1 Like

I decided to use bash and wget to write a pinger. Everything in one file.

I’d appreciate it if someone can tell me how to format the code below. The site doesn’t allow me to add more replies to this topic because I am a new user. All I know is to use the HTML pre tag to enclose the entire script.

#!/bin/bash

# SmartThings IDE configuration
IDE="https://graph-na04-useast2.api.smartthings.com"

# SmartThings application ID and access token
# Get them from the Host Pinger SmartApp under Endpoint Setup Details.
ACCESS_TOKEN="paste-your-access-token-here"
APP_ID="paste-your-app-id-here"
ST_ENDPOINT="${IDE}/api/smartapps/installations/${APP_ID}/statechanged"

# Add hosts you want to ping.
declare -A HOST_STATUS_MAP=(
    [192.168.100.1]="unknown"
    [192.168.0.1]="unknown"
)

# ping interval in seconds
PING_INTERVAL=30
FORCE_UPDATE_INTERVAL=86400
LAST_UPDATE="$(date +%s)"

echo `date` "- Starting SmartThings Host Pinger..."
while true
do
    FORCE_UPDATE=false
    CURR_TIME="$(date +%s)"

    if (( CURR_TIME - LAST_UPDATE > FORCE_UPDATE_INTERVAL ))
    then
        FORCE_UPDATE=true
        echo -e "\nForcing SmartThings update..."
    fi

    for IP_ADDR in "${!HOST_STATUS_MAP[@]}"
    do
        HOST_STATUS="unknown"
        WGET_STATUS=0

        if /bin/ping -c 2 ${IP_ADDR} > /dev/null
        then
            HOST_STATUS="online"
        else
            HOST_STATUS="offline"
        fi

        ST_URL="${ST_ENDPOINT}/${HOST_STATUS}?access_token=${ACCESS_TOKEN}&ipadd=${IP_ADDR}"

        # Only update the status if it has changed or forced update is due.

        if [ "${HOST_STATUS}" != "${HOST_STATUS_MAP[${IP_ADDR}]}" ] || ${FORCE_UPDATE}
        then
            /usr/bin/wget -q -O /dev/null -T 10 "${ST_URL}"
            WGET_STATUS=$?
            echo

            # Update the status map if SmartThings was successfully updated.

            if [ ${WGET_STATUS} -eq 0 ]
            then
                HOST_STATUS_MAP[${IP_ADDR}]=${HOST_STATUS}
                LAST_UPDATE="$(date +%s)"
                echo `date` "- ${IP_ADDR} status: [${HOST_STATUS}]"
            else
                echo `date` "- Unable to reach SmartThings Endpoint."
            fi
        fi
    done

#    echo "All hosts: ${!HOST_STATUS_MAP[@]}"
#    echo "All status: ${HOST_STATUS_MAP[@]}"
#    echo "sleeping..."
    sleep ${PING_INTERVAL}
    echo -n "*"
done
4 Likes

@camedia Great work now the 4th way of pinging devices, who thought pinging would be so popular!

I’ll add a link in the 4th post!

By the way you can select and format the code as code if you edit your post (it doesn’t really matter but sometimes makes it easier…

A Bourne shell script that runs on an Asus router with original firmware to detect if a failover has happened. I use it to turn on an orange light behind my TV when the router fails over to the secondary WAN, which is a mobile hotspot.

I am not using ping to detect the change. Instead I use the router’s “nvram get wanX_realip_ip” command. It shows that the Host Pinger smart app can be used as a more general purpose resource state tracker.

The BEGIN_DATA and END_DATA variables should have the values below. They didn’t display correctly when I used the HTML pre tag to enclose the entire script.
BEGIN_DATA=’<?xml version="1.0" encoding="utf-8"?><s:Envelope xmlns:s=“http://schemas.xmlsoap.org/soap/envelope/” s:encodingStyle=“http://schemas.xmlsoap.org/soap/encoding/”><s:Body><u:SetBinaryState xmlns:u=“urn:Belkin:service:basicevent:1”>‘
END_DATA=’</u:SetBinaryState></s:Body></s:Envelope>’


#!/bin/sh

#### This script runs on a Asus router with original Asus firmware.
#### It checks the status of the primary and secondary/failover WAN
#### and updates the Host Pinger smart app when the status changes.
#### It also turns on a Wemo Mini smart plug on the LAN when a 
#### failover happens.

# SmartThings IDE configuration. Change it to your own IDE URL.
IDE="https://graph-na04-useast2.api.smartthings.com"

# SmartThings application ID and access token
# Get them from the Host Pinger SmartApp under Endpoint Setup Details.
ACCESS_TOKEN="paste-your-access-token-here"
APP_ID="paste-your-app-id-here"
ST_ENDPOINT="${IDE}/api/smartapps/installations/${APP_ID}/statechanged"

# ping interval in seconds
PING_INTERVAL=30
FORCE_UPDATE_INTERVAL=14400
FORCE_UPDATE=false
LAST_UPDATE=$(date +%s)

# Primary WAN
WAN0_IP_ADDR=192.168.100.1
WAN0_PREV_STAT=unknown

# Failover WAN
WAN1_IP_ADDR=192.168.0.1
WAN1_PREV_STAT=unknown

# IP of Wemo Mini smart plug
WEMO_IP=192.168.1.137

H_ACCEPT="Accept: "
H_CONTENT='Content-type: text/xml; charset=utf-8'
H_SOAPACTION="SOAPACTION: \"urn:Belkin:service:basicevent:1#SetBinaryState\""
BEGIN_DATA=' '
END_DATA=' '

#### Turn on/off Wemo Mini
toggle_wemo()
{
    ON_OFF=$1

    # Wemo's web service port can change periodically.
    # Test which port is currently open.
    for PTEST in 49152 49153 49154 49155
    do
        PORTTEST=$(wget -q -t 1 -T 5 -O - http://$WEMO_IP:$PTEST/setup.xml | grep "root")                      
        if [ "$PORTTEST" != "" ]; then
            PORT=$PTEST
            break
        fi
    done    
    
#    echo "${BEGIN_DATA}${ON_OFF}${END_DATA}" 

    if [ "${PORT}" != "" ]; then
        wget --header="${H_ACCEPT}" \
             --header="${H_CONTENT}" \
             --header="${H_SOAPACTION}" \
             --post-data="${BEGIN_DATA}${ON_OFF}${END_DATA}" \
             -q -t 1 -T 10 -o /dev/null -O /dev/null http://$WEMO_IP:$PORT/upnp/control/basicevent1
    fi
}

#### Update device status in SmartThings
update_st_status()
{
    WAN_NUM=$1
    IP_ADDR=$2
    HOST_STATUS=$3
    
    ST_URL="${ST_ENDPOINT}/${HOST_STATUS}?access_token=${ACCESS_TOKEN}&ipadd=${IP_ADDR}"
    
    wget -q -t 1 -T 10 -o /dev/null -O /dev/null --no-check-certificate "${ST_URL}"
    WGET_STATUS=$?
    
    if [ ${WGET_STATUS} -eq 0 ]; then
        LAST_UPDATE=$(date +%s)
        eval "WAN${WAN_NUM}_PREV_STAT=${HOST_STATUS}"
    fi
}

#### Use Asus router's "nvram get wanX_realip_ip" command
#### to check if a WAN is active. X is 0 for the primary WAN
#### and 1 for the secondary/failover WAN.
check_wan_status()
{
    WAN_NUM=$1
    IP_ADDR=$2
    PREV_STATUS=$3
    
    WAN_IP_ADDR=$(nvram get wan${WAN_NUM}_realip_ip)
    
    if [ "${WAN_IP_ADDR}" != "" ]; then
        WAN_STATUS=online
    else
        WAN_STATUS=offline
    fi

    if [ "${WAN_STATUS}" != "${PREV_STATUS}" ] || ${FORCE_UPDATE} ; then
        # Update the Wemo plug directly instead of waiting for SmartThings
        # because during failover the ST hub might take minutes to
        # reconnect to the cloud.
        if [ ${WAN_NUM} -eq 1 ] && [ ${WAN_STATUS} = "online" ]; then
           toggle_wemo 1
        elif [ ${WAN_NUM} -eq 1 ] && [ ${WAN_STATUS} = "offline" ]; then
           toggle_wemo 0
        fi
        
        echo $(date) ${WAN_NUM} "${IP_ADDR}" "${WAN_STATUS}"
        update_st_status ${WAN_NUM} "${IP_ADDR}" "${WAN_STATUS}"
    fi
}

#### Main
echo $(date) "Starting SmartThings Pinger..."

while true
do
    CURR_TIME=$(date +%s)
    TIME_LAPSED=$(expr ${CURR_TIME} - ${LAST_UPDATE} )
#    echo "Time lapsed: ${TIME_LAPSED}"
    
    if [ ${TIME_LAPSED} -ge ${FORCE_UPDATE_INTERVAL} ]; then
        FORCE_UPDATE=true
        echo $(date) "Forced update: $FORCE_UPDATE"
    else
        FORCE_UPDATE=false
    fi

    check_wan_status 0 ${WAN0_IP_ADDR} ${WAN0_PREV_STAT}
    check_wan_status 1 ${WAN1_IP_ADDR} ${WAN1_PREV_STAT}
    
    sleep ${PING_INTERVAL}
done


2 Likes

Something strange here, I wanted to transfer my sthostpinger to another rpi device so I copied the exact sthostpinger and config file to another rpi. However now when I run I got the following

Failed to SendGetRequest: Error getting response stream (Write: The authentication or decryption has failed.): SendFailure

Any settings I need to reset or reconfigure when changing to another rpi?

It’s an issue with your mono install…and the security certificates

@rontalley worked this out in post 34, although the link in his post doesn’t go the the right place anymore… so here’s a fresh link :slight_smile:

http://www.mono-project.com/download/stable/#download-lin-raspbian

2 Likes

Updated my post as well.

I still refer people to this all the time! Been working for me since day 1.

Thanks again for this awesome app!

1 Like

I also updated the first post under the troubleshooting section yesterday too.

Thanks for your awesome help and ideas :slight_smile:

1 Like

Ahh thanks, that was the issue. Maybe include it in the installation notes.

The mono section of the guide already links to the same page I linked earlier (you just need to click through)… but will update with the new link and a note specific to this issue :slight_smile:

I guess you sorted it, if not happy to help!

hi all,
i need some advice i have host ping set up on my pc i was hope that when it was shutdown it go offline but i am seeing online do i have some thing set up wrong

Hi @beau76 glad you solved your first issue, for the second this software is designed to be left running on an always on machine or dedicated device… this is not designed to monitor the machine in which it is running…

can it all be run on smartthings what i am after i have a switch that when triggered it does a wake on lan i am look for a way to let it known pc is off

Only if you run the exe on another computer or on a device such as an Arduino / ESP8266…

It’s not meant to report the computer on which it’s running… it may be possible to update the code for this so when exited it puts everything offline… but I don’t have a lot of time free at the moment to work out how to add this in and an option to enable and disable it…

If you just need to send a WOL and current state is not important… you could use a momentary switch, in which case state is not relevant… and will send a WOL request with every press

1 Like

here what i have run in to use wol with alexa it only woks with on/off
switch so it set were on is wol but then i have to set it to off to work next time