Ankündigung

Einklappen
Keine Ankündigung bisher.

Blinker.py konfigurieren

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • gama
    antwortet
    Hallo Zusammen, ich war ein paar Tage offline - sorry - und da hat sich ja einiges getan.
    Msinn, danke für das Update!

    Einen Kommentar schreiben:


  • Msinn
    antwortet
    Ich habe im Blog Artikel die überarbeitete Version der Logik mit Hinweis auf diesen Thread ergänzt.

    Einen Kommentar schreiben:


  • Jürgen
    antwortet
    Jehova!
    Für nachfolgende Generationen: Die Variante aus #24 blinkt mit einem oder zwei Items, alles wie gewünscht.
    Prima!

    Danke für die Unterstützung, der Dummy kann nun entfernt werden.

    Gruß
    Jürgen

    Einen Kommentar schreiben:


  • Morg
    antwortet
    Code:
    #!/usr/bin/env python3
    # vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab
    
    # LOGIC config
    # -------------------------------------------------------
    # visual_alarm:
    #     filename: blinker.py
    #     watch_item: HOME.alarm.action.blinkinglight
    #     set_items_cyclic:
    #         - AUSSEN.south.light.outer
    #         - AUSSEN.west.light.outer
    #     set_items_anticyclic:
    #         - AUSSEN.south.light.inner
    #         - AUSSEN.east.light.door
    #         - AUSSEN.west.light.nested
    #     set_blink_cycles: -1 ' -1: endless
    #     set_blink_interval: 2
    #     dry_run: 0
    
    control_item_name = trigger['source']
    control_item = sh.return_item(control_item_name)
    triggered_by = trigger['by']
    
    if control_item is not None:
        logger.info(f'LOGIC blinker.py: {logic.name} triggered from source {control_item_name} by {triggered_by}')
    
        # control_item_active = trigger['value']
        control_item_active = control_item()
    
        # set parameters from logic config
        blink_items_cyclic = []
        if hasattr(logic, 'set_items_cyclic'):
            blink_items_cyclic = logic.set_items_cyclic
        if blink_items_cyclic == 'None':
            blink_items_cyclic = []
        if isinstance(blink_items_cyclic, str):
            blink_items_cyclic = [blink_items_cyclic, ]
    
        # do we have blink items?
        if not isinstance(blink_items_cyclic, list) or len(blink_items_cyclic) == 0:
            logger.info('LOGIC blinker.py: error, no cyclic blink items set. Aborting')
        else:
    
            blink_items_anticyclic = []
            if hasattr(logic, 'set_items_anticyclic'):
                blink_items_anticyclic = logic.set_items_anticyclic
            if blink_items_anticyclic == 'None':
                blink_items_anticyclic = []
            elif isinstance(blink_items_anticyclic, str):
                blink_items_anticyclic = [blink_items_anticyclic, ]
    
            # did we get strange data?
            if not isinstance(blink_items_anticyclic, list):
                blink_items_anticyclic = []
    
            if hasattr(logic, 'set_blink_cycles'):
                blink_cycles = int(logic.set_blink_cycles)
            else:
                blink_cycles = 2
                logger.info(f'LOGIC blinker.py: no blink cycles set, setting to default: {blink_cycles}')
    
            if hasattr(logic, 'set_blink_interval'):
                blink_interval = int(logic.set_blink_interval)
            else:
                blink_interval = 2
                logger.info(f'LOGIC blinker.py: no blink interval set, setting to default: {blink_interval}')
    
            if hasattr(logic, 'dry_run'):
                dry_run = (int(logic.dry_run) > 0)
            else:
                dry_run = False
    
            if control_item_active:
    
                # first call?
                if not hasattr(logic, 'blink_init'):
                    logger.info(f'LOGIC blinker.py: initiating {blink_cycles} blinks for {len(blink_items_cyclic)} cyclic and {len(blink_items_anticyclic)} anti-cyclic items')
                    logic.blink_init = True
    
                    blink_items = blink_items_cyclic + blink_items_anticyclic
                    if len(blink_items) > 0:
                        # SAVE item states
                        logic.saved_items = {}
                        for item_name in blink_items:
                            item = sh.return_item(item_name)
                            if item:
                                logic.saved_items[item_name] = item()
                                logger.info(f'LOGIC blinker.py: save {item_name} = {item()}')
    
                        if dry_run:
                            logger.warn('LOGIC blinker.py: test mode, dry run active')
    
                    else:
                        logger.warn('LOGIC blinker.py: no blink items set')
    
                # prepare blink
                if hasattr(logic, 'blink_value'):
                    logic.blink_value = not logic.blink_value
                else:
                    logic.blink_value = True
    
                if hasattr(logic, 'blink_countdown'):
                    logic.blink_countdown -= 1
                else:
                    logic.blink_countdown = blink_cycles
    
                # any blinks left?
                if logic.blink_countdown > 0 or blink_cycles == -1:
                    if blink_cycles == -1:
                        logger.info('LOGIC blinker.py BLINK (endless)')
                    else:
                        logger.info(f'LOGIC blinker.py BLINK ({logic.blink_countdown} cycles remaining)')
    
                    # set all cyclic items
                    for item_name in blink_items_cyclic:
                        item = sh.return_item(item_name)
                        logger.info(f'LOGIC blinker.py SET {item_name} to {logic.blink_value}')
                        if not dry_run:
                            item(logic.blink_value)
                            print(f'    - {item.id()}:{item()}')
    
                    # set all anti-cyclic items
                    for item_name in blink_items_anticyclic:
                        item = sh.return_item(item_name)
                        logger.info(f'LOGIC blinker.py SET {item_name} to {not logic.blink_value}')
                        if not dry_run:
                            item(not logic.blink_value)
                            print(f'    - {item.id()}:{item()}')
    
                    sh.trigger(f'logics.{logic.name}', by=trigger['by'], source=trigger['source'], value=trigger['value'], dt=sh.now() + datetime.timedelta(seconds=blink_interval))
    
                else:
                    logger.info('LOGIC blinker.py countdown finished, set control item to False')
                    control_item(False)  # this triggers logic again!
    
            else:
                logger.info('LOGIC blinker.py control item set to false: stop blink logic, restore saved item values')
    
                # RESTORE item states
                if hasattr(logic, 'saved_items'):
                    for item_name in logic.saved_items:
                        item = sh.return_item(item_name)
                        value = logic.saved_items[item_name]
                        logger.info(f'LOGIC blinker.py: restore {item_name} = {item()}')
                        if not dry_run:
                            item(value)
    
                # reset persistent values
                if hasattr(logic, 'saved_items'):
                    delattr(logic, 'saved_items')
                if hasattr(logic, 'blink_countdown'):
                    delattr(logic, 'blink_countdown')
                if hasattr(logic, 'blink_value'):
                    delattr(logic, 'blink_value')
                if hasattr(logic, 'blink_init'):
                    delattr(logic, 'blink_init')
    
    else:
        logger.info('LOGIC blinker.py triggered without source... ignoring...')

    Einen Kommentar schreiben:


  • Jürgen
    antwortet
    Watchitem schaltet Blinkitem dauerhaft ein

    Einen Kommentar schreiben:


  • Morg
    antwortet
    Bei mir gehts. Was meinst du mit Blinkitem einschalten?

    Einen Kommentar schreiben:


  • Jürgen
    antwortet
    Hallo,

    die letzte Version von Morg schaltet nur zeitgleich das Blinkitem ein, blinken tut damit nix.
    Ich bin zufrieden mit der letzten Version, wenn es auch antizyklisch blinken soll, kann ich ja das Original verwenden.

    Gruß Jürgen

    Einen Kommentar schreiben:


  • Morg
    antwortet
    Mit dem aktuellen Code "muss" man es eigentlich nicht. Ich habe das so angepasst, dass er mit leeren oder nicht vorhandenen Parametern umgehen kann.

    Einen Kommentar schreiben:


  • AndreK
    antwortet
    Hi Morg und Jürgen

    Morg hat natürlich recht, da war ich vorhin noch kurz auf dem falschen Dampfer. Man muss aber dann wie im letzten Post von Morg auch

    Code:
    # set_items_anticyclic:
    auskommentieren

    Gruss Andre

    Einen Kommentar schreiben:


  • Morg
    antwortet
    Der Tip von Andre läuft gegen die Wand, wenn du items_blink_anticyclic verwendest, die verschwinden dann nämlich...

    Geht der zweite Blinker nicht, wenn du beide Blinker auf dieselbe Datei blinker.py verweist?
    Zuletzt geändert von Morg; 17.01.2021, 16:19.

    Einen Kommentar schreiben:


  • Jürgen
    antwortet
    Hallo Leuts,

    jepp, der Tipp von Andre bringt die Lösung!

    Hier der Inhalt der Datei blinker.py, speichern ins Verzeichnis /usr/local/smarthome/logics

    Code:
    #!/usr/bin/env python3
    # vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab
    
    # LOGIC config
    # -------------------------------------------------------
    # visual_alarm:
    #     filename: blinker.py
    #     watch_item: HOME.alarm.action.blinkinglight
    #     set_items_cyclic:
    #         - AUSSEN.south.light.outer
    #         - AUSSEN.west.light.outer
    #     set_items_anticyclic:
    #         - AUSSEN.south.light.inner
    #         - AUSSEN.east.light.door
    #         - AUSSEN.west.light.nested
    #     set_blink_cycles: -1 ' -1: endless
    #     set_blink_interval: 2
    #     dry_run: 0
    
    control_item_name = trigger['source']
    control_item = sh.return_item(control_item_name)
    triggered_by = trigger['by']
    
    if control_item is not None:
        logger.info(f'LOGIC blinker.py: {logic.name} triggered from source {control_item_name} by {triggered_by}')
    
        # control_item_active = trigger['value']
        control_item_active = control_item()
    
        # set parameters from logic config
        blink_items_cyclic = []
        if hasattr(logic, 'set_items_cyclic'):
            blink_items_cyclic = logic.set_items_cyclic
        if isinstance(blink_items_cyclic, str):
            blink_items_cyclic = [blink_items_cyclic, ]
    
        # do we have blink items?
        if not isinstance(blink_items_cyclic, list) or len(blink_items_cyclic) == 0:
            logger.info('LOGIC blinker.py: error, no cyclic blink items set. Aborting')
        else:
    
            blink_items_anticyclic = []
            if hasattr(logic, 'set_items_anticyclic'):
                blink_items_anticyclic = logic.set_items_anticyclic
            if isinstance(blink_items_anticyclic, str):
                blink_items_anticyclic = [blink_items_anticyclic, ]
    
            # did we get strange data?
            if not isinstance(blink_items_anticyclic, str):
                blink_items_anticyclic = []
    
            if hasattr(logic, 'set_blink_cycles'):
                blink_cycles = int(logic.set_blink_cycles)
            else:
                blink_cycles = 2
                logger.info(f'LOGIC blinker.py: no blink cycles set, setting to default: {blink_cycles}')
    
            if hasattr(logic, 'set_blink_interval'):
                blink_interval = int(logic.set_blink_interval)
            else:
                blink_interval = 2
                logger.info(f'LOGIC blinker.py: no blink interval set, setting to default: {blink_interval}')
    
            if hasattr(logic, 'dry_run'):
                dry_run = (int(logic.dry_run) > 0)
            else:
                dry_run = False
    
            if control_item_active:
    
                # first call?
                if not hasattr(logic, 'blink_init'):
                    logger.info(f'LOGIC blinker.py: initiating {blink_cycles} blinks for {len(blink_items_cyclic)} cyclic and {len(blink_items_anticyclic)} anti-cyclic items')
                    logic.blink_init = True
    
                    blink_items = blink_items_cyclic + blink_items_anticyclic
                    if len(blink_items) > 0:
                        # SAVE item states
                        logic.saved_items = {}
                        for item_name in blink_items:
                            item = sh.return_item(item_name)
                            logic.saved_items[item_name] = item()
                            logger.info(f'LOGIC blinker.py: save {item_name} = {item()}')
    
                        if dry_run:
                            logger.warn('LOGIC blinker.py: test mode, dry run active')
    
                    else:
                        logger.warn('LOGIC blinker.py: no blink items set')
    
                # prepare blink
                if hasattr(logic, 'blink_value'):
                    logic.blink_value = not logic.blink_value
                else:
                    logic.blink_value = True
    
                if hasattr(logic, 'blink_countdown'):
                    logic.blink_countdown -= 1
                else:
                    logic.blink_countdown = blink_cycles
    
                # any blinks left?
                if logic.blink_countdown > 0 or blink_cycles == -1:
                    if blink_cycles == -1:
                        logger.info('LOGIC blinker.py BLINK (endless)')
                    else:
                        logger.info(f'LOGIC blinker.py BLINK ({logic.blink_countdown} cycles remaining)')
    
                    # set all cyclic items
                    for item_name in blink_items_cyclic:
                        item = sh.return_item(item_name)
                        logger.info(f'LOGIC blinker.py SET {item_name} to {logic.blink_value}')
                        if not dry_run:
                            item(logic.blink_value)
    
                    # set all anti-cyclic items
                    for item_name in blink_items_anticyclic:
                        item = sh.return_item(item_name)
                        logger.info(f'LOGIC blinker.py SET {item_name} to {not logic.blink_value}')
                        if not dry_run:
                            item(not logic.blink_value)
    
                    sh.trigger(f'logics.{logic.name}', by=trigger['by'], source=trigger['source'], value=trigger['value'], dt=sh.now() + datetime.timedelta(seconds=blink_interval))
    
                else:
                    logger.info('LOGIC blinker.py countdown finished, set control item to False')
                    control_item(False)  # this triggers logic again!
    
            else:
                logger.info('LOGIC blinker.py control item set to false: stop blink logic, restore saved item values')
    
                # RESTORE item states
                if hasattr(logic, 'saved_items'):
                    for item_name in logic.saved_items:
                        item = sh.return_item(item_name)
                        value = logic.saved_items[item_name]
                        logger.info(f'LOGIC blinker.py: restore {item_name} = {item()}')
                        if not dry_run:
                            item(value)
    
                # reset persistent values
                if hasattr(logic, 'saved_items'):
                    delattr(logic, 'saved_items')
                if hasattr(logic, 'blink_countdown'):
                    delattr(logic, 'blink_countdown')
                if hasattr(logic, 'blink_value'):
                    delattr(logic, 'blink_value')
                if hasattr(logic, 'blink_init'):
                    delattr(logic, 'blink_init')
    
    else:
        logger.info('LOGIC blinker.py triggered without source... ignoring...')
    Die Version mit einem zweiten Blinker habe ich auch getestet:

    Blinker.py nach blinker2.py kopieren und einen weiteren Eintrag in der logic.yaml erzeugen:

    Code:
    %YAML 1.1
    ---
    #
    # etc/logic.yaml
    #
    ex_logging:
        filename: example_logging.py
    
    ex_persist:
        filename: example_persistance.py
    visual_alarm:
        filename: blinker.py
        watch_item: Erdgeschoss.Arbeitszimmer.Licht.Deckenlicht
        set_items_cyclic:
             - Erdgeschoss.Arbeitszimmer.Licht.Schranklicht
    #        - AUSSEN.south.light.outer
    #        - AUSSEN.west.light.outer
        set_items_anticyclic:
    #        - AUSSEN.south.light.inner
    #        - AUSSEN.east.light.door
    #        - AUSSEN.west.light.nested
        set_blink_cycles: -1 # -1 for endless loop
        set_blink_interval: 4
        dry_run: 0
    visual_alarm2:
        filename: blinker2.py
        watch_item: Erdgeschoss.Flur.Licht.Vitrine
        set_items_cyclic:
             - Erdgeschoss.Arbeitszimmer.Licht.Schreibtischlicht
    #        - AUSSEN.south.light.outer
    #        - AUSSEN.west.light.outer
        set_items_anticyclic:
    #        - AUSSEN.south.light.inner
    #        - AUSSEN.east.light.door
    #        - AUSSEN.west.light.nested
        set_blink_cycles: -1 # -1 for endless loop
        set_blink_interval: 4
        dry_run: 0
    Läuft!

    Danke für Eure Hilfe

    Jürgen

    Einen Kommentar schreiben:


  • Morg
    antwortet
    Äh - ne, das ist falsch. Wenn du das machst, dann gehts gar nicht. Er soll prüfen, ob blink_items_anticyclic eine Liste ist, und wenn nicht, eine leere Liste beisteuern.

    Deine Änderung würde prüfen, ob es ein String ist, und wenn nicht (sondern z.B. eine korrekt befüllte Liste) eine leere Liste zurückgeben.


    Sorry für das sequenzielle Debugging, aber ich kann gerade nicht das System umstricken für den Test, bin mitten in einer anderen Debugging-Session...

    Code:
    #!/usr/bin/env python3
    # vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab
    
    # LOGIC config
    # -------------------------------------------------------
    # visual_alarm:
    #     filename: blinker.py
    #     watch_item: HOME.alarm.action.blinkinglight
    #     set_items_cyclic:
    #         - AUSSEN.south.light.outer
    #         - AUSSEN.west.light.outer
    #     set_items_anticyclic:
    #         - AUSSEN.south.light.inner
    #         - AUSSEN.east.light.door
    #         - AUSSEN.west.light.nested
    #     set_blink_cycles: -1 ' -1: endless
    #     set_blink_interval: 2
    #     dry_run: 0
    
    control_item_name = trigger['source']
    control_item = sh.return_item(control_item_name)
    triggered_by = trigger['by']
    
    if control_item is not None:
        logger.info(f'LOGIC blinker.py: {logic.name} triggered from source {control_item_name} by {triggered_by}')
    
        # control_item_active = trigger['value']
        control_item_active = control_item()
    
        # set parameters from logic config
        blink_items_cyclic = []
        if hasattr(logic, 'set_items_cyclic'):
            blink_items_cyclic = logic.set_items_cyclic
        if isinstance(blink_items_cyclic, str):
            blink_items_cyclic = [blink_items_cyclic, ]
    
        # do we have blink items?
        if not isinstance(blink_items_cyclic, list) or len(blink_items_cyclic) == 0:
            logger.info('LOGIC blinker.py: error, no cyclic blink items set. Aborting')
        else:
    
            blink_items_anticyclic = []
            if hasattr(logic, 'set_items_anticyclic'):
                blink_items_anticyclic = logic.set_items_anticyclic
            if isinstance(blink_items_anticyclic, str):
                blink_items_anticyclic = [blink_items_anticyclic, ]
    
            # did we get strange data?
            if not isinstance(blink_items_anticyclic, list):
                blink_items_anticyclic = []
    
            if hasattr(logic, 'set_blink_cycles'):
                blink_cycles = int(logic.set_blink_cycles)
            else:
                blink_cycles = 2
                logger.info(f'LOGIC blinker.py: no blink cycles set, setting to default: {blink_cycles}')
    
            if hasattr(logic, 'set_blink_interval'):
                blink_interval = int(logic.set_blink_interval)
            else:
                blink_interval = 2
                logger.info(f'LOGIC blinker.py: no blink interval set, setting to default: {blink_interval}')
    
            if hasattr(logic, 'dry_run'):
                dry_run = (int(logic.dry_run) > 0)
            else:
                dry_run = False
    
            if control_item_active:
    
                # first call?
                if not hasattr(logic, 'blink_init'):
                    logger.info(f'LOGIC blinker.py: initiating {blink_cycles} blinks for {len(blink_items_cyclic)} cyclic and {len(blink_items_anticyclic)} anti-cyclic items')
                    logic.blink_init = True
    
                    blink_items = blink_items_cyclic + blink_items_anticyclic
                    if len(blink_items) > 0:
                        # SAVE item states
                        logic.saved_items = {}
                        for item_name in blink_items:
                            item = sh.return_item(item_name)
                            if item:
                                logic.saved_items[item_name] = item()
                                logger.info(f'LOGIC blinker.py: save {item_name} = {item()}')
    
                        if dry_run:
                            logger.warn('LOGIC blinker.py: test mode, dry run active')
    
                    else:
                        logger.warn('LOGIC blinker.py: no blink items set')
    
                # prepare blink
                if hasattr(logic, 'blink_value'):
                    logic.blink_value = not logic.blink_value
                else:
                    logic.blink_value = True
    
                if hasattr(logic, 'blink_countdown'):
                    logic.blink_countdown -= 1
                else:
                    logic.blink_countdown = blink_cycles
    
                # any blinks left?
                if logic.blink_countdown > 0 or blink_cycles == -1:
                    if blink_cycles == -1:
                        logger.info('LOGIC blinker.py BLINK (endless)')
                    else:
                        logger.info(f'LOGIC blinker.py BLINK ({logic.blink_countdown} cycles remaining)')
    
                    # set all cyclic items
                    for item_name in blink_items_cyclic:
                        item = sh.return_item(item_name)
                        logger.info(f'LOGIC blinker.py SET {item_name} to {logic.blink_value}')
                        if not dry_run:
                            item(logic.blink_value)
    
                    # set all anti-cyclic items
                    for item_name in blink_items_anticyclic:
                        item = sh.return_item(item_name)
                        logger.info(f'LOGIC blinker.py SET {item_name} to {not logic.blink_value}')
                        if not dry_run:
                            item(not logic.blink_value)
    
                    sh.trigger(f'logics.{logic.name}', by=trigger['by'], source=trigger['source'], value=trigger['value'], dt=sh.now() + datetime.timedelta(seconds=blink_interval))
    
                else:
                    logger.info('LOGIC blinker.py countdown finished, set control item to False')
                    control_item(False)  # this triggers logic again!
    
            else:
                logger.info('LOGIC blinker.py control item set to false: stop blink logic, restore saved item values')
    
                # RESTORE item states
                if hasattr(logic, 'saved_items'):
                    for item_name in logic.saved_items:
                        item = sh.return_item(item_name)
                        value = logic.saved_items[item_name]
                        logger.info(f'LOGIC blinker.py: restore {item_name} = {item()}')
                        if not dry_run:
                            item(value)
    
                # reset persistent values
                if hasattr(logic, 'saved_items'):
                    delattr(logic, 'saved_items')
                if hasattr(logic, 'blink_countdown'):
                    delattr(logic, 'blink_countdown')
                if hasattr(logic, 'blink_value'):
                    delattr(logic, 'blink_value')
                if hasattr(logic, 'blink_init'):
                    delattr(logic, 'blink_init')
    
    else:
        logger.info('LOGIC blinker.py triggered without source... ignoring...')

    Einen Kommentar schreiben:


  • AndreK
    antwortet
    Hi @Jürgen,

    ändere mal noch bitte

    Code:
            # did we get strange data?
            if not isinstance(blink_items_anticyclic):
                blink_items_anticyclic = []
    in


    Code:
            # did we get strange data?
            if not isinstance(blink_items_anticyclic[MARKIEREN], str[/MARKIEREN]):
                blink_items_anticyclic = []
    Dann tuts was es soll

    Viele Grüsse
    Andre

    P.S: ich habe folgende Einträge in der logic.yaml

    Code:
    visual_alarm:
        filename: blinker.py
        watch_item: OG.Alarmtrigger
        set_items_cyclic:
        -   OG.Bad.Licht
    
        set_items_anticyclic:
    
        set_blink_cycles: 5  # -1: endless
        set_blink_interval: 2
        dry_run: 0

    Einen Kommentar schreiben:


  • Jürgen
    antwortet
    Nö...

    > Traceback (most recent call last):
    > File "/usr/local/smarthome/lib/scheduler.py", line 590, in _task
    > exec(obj.bytecode)
    > File "/usr/local/smarthome/logics/blinker.py", line 82, in <module>
    > logic.saved_items[item_name] = item()
    > TypeError: 'NoneType' object is not callable

    Einen Kommentar schreiben:


  • Morg
    antwortet
    Code:
    #!/usr/bin/env python3
    # vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab
    
    # LOGIC config
    # -------------------------------------------------------
    # visual_alarm:
    #     filename: blinker.py
    #     watch_item: HOME.alarm.action.blinkinglight
    #     set_items_cyclic:
    #         - AUSSEN.south.light.outer
    #         - AUSSEN.west.light.outer
    #     set_items_anticyclic:
    #         - AUSSEN.south.light.inner
    #         - AUSSEN.east.light.door
    #         - AUSSEN.west.light.nested
    #     set_blink_cycles: -1 ' -1: endless
    #     set_blink_interval: 2
    #     dry_run: 0
    
    control_item_name = trigger['source']
    control_item = sh.return_item(control_item_name)
    triggered_by = trigger['by']
    
    if control_item is not None:
        logger.info(f'LOGIC blinker.py: {logic.name} triggered from source {control_item_name} by {triggered_by}')
    
        # control_item_active = trigger['value']
        control_item_active = control_item()
    
        # set parameters from logic config
        blink_items_cyclic = []
        if hasattr(logic, 'set_items_cyclic'):
            blink_items_cyclic = logic.set_items_cyclic
        if isinstance(blink_items_cyclic, str):
            blink_items_cyclic = [blink_items_cyclic, ]
    
        # do we have blink items?
        if not isinstance(blink_items_cyclic, list) or len(blink_items_cyclic) == 0:
            logger.info('LOGIC blinker.py: error, no cyclic blink items set. Aborting')
        else:
    
            blink_items_anticyclic = []
            if hasattr(logic, 'set_items_anticyclic'):
                blink_items_anticyclic = logic.set_items_anticyclic
            if isinstance(blink_items_anticyclic, str):
                blink_items_anticyclic = [blink_items_anticyclic, ]
    
            # did we get strange data?
            if not isinstance(blink_items_anticyclic, list):
                blink_items_anticyclic = []
    
            if hasattr(logic, 'set_blink_cycles'):
                blink_cycles = int(logic.set_blink_cycles)
            else:
                blink_cycles = 2
                logger.info(f'LOGIC blinker.py: no blink cycles set, setting to default: {blink_cycles}')
    
            if hasattr(logic, 'set_blink_interval'):
                blink_interval = int(logic.set_blink_interval)
            else:
                blink_interval = 2
                logger.info(f'LOGIC blinker.py: no blink interval set, setting to default: {blink_interval}')
    
            if hasattr(logic, 'dry_run'):
                dry_run = (int(logic.dry_run) > 0)
            else:
                dry_run = False
    
            if control_item_active:
    
                # first call?
                if not hasattr(logic, 'blink_init'):
                    logger.info(f'LOGIC blinker.py: initiating {blink_cycles} blinks for {len(blink_items_cyclic)} cyclic and {len(blink_items_anticyclic)} anti-cyclic items')
                    logic.blink_init = True
    
                    blink_items = blink_items_cyclic + blink_items_anticyclic
                    if len(blink_items) > 0:
                        # SAVE item states
                        logic.saved_items = {}
                        for item_name in blink_items:
                            item = sh.return_item(item_name)
                            logic.saved_items[item_name] = item()
                            logger.info(f'LOGIC blinker.py: save {item_name} = {item()}')
    
                        if dry_run:
                            logger.warn('LOGIC blinker.py: test mode, dry run active')
    
                    else:
                        logger.warn('LOGIC blinker.py: no blink items set')
    
                # prepare blink
                if hasattr(logic, 'blink_value'):
                    logic.blink_value = not logic.blink_value
                else:
                    logic.blink_value = True
    
                if hasattr(logic, 'blink_countdown'):
                    logic.blink_countdown -= 1
                else:
                    logic.blink_countdown = blink_cycles
    
                # any blinks left?
                if logic.blink_countdown > 0 or blink_cycles == -1:
                    if blink_cycles == -1:
                        logger.info('LOGIC blinker.py BLINK (endless)')
                    else:
                        logger.info(f'LOGIC blinker.py BLINK ({logic.blink_countdown} cycles remaining)')
    
                    # set all cyclic items
                    for item_name in blink_items_cyclic:
                        item = sh.return_item(item_name)
                        logger.info(f'LOGIC blinker.py SET {item_name} to {logic.blink_value}')
                        if not dry_run:
                            item(logic.blink_value)
    
                    # set all anti-cyclic items
                    for item_name in blink_items_anticyclic:
                        item = sh.return_item(item_name)
                        logger.info(f'LOGIC blinker.py SET {item_name} to {not logic.blink_value}')
                        if not dry_run:
                            item(not logic.blink_value)
    
                    sh.trigger(f'logics.{logic.name}', by=trigger['by'], source=trigger['source'], value=trigger['value'], dt=sh.now() + datetime.timedelta(seconds=blink_interval))
    
                else:
                    logger.info('LOGIC blinker.py countdown finished, set control item to False')
                    control_item(False)  # this triggers logic again!
    
            else:
                logger.info('LOGIC blinker.py control item set to false: stop blink logic, restore saved item values')
    
                # RESTORE item states
                if hasattr(logic, 'saved_items'):
                    for item_name in logic.saved_items:
                        item = sh.return_item(item_name)
                        value = logic.saved_items[item_name]
                        logger.info(f'LOGIC blinker.py: restore {item_name} = {item()}')
                        if not dry_run:
                            item(value)
    
                # reset persistent values
                if hasattr(logic, 'saved_items'):
                    delattr(logic, 'saved_items')
                if hasattr(logic, 'blink_countdown'):
                    delattr(logic, 'blink_countdown')
                if hasattr(logic, 'blink_value'):
                    delattr(logic, 'blink_value')
                if hasattr(logic, 'blink_init'):
                    delattr(logic, 'blink_init')
    
    else:
        logger.info('LOGIC blinker.py triggered without source... ignoring...')

    Einen Kommentar schreiben:

Lädt...
X