Hello,
Last week I setup the uptimerobot to monitor my HA server (synology NAS). it is working fine so far, but there are 2 things i dont really like on it:
1/ I am monitoring the interface webpage, and I am not 100% if this is the best way to do it.
2/ I have to open the firewall ports to let the external server connect in my place, which is something i don’t like. funny enough, after i open the port 8123 i saw logs in the FW for other IPs messing around. I did fix that by only allowing the uptimerobot IP traffic in, but I still dont like open ports on the FW.
To solve my own problem, I start a quick adventure to built a watchdog server, that will be listing for periodic messages from HA, if HA stop to send those messages, then the server will send me a notification and let me know about it.
I plan the following setup:
1/ HA send a message to MQTT broker
2/ server will be listening to the message
3/ server to send alert in case no message arrive during 10 min.
to make it work, I could have used a RPi in my house, but it still wont alert me in case my internet die for example.
so i setup a tiny server installation on AWS which is free of charge. so I have
HASS server → Cloud MQTT ↔ AWS server → pushover
the HASS part is quite simple, it is a time triggered automation that publish a message to the broker:
- alias: ‘tovivo’
trigger:
- platform: time
minutes: ‘/3’
seconds: 0
action:
- service: mqtt.publish
data:
topic: “watchdog”
payload: “hass”
the cloudMQTT i setup as indicated here: MQTT - Home Assistant
the AWS I had setup more than 6 months ago to play around, I dont have any links on how to do it, but google have alot!
the pushover setup was quite straight forward in their website, inclusive on how to send POST messages.
the last part was to create the python server. and surprisingly was not that hard (please keep in mind, I am a computer engineer that did its last code line around 10 years ago) i use to program in C, python was not my strongest skill, also, I AM REALLY RUSTY, the code is “quick and dirty” but solve my problem, I am quite sure it can be optimized, but is stable enough (well, it is working for the last 6 hours, so far, so good.
any helpful idea/improvements suggestions are appreciated.
the code is:
import requests
import paho.mqtt.client as mqtt
import datetime
import time
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
client.subscribe("watchdog/#")
client.subscribe("checktime/#")
client.subscribe("paranoid/#")
client.subscribe("status/#")
client.subscribe("execute/#")
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
global counter
global checktime
global paranoid
global comeback
global dead
global execute
global schedule
old_counter = counter
counter = 0
if dead == 1:
comeback = 1
if msg.topic == 'checktime':
checktime = str(msg.payload, 'utf-8')
if msg.topic == 'execute':
execute = str(msg.payload, 'utf-8')
if msg.topic == 'paranoid':
paranoid = str(msg.payload, 'utf-8')
if msg.topic == 'status':
message = 'Current timer: '+ str(old_counter)+ ' Server Time: '+ schedule +' checktime: ' + checktime + ' paranoid: '+ paranoid
title = 'Watchdog Status'
pushover = requests.post ( url , data = {'token': token, 'user': user , 'message' : message , 'title' : title })
print (message)
#initiate global variables
checktime = '2000' # daily check on format HHMM
paranoid = 'off'
counter = 0
comeback = 0
dead = 0
firstdead = 0
execute = 'true'
schedule = '1900'
token = 'XXXXXXXXXX' # token for app on pushover
user = 'XXXXXXXXXX' # pushover user
message = 'just started'
title = 'just started'
url = 'https://api.pushover.net/1/messages.json'
client = mqtt.Client()
client.username_pw_set('XXXXX', password='XXXXXX') #Cloud MQTT user and pass
client.on_connect = on_connect
client.on_message = on_message
client.connect("XXXXX", XXXXXX, 60) #cloud MQTT server / port
client.loop_start()
while execute == 'true':
now = datetime.datetime.now()
hour = '{str_0:0>2}'.format(str_0=now.hour)
minute = '{str_0:0>2}'.format(str_0=now.minute)
schedule = hour + minute
if schedule == checktime: #daily check to return server status
message = 'Daily Check passed'
title = 'Daily Check'
pushover = requests.post ( url , data = {'token': token, 'user': user , 'message' : message , 'title' : title })
time.sleep(62)
if comeback == 1: #to track if the server was dead, then return
message = 'HASS is back to Life at ' + schedule
title = 'Back to Life'
pushover = requests.post ( url , data = {'token': token, 'user': user , 'message' : message , 'title' : title })
comeback = 0
dead = 0
if counter == 600: #main loop, my system is flagged for 10 min = 600 secs
if dead == 0: #main alert, server just died
firstdead = schedule
message = 'HASS stop to respond at ' + schedule
title = 'HASS is dead!'
pushover = requests.post ( url , data = {'token': token, 'user': user , 'message' : message , 'priority': '2' , 'retry' : '30' , 'expire': '3600', 'title' : title })
dead = 1
if dead == 1: #follow up alert in case paranoid flag is on
message = 'HASS stop to respond at ' + firstdead
title = 'HASS is still dead!'
pushover = requests.post ( url , data = {'token': token, 'user': user , 'message' : message , 'priority': '2' , 'retry' : '30' , 'expire': '3600', 'title' : title })
if paranoid == 'on':
counter = 300
else:
counter = 700
if counter == 760: # second loop, in case paranoid id off. also aimed to prevent variable overflow
counter = 700
time.sleep(1)
counter = counter + 1
#full pushover post message
# pushover = requests.post ('https://api.pushover.net/1/messages.json' , data = {'token': XXXXX, 'user': XXXXXX , 'message' : 'Hello' , 'priority': '2' , 'retry' : '30' , 'expire': '3600', 'title' : 'HELP!!'})
I hope someone else have a use for it!
Luis