thernst-de / smarthome.plugin.autoblind

Finite state machine plugin for smarthomeNG (finite state machine)
6 stars 2 forks source link

Implement attribute "as_action_<name>" which contains all parameters for a single action #13

Closed thernst-de closed 7 years ago

thernst-de commented 7 years ago

An attribute "asaction" should be implemented. It should contain all information regarding a single action, which is now spread over several action-attributes in one single attribute. A list format with key/value pairs should be used:

as_action_myaction = function: set | value: 10 | repeat: False | delay: 5
onkelandy commented 7 years ago

I'm wondering if something like this could also apply to the different state attributes..

Something like:

as_state_time = min: value:10:00 | max: var:item.suspend_age | negate: True
as_state_suspend = value: True | agemax: eval:1+2
as_state_modus = value: 1, 1.0 | agemax: eval:sh.bla()
as_state_xyz = eval: myevalname

For the eval it would be awesome if you could define the eval in the rules section like you do with the itemnames right now. So instaed of as_item_myitem it could be as_eval_myevalname. And you reference it like eval: myevalname. Could make things cleaner and better readable.

I see a problem with the double ":" and the value-keyword as it is used in a slightly different way now but maybe when thinking about it a bit longer we can come up with a good idea..? Also the list for several possible values might become a problem.. On the other hand maybe there is a possibility to figure out the type automatically? The 3 variables are given keywords and include a dot. An evaluation always contains a special character not possible in an item, a "sh." or "if", etc. So the above example might look like..

as_state_time = min: 10:00 | max: item.suspend_age | negate: True
as_state_suspend = value: True | agemax: 1+2
as_state_modus = value: 1, 1.0 | agemax: sh.bla()
as_state_xyz = value: eval.myevalname
thernst-de commented 7 years ago

For now I would start with the action attributes and see how it works out. If it works good, we can check how it can be applied for the conditions, too.

thernst-de commented 7 years ago

Attribute has been implemented as describe in the first post in this issue.

as_action_<name> = function: <func> | value: <val> | repeat: [True/False] | delay: <delay> | force: [True/False] | order: <order>

Valid values for (relating to existing action types) are: "set", "force", "byattr", "trigger", "run" and "special"

