###########################################################################
# Beispiel: Steuerung nach Sonnenzyklus mit Zeitfenster
#
# Aufgabenstellung: Ein Rolladen soll eine Stunde nach Sonnenuntergang
# schliessen, aber fruehestens um 20:00 und spaetestens um 22:00
#
# Loesungsansatz: Es werden zwei at-Jobs zu festen Zeiten eingeplant, um 
# 20:00 und um 22:00, zusaetzlich existiert ein at-Job, der mit der  
# variablen Zeit "sunset_rel(3600)" eingeplant ist. Die einzelnen Jobs 
# verwenden ein benutzerdefiniertes Attribut "freigabe", um untereinander 
# Informationen auszutauschen.
#
# Funktionsweise: Der erste ablaufende Job prueft den Zustand des Attributs
# "freigabe". Wenn es existiert, wird der Rolladen geschlossen und das
# Attribut geloescht. Wenn nicht, wird das Attribut gesetzt, der Rolladen
# aber nicht geschlossen. Der naechste Job findet dann ein gesetztes Attribut
# vor, schliesst den Rolladen und loescht das Atribut. Der 22:00-Job, der
# das Ende des Zeitfensters darstellt, loescht das Attribut und schliesst 
# den Rolladen, falls noch nicht geschehen.
#
# Sonnenuntergang um 18:30:
#   um 19:30 laeuft der variable Job und setzt das Attribut
#   um 20:00 laeuft der fixe Job 1 und schliesst den Rolladen
#   um 22:00 laeuft der fixe Job 2 (und veraendert nichts)
# Sonnenuntergang um 20:30:
#   um 20:00 laeuft der fixe Job 1 und setzt das Attribut
#   um 21:30 laeuft der variable Job und schliesst den Rolladen
#   um 22:00 laeuft der fixe Job 2 (und veraendert nichts)
# Sonnenuntergang um 22:30:
#   um 20:00 laeuft der fixe Job 1 und setzt das Attribut
#   um 22:00 laeuft der fixe Job 2 und schliesst den Rolladen
#   um 23:30 laeuft der variable Job (und veraendert nichts)
###########################################################################
# example: sunset-dependent action within fixed-time boundaries
#
# task: A shutter is to be closed one hour past sunset, but not before
# 20:00 and at 22:00 at the latest.
#
# solution: Two fixed-time jobs at 20:00 and 22:00, respectively, mark the 
# desired "window of opportunity". A time-variable job is scheduled for one 
# hour past sunset ("sunset_rel(3600)"). The jobs use a user defined attribute
# named "freigabe" ("permission" in german) to exchange information.

# How it works: The first job checks the status of the attribute. If it's set,
# the shutter is closed and the attribute is deleted. If the attribute doesn't
# exist, it is set but the shutter will not be closed. The next job running 
# then finds the attribute set and therefore closes the shutter and deletes 
# the attribute. The job running at 22:00 unconditionally deletes the attribute 
# and closes the shutter, if it's still open.
#
# sunset at 18:30:
#   at 19:30 the time-variable job runs and sets the attribute
#   at 20:00 fixed job 1 runs and closes the shutter
#   at 22:00 fixed job 2 runs (and changes nothing)
# sunset at 20:30:
#   at 20:00 fixed job 1 runs and sets the attribute
#   at 21:30 the time-variable job runs and closes the shutter
#   at 22:00 fixed job 2 runs (and changes nothing)
# sunset at 22:30:
#   at 20:00 fixed job 1 runs and sets the attribute
#   at 22:00 fixed job 2 runs and closes the shutter
#   at 23:30 the time-variable job runs (and changes nothing)
###########################################################################

# Globale Einstellungen
# global settings

attr global logfile /tmp/fhem.log
attr global statefile /tmp/fhem.save
attr global pidfilename /var/run/fhem.pid
attr global verbose 3
attr global port 7072
attr global modpath /usr/share/fhem

# Die Definition des Attributs "freigabe"
# definition of attribute "freigabe"

attr global userattr freigabe

define FHZ FHZ /dev/ttyUSB0        

# devices

define roll_eg_wz1  FS20 fb02 0c fg f2 lm 8f

##########################################################################
# Timing-Funktionen
# timed jobs
##########################################################################

define roll_wz1_off1 at *20:00:00 {             \
  if( $value{roll_eg_wz1} ne "off" ) {          \
    if( $attr{roll_eg_wz1}{freigabe} ) {        \
        fhem("set roll_eg_wz1 off");;           \
        fhem("deleteattr roll_eg_wz1 freigabe") \
    } else {                                    \
        fhem("attr roll_eg_wz1 freigabe")       \
    }                                           \
  }                                             \
}

define roll_wz1_off2 at +*{sunset_rel(+3600)}   {\
  if( $value{roll_eg_wz1} ne "off" ) {          \
    if( $attr{roll_eg_wz1}{freigabe} ) {        \
        fhem("set roll_eg_wz1 off");;           \
        fhem("deleteattr roll_eg_wz1 freigabe") \
    } else {                                    \
        fhem("attr roll_eg_wz1 freigabe")       \
    }                                           \
  }                                             \
}

define roll_wz1_off3 at *22:00:00 {\
  fhem("set roll_eg_wz1 off") if($value{roll_eg_wz1} ne "off");; \
  fhem("deleteattr roll_eg_wz1 freigabe") }