Gå til innhold
  • Bli medlem
Støtt hjemmeautomasjon.no!

Lysstyring ved hjelp av pyscript


Anbefalte innlegg

Det var snakk om dette for noen dager siden og jeg tenkte jeg kunne poste mitt oppsett så kan eventuelt noen bruke det som et eksempel til eget bruk. Jeg har lagd mitt system slik at det baserer seg på scener. Men det er ikke 100% basert på dette. For å slå av lys så blir turn_off på light domene brukt. Her kunne en brukt en scene for å slå av også og da kunne dette vært brukt til andre ting enn lys også.

Jeg har lagd det pyscript kaller en "app". I config.yaml er alt lys satt opp som dette. Har lagt inn noen kommentarer. I tillegg er det lagd slik at bryter veksler mellom scene ved gjentatt trykk på "lys på". Når en bruker bryter til å aktivere scene så skjer dette umiddelbart, men blir en scene aktivert av betingelser så skjer dette ved hjelp av en konfigururbar "transition". Lys over garasjeport blir for eksempel endret over 1 time. Selve koden kommer i et innlegg nedenfor.

 

apps:
    scenestyring:
      - id: lys_stue # unik id for denne appen
        sensors:  # Liste med sensorer som trigger lys. Denne listen trenger ikke være med hvis en bruker en veggbryter for å styre lys
          - binary_sensor.stue_og_kjokken_presence
        lightlevelsensor: sensor.stue_og_kjokken_lightlevel  # Lysnivå-sensor hvis en ikke vil at lys skal slås på dersom det ikke er mørkt
        lightlevel: 95
        switchID: stue_bryter  # Denne er valgfri og styrer lys manuelt. Dersom lys er slått på manuelt så vil det stå på til det blir slått av manuelt.
        lightID: light.stue # ID på lys som skal slås av. Her har jeg brukt en lysgruppe
        delay: 7200 # Antall sekunder lys skal stå på før det automatisk blir slått av.
        Transition: 600 # Antall sekunder en skal bruke på å aktivere normal scene dersom betingelsene for det er oppfylt. Dette gjelder kun hvis en annen scene er aktiv. Er lys av så blir en scene aktivert umiddelbart. En vil jo ha det lyst med en gang en kommer inn i et rom.
        SceneNormal: scene.stue_normal # Scene som skal aktiveres dersom ingen andre betingelser er oppfylt. Den blir på en måte "default" scene.
        scenes: # Dette er en liste med betingelser knyttet opp mot scene som skal aktiveres dersom lys slås på. Disse scenene blir også aktivert dersom lys allerede er påslått automatisk av bevegelsesensor.
          scene1:
            name: scene.stue_natt # Dette er nattlys og gjelder når input_boolean.sleeptime er on. Det går 130 sekund til lyset går av igjen
            sensor: input_boolean.sleeptime
            state: "on"
            delay: 130
          scene2:
            name: scene.stue_besok
            sensor: input_boolean.visitors_comfort_temp
            state: "on"
          scene3:
            name: scene.stue_kveld
            sensor: binary_sensor.dark_outside
            state: "on"
      - id: lys_kjokken
        sensors:
          - binary_sensor.stue_og_kjokken_presence
        lightlevelsensor: sensor.stue_og_kjokken_lightlevel
        lightlevel: 95
        switchID: kjoekken_bryter
        lightID: light.kjoekken
        delay: 7200
        Transition: 600
        SceneNormal: scene.kjoekken_normal
        scenes:
          scene1:
            name: scene.kjokken_natt
            sensor: input_boolean.sleeptime
            state: "on"
            delay: 130
          scene2:
            name: scene.kjokken_besok
            sensor: input_boolean.visitors_comfort_temp
            state: "on"
          scene3:
            name: scene.kjokken_kveld
            sensor: binary_sensor.dark_outside
            state: "on"
      - id: lys_vaskerom
        sensors:
          - binary_sensor.vaskerom_presence
        switchID: vaskerom_bryter
        lightlevelsensor: sensor.vaskerom_lightlevel
        lightlevel: 1000
        lightID: light.vaskerom
        delay: 600
        Transition: 600
        SceneNormal: scene.vaskerom_normal
        scenes:
          scene1:
            name: scene.vaskerom_nattlys
            sensor: binary_sensor.lysstyrke
            state: "off"
            delay: 130
          scene2:
            name: scene.vaskerom_kveld
            sensor: binary_sensor.dark_outside
            state: "on"
            delay: 900 # På vaskerom går lys av igjen etter 600s på dagtid, 900s på kveldstid og etter 130s på nattetid.
      - id: lys_gang_1_etg
        sensors: # Lys i gang styres av bevegelse sensor, men også dør og garasjeport.
          - binary_sensor.gang_1_etg_presence
          - binary_sensor.hoveddor
          - binary_sensor.garasjeport
        switchID: gang_1_etg_bryter
        lightlevelsensor: sensor.gang_1_etg_lightlevel
        lightlevel: 25
        lightID: light.gang_1_etg
        Transition: 600
        SceneNormal: scene.gang_1_etg_normal
        scenes:
          scene1:
            name: scene.gang_1_etg_nattlys
            sensor: input_boolean.sleeptime
            state: "on"
            delay: 130
          scene2:
            name: scene.gang_1_etg_kveld
            sensor: binary_sensor.dark_outside
            state: "on"
            delay: 7200
        delay: 7200
      - id: lys_gang_u_etg
        sensors:
          - binary_sensor.gang_u_etg_presence
          - binary_sensor.hoveddor_u_etg
        switchID: gang_u_etg_bryter
        lightlevelsensor: sensor.gang_u_etg_lightlevel
        lightlevel: 25
        lightID: light.gang_u_etg
        Transition: 60
        SceneNormal: scene.gang_u_etg_normal
        scenes:
          scene1:
            name: scene.gang_u_etg_nattlys
            sensor: binary_sensor.lysstyrke
            state: "off"
            delay: 240
          scene2:
            name: scene.gang_u_etg_kveld
            sensor: binary_sensor.dark_outside
            state: "on"
            delay: 1800
        delay: 900
      - id: lys_bad_1_etg
        sensors:
          - binary_sensor.bad_1_etg_presence
        switchID: bad_1_etg_bryter
        lightlevelsensor: sensor.bad_1_etg_lightlevel
        lightlevel: 1000
        lightID: light.bad_1_etg
        delay: 420
        Transition: 600
        SceneNormal: scene.bad_1_etg_normal
        scenes:
          scene1:
            name: scene.bad_1_etg_speil
            delay: 3
          scene2:
            name: scene.bad_1_etg_nattlys
            sensor: input_boolean.sleeptime
            state: "on"
            delay: 420
          scene3:
            name: scene.bad_1_etg_kveld
            sensor: binary_sensor.dark_outside
            state: "on"
            delay: 420
      - id: lys_bad_u_etg
        sensors:
          - binary_sensor.bad_u_etg_presence
        switchID: bad_u_etg_bryter
        lightlevelsensor: sensor.bad_u_etg_lightlevel
        lightlevel: 1000
        lightID: light.bad_u_etg
        delay: 420
        Transition: 60
        SceneNormal: scene.bad_u_etg_normal
        scenes:
          scene1:
            name: scene.bad_u_etg_speil
            delay: 3
          scene2:
            name: scene.bad_u_etg_nattlys
            sensor: binary_sensor.lysstyrke
            state: "off"
            delay: 420
          scene3:
            name: scene.bad_u_etg_kveld
            sensor: binary_sensor.dark_outside
            state: "on"
            delay: 420
      - id: lys_garasje
        sensors:
          - binary_sensor.garasje_presence
          - binary_sensor.garasjedor
          - binary_sensor.garasjeport
        switchID: garasje_bryter
        lightlevelsensor: sensor.garasje_lightlevel
        lightlevel: 150
        lightID: light.garasje
        delay: 1800
        Transition: 60
        SceneNormal: scene.garasje_normal
        scenes:
          scene1:
            name: scene.garasje_nattlys
            sensor: binary_sensor.lysstyrke
            state: "off"
            delay: 130
      - id: lys_soverom_1_etg
        switchID: soverom_1_etg_bryter
        lightID: light.soverom_1_etg
        Transition: 60
        SceneNormal: scene.soverom_1_etg_normal
        scenes:
          scene1:
            name: scene.soverom_1_etg_nattlys
          scene2:
            name: scene.soverom_1_etg_kveld
            sensor: binary_sensor.dark_outside
            state: "on"
      - id: lys_soverom_u_etg
        switchID: soverom_u_etg_bryter
        lightID: light.soverom_u_etg
        Transition: 60
        SceneNormal: scene.soverom_u_etg_normal
        scenes:
          scene1:
            name: scene.soverom_u_etg_nattlys
          scene2:
            name: scene.soverom_u_etg_kveld
            sensor: binary_sensor.dark_outside
            state: "on"
      - id: lys_gjesterom_u_etg
        switchID: gjesterom_u_etg_bryter
        lightID: light.gjesterom_u_etg
        Transition: 60
        SceneNormal: scene.gjesterom_u_etg_normal
        scenes:
          scene1:
            name: scene.gjesterom_u_etg_nattlys
          scene2:
            name: scene.gjesterom_u_etg_kveld
            sensor: binary_sensor.dark_outside
            state: "on"
      - id: lys_tv_stue
        switchID: tv_stue_bryter
        lightID: light.tv_stue
        Transition: 60
        SceneNormal: scene.tv_stue_normal
        scenes:
          scene1:
            name: scene.tv_stue_leggetid
            sensor: binary_sensor.lysstyrke
            state: "off"
            delay: 30
          scene2:
            name: scene.tv_stue_stemning
            sensor: device_tracker.tv
            state: "home"
            delay: 30
      - id: lys_kontor
        switchID: kontor_bryter
        lightID: light.kontor
        Transition: 60
        SceneNormal: scene.kontor_normal
        scenes:
          scene1:
            name: scene.kontor_kveld
            sensor: binary_sensor.dark_outside
            state: "on"
      - id: lys_bod
        sensors:
          - binary_sensor.boddor
          - binary_sensor.bod_sensor_presence
        lightID: light.bod
        delay: 600
        Transition: 60
        lightlevelsensor: sensor.bod_sensor_lightlevel
        lightlevel: 300
        SceneNormal: scene.bod_normal
        scenes:
          scene1:
            name: scene.bod_kveld
            sensor: binary_sensor.dark_outside
            state: "on"
      - id: lys_ute_1_etg
        sensors:
          - binary_sensor.utelys
        lightID: light.alt_lys_ute
        delay: 300
        Transition: 3540
        lightlevelsensor: sensor.ute_1_etg_lightlevel
        lightlevel: 500
        SceneNormal: scene.ute_normal
        scenes:
          scene1:
            name: scene.ute_farge1
            sensor: binary_sensor.utelys_farge1
            state: "on"
            Transition: 3540
          scene2:
            name: scene.ute_farge2
            sensor: binary_sensor.utelys_farge2
            state: "on"
            Transition: 3540

 

from random import randrange
from random import seed
import time

registered_triggers = []
factory_apps = []

@time_trigger('startup')
def scenestartup():
    for app in pyscript.app_config:
        factory_apps.append(LysStyring(app))

class LysStyring:
    delay = 60
    scene_index = 0

    def __init__(self, config):
        self.scene_index = 0
        self.cfg = config
        
        seed()

        state.persist(f"pyscript.scenestyring_{self.cfg['id']}_twls", default_value=0)
        state.persist(f"pyscript.scenestyring_{self.cfg['id']}_status", default_value=False)

        if "delay" in self.cfg:
            self.delay = int(self.cfg['delay'])
            @time_trigger(f"period(now, {randrange(50, 70, 1)}s)")
            def motion_delay_off_trig():
                if float(state.get(f"pyscript.scenestyring_{self.cfg['id']}_twls")) <= time.time():
                    if "sensors" in self.cfg:
                        for tr in self.cfg['sensors']:
                            if state.get(f"{tr}") == "on":
                                state.set(f"pyscript.scenestyring_{self.cfg['id']}_twls", value = time.time() + self.delay)
                                return
                    
                    self.light_off()
            registered_triggers.append(motion_delay_off_trig)


        if "sensors" in self.cfg:
            for tr in self.cfg['sensors']:
                #log.info(f"Setter opp motion trigger paa {tr}")
                @state_trigger(f"{tr} == 'on' and {tr}.old == 'off'")
                def motion_trig():
                    task.unique(f"scenestyringmotion_{self.cfg['id']}")
                    self.motion()
                registered_triggers.append(motion_trig)

        if "lightlevel" in self.cfg and "lightlevelsensor" in self.cfg:
            @state_trigger(f"{self.cfg['lightlevelsensor']}")
            def lightlevel_trig():
                task.unique(f"scenestyringlightlvl_{self.cfg['id']}")
                self.lightlevel()
            registered_triggers.append(lightlevel_trig)

        if "scenes" in self.cfg:
            for tr in self.cfg['scenes']:
                if "sensor" in self.cfg['scenes'][tr]:
                    #log.info(f"Setter opp state trigger paa {self.cfg['scenes'][tr]['sensor']}")
                    @state_trigger(f"{self.cfg['scenes'][tr]['sensor']}", state_hold = randrange(1, 120, 3))
                    def statechanged_trig(var_name=None):
                        task.unique(f"scenestyringstatechg_{self.cfg['id']}_{var_name}")
                        self.statechanged()
                    registered_triggers.append(statechanged_trig)
        
        if "switchID" in self.cfg:
            @event_trigger("deconz_event", "event == 1000")
            def light_delayon(context, device_id, event_type, trigger_type, unique_id, id=None, event=None):
                if id == self.cfg['switchID']:
                    task.unique(f"scenestyringevent_{self.cfg['id']}")
                    task.sleep(0.5)
                    if self.scene_index > len(self.cfg['scenes']):
                        self.scene_index = 0
                    if self.scene_index == 0:
                        self.setscene(1)
                    else:
                        i = 1
                        for tr in self.cfg['scenes']:
                            if i == self.scene_index:
                                scene.turn_on(entity_id=self.cfg['scenes'][tr]['name'], transition = 1)
                                break
                            i += 1
                    self.scene_index += 1
            registered_triggers.append(light_delayon)

        @state_trigger(f"{self.cfg['lightID']} == 'off'")
        def clear():
            self.scene_index = 0
        registered_triggers.append(clear)

    def motion(self):
        if "lightlevel" in self.cfg and "lightlevelsensor" in self.cfg:
            lightlevellimit = float(self.cfg['lightlevel'])
            lightlevelsensor = float(state.get(f"{self.cfg['lightlevelsensor']}"))
        else:
            lightlevellimit = 1
            lightlevelsensor = 0

        if lightlevelsensor < lightlevellimit:
            if state.get(f"{self.cfg['lightID']}") == "off":
                self.setscene(1.75)
                state.set(f"pyscript.scenestyring_{self.cfg['id']}_status", value = True)
                self.scene_index = 1
            
            state.set(f"pyscript.scenestyring_{self.cfg['id']}_twls", value = time.time() + self.delay)

    def light_off(self):
        if state.get(f"pyscript.scenestyring_{self.cfg['id']}_status") == "True":
            light.turn_off(entity_id = self.cfg['lightID'])
            state.set(f"pyscript.scenestyring_{self.cfg['id']}_status", value = False)

    def lightlevel(self):
        try:
            if state.get(f"pyscript.scenestyring_{self.cfg['id']}_status") == "True" and (float(state.get(f"{self.cfg['lightlevelsensor']}")) > float(self.cfg['lightlevel']) * 2.0):
                light.turn_off(entity_id = self.cfg['lightID'])
                state.set(f"pyscript.scenestyring_{self.cfg['id']}_status", value = False)
        except ValueError:
            pass

    def statechanged(self):
        if state.get(f"{self.cfg['lightID']}") == "on":
            self.setscene(-1)
    
    def setscene(self, trans):
        s = self.cfg['SceneNormal']
        if "delay" in self.cfg:
            self.delay = self.cfg['delay']
        t = int(self.cfg['Transition'])
        
        if "scenes" in self.cfg:
            for tr in self.cfg['scenes']:
                if ("sensor" in self.cfg['scenes'][tr]
                        and "state" in self.cfg['scenes'][tr] 
                        and state.get(f"{self.cfg['scenes'][tr]['sensor']}") == self.cfg['scenes'][tr]['state']):
                    
                    s = self.cfg['scenes'][tr]['name']
                    if "delay" in self.cfg['scenes'][tr]:
                        self.delay = self.cfg['scenes'][tr]['delay']
                    if "Transition" in self.cfg['scenes'][tr]:
                        t = int(self.cfg['scenes'][tr]['Transition'])
                    break
        
        if trans < 0:
            trans = t
        
        scene.turn_on(entity_id = s, transition = trans)

 

Bare for å presisere. Normal scene er den som aktiveres hvis scene1 til sceneX ikke har betingelser som gjør at de blir valgt.

  • Like 2
Lenke til kommentar
Del på andre sider

Bli med i samtalen

Du kan publisere innhold nå og registrere deg senere. Hvis du har en konto, logg inn nå for å poste med kontoen din.

Gjest
Skriv svar til emnet...

×   Du har limt inn tekst med formatering.   Lim inn uten formatering i stedet

  Du kan kun bruke opp til 75 smilefjes.

×   Lenken din har blitt bygget inn på siden automatisk.   Vis som en ordinær lenke i stedet

×   Tidligere tekst har blitt gjenopprettet.   Tøm tekstverktøy

×   Du kan ikke lime inn bilder direkte. Last opp eller legg inn bilder fra URL.

×
×
  • Opprett ny...

Viktig informasjon

Vi har plassert informasjonskapsler/cookies på din enhet for å gjøre denne siden bedre. Du kan justere dine innstillinger for informasjonskapsler, ellers vil vi anta at dette er ok for deg.