Order (Issue #10 ) has been implemented here, too.

onkelandy commented 7 years ago

Seit den neuesten Updates scheint nichts mehr zu funktionieren.. Init Autoblind Items kommt noch, danach wird nichts mehr geloggt und Zustandsautomat macht nix :(

thernst-de commented 7 years ago

Ruf mal shNG im im Debug-Modus auf und schaue, ob es dort Fehlermeldungen gibt

[shNG-Basispfad]/bin/smarthome.py -d
onkelandy commented 7 years ago

Hab eigtl. im logging.yaml das Autoblind Plugin auf Debug gestellt.. aber da kommt nix. Wenn ich jetzt im Debugmodus starte, bekomme ich immerhin:

Exception in thread autoblind:
Traceback (most recent call last):
  File "/volume1/@appstore/py3k/usr/local/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "/volume1/homes/onkelandy/smarthome/lib/plugin.py", line 150, in run
    self.plugin.run()
  File "/volume1/homes/onkelandy/smarthome/plugins/autoblind/__init__.py", line 113, in run
    ab_item = AutoBlindItem.AbItem(self._sh, item)
  File "/volume1/homes/onkelandy/smarthome/plugins/autoblind/AutoBlindItem.py", line 131, in __init__
    self.__write_to_log()
  File "/volume1/homes/onkelandy/smarthome/plugins/autoblind/AutoBlindItem.py", line 541, in __write_to_log
    state.write_to_log()
  File "/volume1/homes/onkelandy/smarthome/plugins/autoblind/AutoBlindState.py", line 121, in write_to_log
    self.__actions_enter_or_stay.write_to_logger()
  File "/volume1/homes/onkelandy/smarthome/plugins/autoblind/AutoBlindActions.py", line 207, in write_to_logger
    for order, action in sorted(actions):
TypeError: unorderable types: AbActionSetItem() < AbActionSetItem()

Ein Item wird initialisiert, bei den anderen passiert nix.

thernst-de commented 7 years ago

Ändere mal bitte testweise die Datei AutoBlindActions.py. Ersetze in den Zeilen 199 und 207 jeweils das

sorted(actions)

durch

sorted(actions, key=lambda x: x[0])

Behebt das das Problem?

onkelandy commented 7 years ago

Jawollja, das hat das Problem behoben! Ich komm mit den neuen Keywords noch nicht ganz klar. Value beißt sich irgendwie mit dem bisherigen, wenn auch optionalen "as_set_bla = value:10". Sollte value nicht besser action heißen?

Und dann statt function: kommt dann einfach eval:, suspend: oder var: oder was auch immer? Wär für mich schlüssiger.. Hab jetzt jedenfalls einige Varianten ausprobiert, bekomme immer Fehlermeldungen, insbesondere mit var:item.suspend_remaining. Kannst du bitte mal die Actions komplett für das Suspend Item posten? Danke.

Action as_action_retrigger: Attribute 'as_action_retrigger: Invalid value 'var: item.suspend_remaining' for parameter 'function'!

thernst-de commented 7 years ago

OK, habe das als Fix gepusht.

Mit dem "kombinierten" Attribut ist es eigentlich ganz einfach:

aus

as_<func>_<name> = <val>
as_repeat_<name> =  <repeat>
as_delay_<name> = <delay>
as_order_<name> = <order>

wird

as_action_<name> = function: <func> | value: <val> | repeat: <repeat> | delay: <delay> | force: [True/False] | order: <order>

Der Parameter force soll dabei irgendwann das function: forceersetzen.

Mein Suspendzustand in der Testumgebung schaut damit wie folgt aus:

[[[[Suspend]]]]
    type = foo
    name = Ausgesetzt
    as_name = eval:autoblind_eval.insert_suspend_time("..suspend")

    [[[[[on_enter_or_stay]]]]]
        as_action_suspend = function: special | value: suspend:..suspend,..manuell | order: 1
        as_action_retrigger = function: set | value: True | delay: var:item.suspend_remaining | order: 2

    [[[[[on_leave]]]]]
        as_action_suspend = function: set | value: False

    [[[[[enter_manuell]]]]]
        type = foo
        as_value_trigger_source = test.suspend.manuell

    [[[[[enter_stay]]]]]
        type = foo
        as_value_laststate = var:current.state_id
        as_agemax_manuell = var:item.suspend_time
        as_value_suspend = True
onkelandy commented 7 years ago

Ooookay, oben müsste es dann heißen: Valid values for (relating to existing action types) are: und da das func gefehlt hat, hab ich mich verwirren lassen ;) Das force: True hat auch nen Fehler ausgespuckt, aber jetzt ist alles klar.

Selbst das mit on_leave scheint, zumindest jetzt beim Suspenditem top zu funktionieren, cool!

Im Code muss sich aber noch eine Test-Aktion befinden, denn ich bekomm noch die Meldung: Action 'restart': No item defined. Ignoring.

und hab definitiv nix mit restart drin.

Falls sich inzwischen was geändert hat bezüglich der Evaluierung, warum man in einem State gelandet ist, also über welches Set.. dann würde sich ein weiteres Schlüsselwort anbieten, nämlich -> | stateset: enter_manuell oder eben | state: enter_stay etc. Könnte man sich dann das special für suspend sparen, auch wenn es dann natürlich 2 Einträge für as_action_suspend bräuchte.

Was passiert derzeit eigtl. wenn man bei order zwei Mal die gleiche Zahl einsetzt? Zufall, welche Aktion zuerst ausgeführt wird?

thernst-de commented 7 years ago

Documentation added, closing this issue.