Moin,
ich habe mir mal ein SingleAction Event in DoorPi gebastelt. Hatte überlegt es einzusetllen und dieses Thema dazu hier gesehen. Daher füge ich es einfach mal hier an. Dann bekommt ihr alle eine Info, da Ihr schon dran gearbeitet habt.
Die Class "sun" (Berechnung Sonnenaufgang/Untergang) habe ich mit in die *.py eingefügt von http://michelanders.blogspot.c…and-sunset-in-python.html. Da habe ich mir keine Mühe gemacht, das neu zu erfinden.
Über einen oder mehrere EVENTS (siehe unten) wird der SingleAction "sunset" aufgerufen. Übergabe gibt es 2 Werte, der erste ist das Script was bei Sonnenaufgang ausgeführt wird, das andere bei Sonnenuntergang. Über Einträge in der DoorPi (siehe auch unten) werden der Ort und evtl. Delays übergeben. Delay kann auch negativ sein und entspricht Minuten. Das SCript übergebene Script wird nur beim Tag/Nacht und Nacht/Tag Wechsel ausgeführt und nicht dauerhaft am Tag. Umso geringer der EVENT (also every Minute statt every Stunde) umso genau wird es am eigentlichen Sonnenaufgang Wert ausgeführt.
Viel Spass
- Python tzlocal installieren https://pypi.python.org/pypi/tzlocal
sudo pip install tzlocal
- Script abspeichern
sunset.py im Verzeichnis /action/SingleAction/ (siehe unten)
- doorpi.ini Einträge
[SunSet]
location_lat = 52.386 # Default = 52.509 (Berlin BRB Tor)
location_long = 13.261 # Default = 13.376 (Berlin BRB Tor)
sunrise_delay = 60 # Default = 0
sunset_delay = 60 # Default = 0
- ACTION
[EVENT_OnTimeMinute30]
10 = sunset:/usr/local/etc/DoorPi/script/sunrise.sh,/usr/local/etc/DoorPi/script/sunset.sh
- sunset.sh oder sunrise.sh (natürlich ausführbar)
curl -s -k "http://<IP>/cgi-bin/hi3510/param.cgi?cmd=setinfrared&-infraredstat=open"
sunset.py
# -*- coding: utf-8 -*-
# created by Kater432
# function sun included from http://michelanders.blogspot.co.uk/2010/12/calulating-sunrise-and-sunset-in-python.html
import logging
logger = logging.getLogger(__name__)
logger.debug("%s loaded", __name__)
from doorpi.action.base import SingleAction
import doorpi
import subprocess
from math import cos, sin, acos, asin, tan
from math import degrees as deg, radians as rad
from datetime import date, datetime, time, timedelta
from tzlocal import get_localzone # Zeitzone rausfinden
# from url_call import fire_command
def fire_sunrise(cmd_sunrise, cmd_sunset):
try:
location_lat = doorpi.DoorPi().config.get_float('SunSet', 'location_lat', 52.509)
location_long = doorpi.DoorPi().config.get_float('SunSet', 'location_long', 13.376)
sunrise_delay = doorpi.DoorPi().config.get_integer('SunSet', 'sunrise_delay', 0)
sunset_delay = doorpi.DoorPi().config.get_integer('SunSet', 'sunset_delay', 0)
day = doorpi.DoorPi().config.get('SunSet', 'day', False)
current = datetime.combine(date.today(),
time(datetime.now().hour, datetime.now().minute, datetime.now().second, 0))
sunrise = datetime.combine(date.today(),
sun(location_lat, location_long).sunrise(datetime.now(get_localzone())))
sunset = datetime.combine(date.today(), sun(location_lat, location_long).sunset(datetime.now(get_localzone())))
if current >= (sunrise + timedelta(0, 0, 0, 0, sunrise_delay)) and current <= (
sunset + timedelta(0, 0, 0, 0, sunset_delay)) and not day: # Aufgang + Delay
doorpi.DoorPi().config.set_value('SunSet', 'day', True)
logger.trace("SONNENAUFGANG mit Delay[{}]".format(sunrise + timedelta(0, 0, 0, 0, sunrise_delay)))
# fire_command(cmd_sunrise) # optional über url_call
return subprocess.Popen(
cmd_sunrise,
shell=True,
stdout=subprocess.PIPE
).stdout.read()
else:
if current >= (sunset + timedelta(0, 0, 0, 0, sunset_delay)) and day: # Untergang + Delay
doorpi.DoorPi().config.set_value('SunSet', 'day', False)
logger.trace("SONNENUNTERGANG mit Delay[{}]".format(sunset + timedelta(0, 0, 0, 0, sunset_delay)))
# fire_command(cmd_sunset)
return subprocess.Popen(
cmd_sunset,
shell=True,
stdout=subprocess.PIPE
).stdout.read()
else:
logger.trace("NothingToDo {}".format(current))
except Exception as ex:
logger.exception('--------------Exception------------------')
return False
return True
def get(parameters):
parameter_list = parameters.split(',')
if len(parameter_list) < 2 or len(parameter_list) > 2: return None
cmd_sunrise = parameter_list[0]
cmd_sunset = parameter_list[1]
return SunRiseAction(fire_sunrise,
cmd_sunrise=cmd_sunrise,
cmd_sunset=cmd_sunset)
class SunRiseAction(SingleAction):
pass
# function sun from http://michelanders.blogspot.co.uk/2010/12/calulating-sunrise-and-sunset-in-python.html
class sun:
"""
Calculate sunrise and sunset based on equations from NOAA
http://www.srrb.noaa.gov/highlights/sunrise/calcdetails.html
typical use, calculating the sunrise at the present day:
import datetime
import sunrise
s = sun(lat=49,long=3)
print('sunrise at ',s.sunrise(when=datetime.datetime.now())
"""
def __init__(self, lat=52.37, long=4.90): # default Amsterdam
self.lat = lat
self.long = long
def sunrise(self, when=None):
"""
return the time of sunrise as a datetime.time object
when is a datetime.datetime object. If none is given
a local time zone is assumed (including daylight saving
if present)
"""
if when is None: when = datetime.now(tz=LocalTimezone())
self.__preptime(when)
self.__calc()
return sun.__timefromdecimalday(self.sunrise_t)
def sunset(self, when=None):
if when is None: when = datetime.now(tz=LocalTimezone())
self.__preptime(when)
self.__calc()
return sun.__timefromdecimalday(self.sunset_t)
def solarnoon(self, when=None):
if when is None: when = datetime.now(tz=LocalTimezone())
self.__preptime(when)
self.__calc()
return sun.__timefromdecimalday(self.solarnoon_t)
@staticmethod
def __timefromdecimalday(day):
"""
returns a datetime.time object.
day is a decimal day between 0.0 and 1.0, e.g. noon = 0.5
"""
hours = 24.0 * day
h = int(hours)
minutes = (hours - h) * 60
m = int(minutes)
seconds = (minutes - m) * 60
s = int(seconds)
return time(hour=h, minute=m, second=s)
def __preptime(self, when):
"""
Extract information in a suitable format from when,
a datetime.datetime object.
"""
# datetime days are numbered in the Gregorian calendar
# while the calculations from NOAA are distibuted as
# OpenOffice spreadsheets with days numbered from
# 1/1/1900. The difference are those numbers taken for
# 18/12/2010
self.day = when.toordinal() - (734124 - 40529)
t = when.time()
self.time = (t.hour + t.minute / 60.0 + t.second / 3600.0) / 24.0
self.timezone = 0
offset = when.utcoffset()
if not offset is None:
self.timezone = offset.seconds / 3600.0
def __calc(self):
"""
Perform the actual calculations for sunrise, sunset and
a number of related quantities.
The results are stored in the instance variables
sunrise_t, sunset_t and solarnoon_t
"""
timezone = self.timezone # in hours, east is positive
longitude = self.long # in decimal degrees, east is positive
latitude = self.lat # in decimal degrees, north is positive
time = self.time # percentage past midnight, i.e. noon is 0.5
day = self.day # daynumber 1=1/1/1900
Jday = day + 2415018.5 + time - timezone / 24 # Julian day
Jcent = (Jday - 2451545) / 36525 # Julian century
Manom = 357.52911 + Jcent * (35999.05029 - 0.0001537 * Jcent)
Mlong = 280.46646 + Jcent * (36000.76983 + Jcent * 0.0003032) % 360
Eccent = 0.016708634 - Jcent * (0.000042037 + 0.0001537 * Jcent)
Mobliq = 23 + (26 + ((21.448 - Jcent * (46.815 + Jcent * (0.00059 - Jcent * 0.001813)))) / 60) / 60
obliq = Mobliq + 0.00256 * cos(rad(125.04 - 1934.136 * Jcent))
vary = tan(rad(obliq / 2)) * tan(rad(obliq / 2))
Seqcent = sin(rad(Manom)) * (1.914602 - Jcent * (0.004817 + 0.000014 * Jcent)) + sin(rad(2 * Manom)) * (
0.019993 - 0.000101 * Jcent) + sin(rad(3 * Manom)) * 0.000289
Struelong = Mlong + Seqcent
Sapplong = Struelong - 0.00569 - 0.00478 * sin(rad(125.04 - 1934.136 * Jcent))
declination = deg(asin(sin(rad(obliq)) * sin(rad(Sapplong))))
eqtime = 4 * deg(
vary * sin(2 * rad(Mlong)) - 2 * Eccent * sin(rad(Manom)) + 4 * Eccent * vary * sin(rad(Manom)) * cos(
2 * rad(Mlong)) - 0.5 * vary * vary * sin(4 * rad(Mlong)) - 1.25 * Eccent * Eccent * sin(
2 * rad(Manom)))
hourangle = deg(acos(cos(rad(90.833)) / (cos(rad(latitude)) * cos(rad(declination))) - tan(rad(latitude)) * tan(
rad(declination))))
self.solarnoon_t = (720 - 4 * longitude - eqtime + timezone * 60) / 1440
self.sunrise_t = self.solarnoon_t - hourangle * 4 / 1440
self.sunset_t = self.solarnoon_t + hourangle * 4 / 1440
Alles anzeigen