Skip to content

Instantly share code, notes, and snippets.

@jpmens
Last active February 11, 2016 23:58
Show Gist options
  • Save jpmens/8897584 to your computer and use it in GitHub Desktop.
Save jpmens/8897584 to your computer and use it in GitHub Desktop.
openHAB sunrise / sunset

I use an MQTT 'bus' to communicate with openHAB.

forecast-io.py queries a weather service once an hour and publishes retained messages to MQTT at, say,

home/weather/today/sunsetTime 1391963342
home/weather/today/sunsetTime-iso 2014-02-09T17:29:02
home/weather/today/sunsetTime-hhmm 17:29

(note that some of these values are calculated by the program, and not retrieved from the service)

#!/usr/bin/env python
# Jan-Piet Mens, February 2013
import paho.mqtt.client as paho
import urllib2
import json
import time
import datetime
import sys
apikey = 'xxxxxxxxxxx'
lat = "nn.nnnn"
lon = "mm.mmmmm"
broker = 'localhost'
broker_port = 1883
root_topic = 'home/weather'
delay = (60 * 60)
retain=True
def get_forecastio(lat, lon, apikey, tics, units="si"):
URL = 'https://api.forecast.io/forecast/%s/%s,%s,%s?units=%s' % (
apikey, lat, lon, tics, units)
data = None
try:
response = urllib2.urlopen(URL)
data = json.loads(response.read())
except Exception, e:
print "Cannot get or decode %s: %s" % (URL, str(e))
return data
def data2topics(mqttc, branch, data, keys=None):
for k in data.keys():
if keys is not None and k not in keys:
continue
topic = '%s/%s/%s' % (root_topic, branch, k)
payload = data[k]
mqttc.publish(topic, str(payload), qos=0, retain=retain)
# print "%s: %s" % (topic, payload)
# Also create ISO timestamp and HH:MM format for time values
if 'Time' in k or 'time' in k:
topic_iso = '%s-iso' % topic
dt = datetime.datetime.fromtimestamp(int(payload))
mqttc.publish(topic_iso, str(dt.isoformat()), qos=0, retain=retain)
topic_hhmm = '%s-hhmm' % topic
hh_mm = dt.strftime('%H:%M')
mqttc.publish(topic_hhmm, str(hh_mm), qos=0, retain=retain)
if __name__ == '__main__':
keys = [
'cloudCover',
'temperatureMin',
'summary',
'temperatureMax',
'moonPhase',
'sunsetTime',
'precipProbability',
'icon',
'humidity',
'windSpeed',
'time',
'precipIntensity',
'sunriseTime',
]
mqttc = paho.Client('forecastio1', clean_session=True)
mqttc.connect(broker, broker_port, 60)
mqttc.loop_start()
while True:
try:
tics = int(time.time())
data = get_forecastio(lat, lon, apikey, tics)
if data is not None:
data2topics(mqttc, 'current', data['currently'], None)
daily_data = data['daily']['data'][0]
data2topics(mqttc, 'today', daily_data, keys)
morrow = tics + (24 * 60 * 60)
data = get_forecastio(lat, lon, apikey, morrow)
if data is not None:
daily_data = data['daily']['data'][0]
data2topics(mqttc, 'tomorrow', daily_data, keys)
time.sleep(delay)
except KeyboardInterrupt:
break
except:
raise
mqttc.loop_stop()
mqttc.disconnect()
Group Sun
// query the sunrise/sunset times from retained MQTT topics
// home/weather/today/sunsetTime-hhmm 17:17
// home/weather/today/sunriseTime-hhmm 08:04
String SunRiseTime
"Sunrise [%s]"
<sun>
(Sun)
{ mqtt="<[hippo:home/weather/today/sunriseTime-hhmm:state:REGEX((.*))]" }
String SunSetTime
"Sunset [%s]"
<moon>
(Sun)
{ mqtt="<[hippo:home/weather/today/sunsetTime-hhmm:state:REGEX((.*))]" }
import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import org.joda.time.*
var Timer tIndoorLights
rule "React to sunset"
when
Time cron "0 15 13 * * ?" // Every day 13:15 hours, evaluate sunset
then
var year = now.getYear
var month = now.getMonthOfYear
var day = now.getDayOfMonth
var datum = year+"-"+month+"-"+day+" "+ SunSetTime.state
logInfo("Sunset","datum = " + datum)
var DateTime sunset = parse(year+"-"+month+"-"+day+"T"+ SunSetTime.state)
var minutes = 15 // minutes before sunset
/*
* Indoor Lights
*/
// Cancel timer to avoid reschedule
if(tIndoorLights!=null) {
logInfo("Sunset","Timer tIndoorLights cancelled")
tIndoorLights.cancel()
}
logInfo("Sunset","Timer tIndoorLights created")
tIndoorLights = createTimer(sunset.minusMinutes(minutes)) [|
logInfo("Sunset","Timer tIndoorLights executed")
sendCommand(Z_Fireplace, ON)
sendCommand(Z_Dining, ON)
]
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment