Edit 06-01-2018: Updated script for python 3.x, be sure it's installed. Code cleanup and https fixes.
Edit 08-03-2018: Updated buienradar url.
1. Create a dummy percentage device and set thedeviceidx to the idx of this new device
2. Set domoticz server parameters (Server ip + port, http/https), yourlatitude and yourlongitude
3. Put the script in /home/pi/domoticz/scripts/python as buienradar.py
4. Make it executable (optional): chmod +x /home/pi/domoticz/scripts/python/buienradar.py
5. Add a cronjob:
Code: Select all
crontab -e
Code: Select all
*/5 * * * * sudo python3 /home/pi/domoticz/scripts/python/buienradar.py silent
As this is my first python script (based on chopper_robs check_device_online.py python script), feel free to optimize it:
Code: Select all
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Title: buienradar.py
# Date: 25-10-2016/08-03-2018
# Info: Checks buienradar.nl if it is going to rain and reports back to domoticz
# Version : 0.6
# 0.1 Initial release
# 0.2 Added silent mode
# 0.3 Add password
# Use direct connection to domoticz to get values
# 0.4 Add SSL and fix server(s)
# 0.5 Updated to Python 3
# Bug fix when current status was 0
# 0.6 Updated buienradar url
import sys
import datetime
import time
import os
import subprocess
import json
import base64
import ssl
import urllib.request
# Settings for the domoticz server
domoticzserver = "https://192.168.1.200:8006"
domoticzusername = "admin"
domoticzpassword = "password"
domoticzpasscode = "passcode"
domoticzcheckssl = False
# If enabled. The script will log to the file _.log
# Logging to file only happens after the check for other instances, before that it only prints to screen.
log_to_file = False
lat = "52.379189"
lon = "4.899431"
BuienradarUrl = "https://gpsgadget.buienradar.nl/data/raintext/?lat=" + lat + "&lon=" + lon
BuienradarCheckSSL = False
Duration = 25
RainExpectedIDX = "411"
# Check silent mode for cron
silentmode = False
if (len(sys.argv)) > 1:
if (str(sys.argv[1]) == "silent"):
silentmode = True
# DO NOT CHANGE BEYOND THIS LINE
lastsuccess=datetime.datetime.now()
base64string = base64.encodestring(('%s:%s' % (domoticzusername,domoticzpassword)).encode()).decode().replace('\n', '')
def log(message):
if silentmode == False:
print(message)
if log_to_file == True:
logfile = open(sys.argv[0] + '.log', "a")
logfile.write(message + "\n")
logfile.close()
def domoticzrequest(url):
request = urllib.request.Request(url)
request.add_header("Authorization", "Basic %s" % base64string)
if (domoticzcheckssl == False):
response = urllib.request.urlopen(request, context=ssl._create_unverified_context())
else:
response = urllib.request.urlopen(request)
return response.read()
def domoticzstatus(getIDX):
domoticzurl = domoticzserver + '/json.htm?type=devices&rid=' + getIDX
json_object = json.loads(domoticzrequest(domoticzurl).decode('utf-8'))
status = ''
# Search the device in JSON list
if json_object["status"] == "OK":
status = json_object["result"][0]["Data"]
else:
log (datetime.datetime.now().strftime("%H:%M:%S") + " - Error: Could not find device idx " + getIDX + " in Domoticz response.")
return status
log (datetime.datetime.now().strftime("%H:%M:%S") + " - Script buienradar.py started.")
# Get current starttime and endtime
now = datetime.datetime.now().strftime("%H:%M")
hour, min = now.split(":")
starttime = (int(hour)*60) + int(min)
endtime = starttime + Duration
total_rain_predictions = 0
total_rain_values = 0
# Get buienradar data
request = urllib.request.Request(BuienradarUrl)
if (BuienradarCheckSSL == False):
response = urllib.request.urlopen(request, context=ssl._create_unverified_context())
else:
response = urllib.request.urlopen(request)
html = response.read() # read the data
# 000|hh:mm where 000 is mm of rain expected (000 -> no rain, 255 -> heavy rain)
for line in html.splitlines():
#print("rain: " + data[0] + " time:" + data[1])
data = line.decode('utf-8').split("|")
mhour, mmin = data[1].split(":")
calc_time = (int(mhour)*60) + int(mmin)
if ((calc_time >= starttime) and (calc_time <= endtime)):
total_rain_predictions = total_rain_predictions + float(data[0])
total_rain_values = total_rain_values + 1
response.close() # close the connection
# Calculate result
result = "0.00"
if (total_rain_values > 0):
rain_0_100 = (total_rain_predictions/total_rain_values)*0.392156862745098 # convert 000/255 data to procent (100/255)
result = format(rain_0_100, '.2f')
currentstatus = format(int(''.join(filter(str.isdigit, domoticzstatus(RainExpectedIDX)))), '.2f')
if (result != currentstatus): # Status has changed --> notify domoticz
log (datetime.datetime.now().strftime("%H:%M:%S") + " - Current status: " + currentstatus + " / result: " + result)
domoticzrequest(domoticzserver + "/json.htm?type=command¶m=udevice&idx=" + RainExpectedIDX + "&nvalue=0&svalue=" + result + "&passcode=" + domoticzpasscode)
else:
if (hour == 12 and min < 10): # Send some data to prevent a red bar --> notify domoticz
log (datetime.datetime.now().strftime("%H:%M:%S") + " - Current status: " + currentstatus + " / updating")
domoticzrequest(domoticzserver + "/json.htm?type=command¶m=udevice&idx=" + RainExpectedIDX + "&nvalue=0&svalue=0.00&passcode=" + domoticzpasscode)