Heaty will die, Schedy be born!

Thanks for looking into it!

Damn it! :smiley:

Could you please try the development version (state of master branch) and watch the log when you manually change the temperature? The previous value is now logged as well.

This is what I got:

appdaemon        | 2019-02-03 15:34:57.096640 INFO schedy: --> Attribute 'operation_mode' of 'climate.burothermostat' changed from 'auto' to 'auto', resetting <Room R:Buero>.
appdaemon        | 2019-02-03 15:34:57.100352 INFO schedy: --> [R:Buero] [A:climate.burothermostat] Attribute 'temperature' is 23.5.
appdaemon        | 2019-02-03 15:34:57.105472 INFO schedy: --- [R:Buero] Doing schedule re-evaluation in 1 second [reset=True]
appdaemon        | 2019-02-03 15:34:57.108005 INFO schedy: --> [R:Buero] [A:climate.burothermostat] Attribute 'current_temperature' is 24.8.
appdaemon        | 2019-02-03 15:34:57.111758 INFO schedy: --> [R:Buero] [A:climate.burothermostat] Received value of 23.5��.
appdaemon        | 2019-02-03 15:34:57.115403 INFO schedy: --- [R:Buero] Setting value to 23.5��.  [manual]
appdaemon        | 2019-02-03 15:34:57.118978 INFO schedy: --- [R:Buero] [A:climate.burothermostat] Not sending value 23.5�� redundantly.
appdaemon        | 2019-02-03 15:34:57.123430 INFO schedy: <-- [R:Buero] Sending state to HA: state='23.5', attributes={'actor_wanted_values': {'climate.burothermostat': '23.5'}, 'scheduled_value': '22.0', 'rescheduling_time': None, 'overlaid_wanted_value': None, 'overlaid_scheduled_value': None, 'overlaid_rescheduling_time': None, 'friendly_name': 'Buero'}
appdaemon        | 2019-02-03 15:34:58.016312 INFO schedy: --- [R:Buero] Evaluating room's schedule (reset=True, force_resend=False).
appdaemon        | 2019-02-03 15:34:58.019164 INFO schedy: --- [R:Buero] Assuming it to be 2019-02-03 15:34:58.
appdaemon        | 2019-02-03 15:34:58.022056 INFO schedy: --- [R:Buero] 3 / 3 rules of <Schedule 'workroom'> are currently valid.
appdaemon        | 2019-02-03 15:34:58.025134 INFO schedy: --- [R:Buero] ������ <<Schedule 'workroom'>/1:<Rule with sub <Schedule 'prepend'>>>
appdaemon        | 2019-02-03 15:34:58.028117 INFO schedy: --- [R:Buero] ������ 4 / 4 rules of <Schedule 'prepend'> are currently valid.
appdaemon        | 2019-02-03 15:34:58.031070 INFO schedy: --- [R:Buero]     ������ <<Schedule 'workroom'>/1/1:<Rule x="Abort() if is_off('input_boolean.enable_"...>>
appdaemon        | 2019-02-03 15:34:58.034777 INFO schedy: --- [R:Buero]     ������ => Skip()
appdaemon        | 2019-02-03 15:34:58.037752 INFO schedy: --- [R:Buero]     ������ <<Schedule 'workroom'>/1/2:<Rule x="Abort() if is_off('input_boolean.enable_"...>>
appdaemon        | 2019-02-03 15:34:58.040862 INFO schedy: --- [R:Buero]     ������ => Skip()
appdaemon        | 2019-02-03 15:34:58.043845 INFO schedy: --- [R:Buero]     ������ <<Schedule 'workroom'>/1/3:<Rule x='Abort() if not is_empty(filter_entities('...>>
appdaemon        | 2019-02-03 15:34:58.048729 INFO schedy: --- [R:Buero]     ������ => Skip()
appdaemon        | 2019-02-03 15:34:58.051781 INFO schedy: --- [R:Buero]     ������ <<Schedule 'workroom'>/1/4:<Rule x='Mark(OFF, Mark.OVERLAY) if not is_empty('...>>
appdaemon        | 2019-02-03 15:34:58.055150 INFO schedy: --- [R:Buero]     ������ => Skip()
appdaemon        | 2019-02-03 15:34:58.058188 INFO schedy: --- [R:Buero] ������ <<Schedule 'workroom'>/2:<Rule with sub <Schedule 'room-individual'>>>
appdaemon        | 2019-02-03 15:34:58.061201 INFO schedy: --- [R:Buero] ������ 1 / 1 rules of <Schedule 'room-individual'> are currently valid.
appdaemon        | 2019-02-03 15:34:58.064242 INFO schedy: --- [R:Buero]     ������ <<Schedule 'workroom'>/2/1:<Rule with sub <Schedule of 2 rules>, months={1-4,11-12}, v=22>>
appdaemon        | 2019-02-03 15:34:58.067208 INFO schedy: --- [R:Buero]     ������ 1 / 2 rules of <Schedule of 2 rules> are currently valid.
appdaemon        | 2019-02-03 15:34:58.070487 INFO schedy: --- [R:Buero]         ������ <<Schedule 'workroom'>/2/1/2:<Rule from 10:00 to 00:00+1d, weekdays={6-7}>>
appdaemon        | 2019-02-03 15:34:58.073481 INFO schedy: --- [R:Buero]         ������ => 22
appdaemon        | 2019-02-03 15:34:58.076194 INFO schedy: --- [R:Buero] Final result: 22.0��
appdaemon        | 2019-02-03 15:34:58.078851 INFO schedy: --- [R:Buero] Setting value to 22.0��.  [scheduled]
appdaemon        | 2019-02-03 15:34:58.082403 INFO schedy: <-- [R:Buero] [A:climate.burothermostat] Setting value 22.0�� (left tries = 9).
appdaemon        | 2019-02-03 15:34:58.086183 INFO schedy: <-- [R:Buero] [A:climate.burothermostat] Setting temperature = 22.0��, operation mode = <unset>.
appdaemon        | 2019-02-03 15:34:58.714529 INFO schedy: --- [R:Buero] [A:climate.burothermostat] Re-sending in 30 seconds.
appdaemon        | 2019-02-03 15:34:58.717567 INFO schedy: <-- [R:Buero] Value set to 22.0��.  [scheduled]
appdaemon        | 2019-02-03 15:34:58.720492 INFO schedy: <-- [R:Buero] Sending state to HA: state='22.0', attributes={'actor_wanted_values': {'climate.burothermostat': '22.0'}, 'scheduled_value': '22.0', 'rescheduling_time': None, 'overlaid_wanted_value': None, 'overlaid_scheduled_value': None, 'overlaid_rescheduling_time': None, 'friendly_name': 'Buero'}
appdaemon        | 2019-02-03 15:34:58.767143 INFO schedy: --> Attribute 'operation_mode' of 'climate.burothermostat' changed from 'auto' to 'auto', resetting <Room R:Buero>.
appdaemon        | 2019-02-03 15:34:58.770158 INFO schedy: --- [R:Buero] Doing schedule re-evaluation in 1 second [reset=True]
appdaemon        | 2019-02-03 15:34:58.796586 INFO schedy: --> [R:Buero] [A:climate.burothermostat] Attribute 'temperature' is 22.0.
appdaemon        | 2019-02-03 15:34:58.800087 INFO schedy: --> [R:Buero] [A:climate.burothermostat] Attribute 'current_temperature' is 24.8.
appdaemon        | 2019-02-03 15:34:58.803596 INFO schedy: --- [R:Buero] [A:climate.burothermostat] Cancelled re-sending timer.
appdaemon        | 2019-02-03 15:34:58.806361 INFO schedy: --> [R:Buero] [A:climate.burothermostat] Received value of 22.0��.
appdaemon        | 2019-02-03 15:34:58.809392 INFO schedy: --- [R:Buero] Unchanged HA state: state='22.0', attributes={'actor_wanted_values': {'climate.burothermostat': '22.0'}, 'scheduled_value': '22.0', 'rescheduling_time': None, 'overlaid_wanted_value': None, 'overlaid_scheduled_value': None, 'overlaid_rescheduling_time': None, 'friendly_name': 'Buero'}
appdaemon        | 2019-02-03 15:34:59.016229 INFO schedy: --- [R:Buero] Evaluating room's schedule (reset=True, force_resend=False).
appdaemon        | 2019-02-03 15:34:59.024947 INFO schedy: --- [R:Buero] Assuming it to be 2019-02-03 15:34:59.
appdaemon        | 2019-02-03 15:34:59.027911 INFO schedy: --- [R:Buero] 3 / 3 rules of <Schedule 'workroom'> are currently valid.
appdaemon        | 2019-02-03 15:34:59.031055 INFO schedy: --- [R:Buero] ������ <<Schedule 'workroom'>/1:<Rule with sub <Schedule 'prepend'>>>
appdaemon        | 2019-02-03 15:34:59.034188 INFO schedy: --- [R:Buero] ������ 4 / 4 rules of <Schedule 'prepend'> are currently valid.
appdaemon        | 2019-02-03 15:34:59.037360 INFO schedy: --- [R:Buero]     ������ <<Schedule 'workroom'>/1/1:<Rule x="Abort() if is_off('input_boolean.enable_"...>>
appdaemon        | 2019-02-03 15:34:59.041214 INFO schedy: --- [R:Buero]     ������ => Skip()
appdaemon        | 2019-02-03 15:34:59.044370 INFO schedy: --- [R:Buero]     ������ <<Schedule 'workroom'>/1/2:<Rule x="Abort() if is_off('input_boolean.enable_"...>>
appdaemon        | 2019-02-03 15:34:59.047616 INFO schedy: --- [R:Buero]     ������ => Skip()
appdaemon        | 2019-02-03 15:34:59.050756 INFO schedy: --- [R:Buero]     ������ <<Schedule 'workroom'>/1/3:<Rule x='Abort() if not is_empty(filter_entities('...>>
appdaemon        | 2019-02-03 15:34:59.055228 INFO schedy: --- [R:Buero]     ������ => Skip()
appdaemon        | 2019-02-03 15:34:59.058377 INFO schedy: --- [R:Buero]     ������ <<Schedule 'workroom'>/1/4:<Rule x='Mark(OFF, Mark.OVERLAY) if not is_empty('...>>
appdaemon        | 2019-02-03 15:34:59.061967 INFO schedy: --- [R:Buero]     ������ => Skip()
appdaemon        | 2019-02-03 15:34:59.065089 INFO schedy: --- [R:Buero] ������ <<Schedule 'workroom'>/2:<Rule with sub <Schedule 'room-individual'>>>
appdaemon        | 2019-02-03 15:34:59.068221 INFO schedy: --- [R:Buero] ������ 1 / 1 rules of <Schedule 'room-individual'> are currently valid.
appdaemon        | 2019-02-03 15:34:59.071802 INFO schedy: --- [R:Buero]     ������ <<Schedule 'workroom'>/2/1:<Rule with sub <Schedule of 2 rules>, months={1-4,11-12}, v=22>>
appdaemon        | 2019-02-03 15:34:59.075049 INFO schedy: --- [R:Buero]     ������ 1 / 2 rules of <Schedule of 2 rules> are currently valid.
appdaemon        | 2019-02-03 15:34:59.078426 INFO schedy: --- [R:Buero]         ������ <<Schedule 'workroom'>/2/1/2:<Rule from 10:00 to 00:00+1d, weekdays={6-7}>>
appdaemon        | 2019-02-03 15:34:59.083500 INFO schedy: --- [R:Buero]         ������ => 22
appdaemon        | 2019-02-03 15:34:59.086505 INFO schedy: --- [R:Buero] Final result: 22.0��
appdaemon        | 2019-02-03 15:34:59.089393 INFO schedy: --- [R:Buero] Setting value to 22.0��.  [scheduled]
appdaemon        | 2019-02-03 15:34:59.092727 INFO schedy: --- [R:Buero] [A:climate.burothermostat] Not sending value 22.0�� redundantly.
appdaemon        | 2019-02-03 15:34:59.095803 INFO schedy: --- [R:Buero] Unchanged HA state: state='22.0', attributes={'actor_wanted_values': {'climate.burothermostat': '22.0'}, 'scheduled_value': '22.0', 'rescheduling_time': None, 'overlaid_wanted_value': None, 'overlaid_scheduled_value': None, 'overlaid_rescheduling_time': None, 'friendly_name': 'Buero'}

Ok, that’s then behaviour I definitely don’t expect from AppDaemon. I’ll open ann issue about it.

i dont know how you have setup the listeners.

self.listen_state(self.cb,entity, attribute=attribute)

should only get triggered if the attribute from the entity changes.
i cant tell you if anything is wrong with that, because i never listen to attributes, i always break them out.

self.listen_state(callback, entity, attribute=attribute)

Yes, like this. But it get’s called with old and new being the same.

@marank Which AppDaemon version is that?

so you mean

self.listen_state(callback, entity, old=something, new=something, attribute=attribute)

thats will probably fire when another attribute(or state) changes.
which would be the only logical result.

you actually say:
listen to entity changes when attribute doesnt change state

if you look at it in another way, then it should throw an error. because then it would be
listen to attribute state changes when it doesnt change.

if you want expected behaviour, you listen ot old, or new or old different from new.

No, you got me wrong. I specify neither old nor new when registering the listener.

The old and new passed to the callback are the same.

I’m using AppDaemon 3.0.2:

appdaemon        | 2019-02-03 17:13:53.984942 INFO AppDaemon Version 3.0.2 starting
[...]
appdaemon        | 2019-02-03 17:14:04.813837 INFO schedy: *** Welcome to schedy 0.3.0, running on AppDaemon 3.0.2.

sorry, misunderstood indeed.

i guess its expected behaviour also (question is if it should be that way)

self.listen_state(callback, entity)

listens to every (attribute)state change and it gives the state to old and new.
old and new can be the same when an something else then the state changes

self.listen_state(callback, entity, attribute = attribute)

does the same but it passes the state from the attribute to new and old.

it has actually always worked that way allthough when i read the docs you should need to do

self.listen_state(callback, entity, attribute = "all")

to get all changes. that implies that if you dont add attribute=“all” you shouldnt get a callback for any attribute change.

ill talk with Andrew about this. because thinking about it, there might be something wrong all along.

Yes, that would be my assumption as well. Opened https://github.com/home-assistant/appdaemon/issues/512 for reference.

@marank Could you please retry with latest code from master?

Yep, working now.

On a side note, thank you so much for your great work @roschi and @ReneTode. It’s sunday, but I nearly instantly got an answer after posting the issue. That’s awesome and I really appreciate it!

You’re very welcome. It’s not always as quickly as this time, but I try to do my best to get the bugs sorted out. That’ll also save me time later :slight_smile: .

and i am always on call. (except when i eat, when i sleep or when i am doing something else, but it try to avoid people noticing that i do those things :wink: )

just kiddin. i am always answering as quick as i can, and i am checking regularly during the afternoon, evening and night.

I just noticed another issue… Sorry, but I got some time today and started adjusting Schedy again…

Please look at my schedule_prepends:

schedule_prepend:
  - x: "Mark(OFF, Mark.OVERLAY) if not is_empty(filter_entities('binary_sensor', window_room=room_name, state='on')) else Skip()"
  - x: "Mark(OFF, Mark.OVERLAY) if is_on('input_boolean.bathroom_override_off') else Skip()"
  - x: "Abort() if is_off('input_boolean.enable_schedy') else Skip()"
  - x: "Abort() if is_off('input_boolean.enable_schedy_' + room_name) else Skip()"
  - x: "Abort() if not is_empty(filter_entities('climate', schedy_room=room_name, operation_mode='manual')) else Skip()"

In other words, if the bathroom window has been opened, the corresponding thermostat schould be turned off. But with my current rules, this obviously can only happen if the thermostat is in auto mode.
I think I have to return Mark() and Break() at the same time, but ist it even possible?

Hmmm, I’m not quite getting the point I fear. Are you referring to the last rule in schedule_prepend? That won’t be reached at all when a window is open…

@roschi Thank you for sorting this out outside of the forum :slight_smile:

When I try to run Schedy I get the following error:

2019-02-07 20:44:49.948530 INFO AppDaemon: App 'schedy' added
2019-02-07 20:44:49.950406 INFO AppDaemon: Initializing app schedy using class SchedyApp from module hass_apps_loader
2019-02-07 20:44:49.955614 INFO schedy: *** Welcome to schedy 0.3.0, running on AppDaemon 3.0.2.
2019-02-07 20:44:49.960328 INFO schedy: *** 
2019-02-07 20:44:49.965009 INFO schedy: *** This is an app from the hass-apps package.
2019-02-07 20:44:49.969718 INFO schedy: ***   DOCS: https://hass-apps.readthedocs.io/en/stable/
2019-02-07 20:44:49.974415 INFO schedy: *** 
2019-02-07 20:44:49.979158 INFO schedy: *** You like this app, want to honor the effort put into
2019-02-07 20:44:49.983860 INFO schedy: *** it, ensure continuous development and support?
2019-02-07 20:44:49.988561 INFO schedy: *** Then please consider making a donation.
2019-02-07 20:44:49.993226 INFO schedy: ***   DONATE: https://hass-apps.readthedocs.io/en/stable/#donations
2019-02-07 20:44:49.997895 INFO schedy: *** Thank you very much and enjoy schedy!
2019-02-07 20:44:50.002653 INFO schedy: *** 
2019-02-07 20:44:50.025769 WARNING AppDaemon: ------------------------------------------------------------
2019-02-07 20:44:50.026672 WARNING AppDaemon: Unexpected error running initialize() for schedy
2019-02-07 20:44:50.027264 WARNING AppDaemon: ------------------------------------------------------------
2019-02-07 20:44:50.029880 WARNING AppDaemon: Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/appdaemon/appdaemon.py", line 1581, in init_object
    init()
  File "/usr/lib/python3.6/site-packages/hass_apps/common.py", line 90, in initialize
    self.cfg = self.Meta.config_schema(cfg)  # pylint: disable=not-callable
  File "/usr/lib/python3.6/site-packages/voluptuous/schema_builder.py", line 267, in __call__
    return self._compiled([], data)
  File "/usr/lib/python3.6/site-packages/voluptuous/validators.py", line 204, in _run
    return self._exec(self._compiled, value, path)
  File "/usr/lib/python3.6/site-packages/voluptuous/validators.py", line 286, in _exec
    raise e if self.msg is None else AllInvalid(self.msg, path=path)
  File "/usr/lib/python3.6/site-packages/voluptuous/validators.py", line 284, in _exec
    v = func(path, v)
  File "/usr/lib/python3.6/site-packages/voluptuous/schema_builder.py", line 811, in validate_callable
    return schema(data)
  File "/usr/lib/python3.6/site-packages/voluptuous/schema_builder.py", line 267, in __call__
    return self._compiled([], data)
  File "/usr/lib/python3.6/site-packages/voluptuous/schema_builder.py", line 589, in validate_dict
    return base_validate(path, iteritems(data), out)
  File "/usr/lib/python3.6/site-packages/voluptuous/schema_builder.py", line 427, in validate_mapping
    raise er.MultipleInvalid(errors)
voluptuous.error.MultipleInvalid: expected a dictionary for dictionary value @ data['rooms']['slaapkamer_links']['actors']
2019-02-07 20:44:50.030738 WARNING AppDaemon: ------------------------------------------------------------

With the following config:

schedy:
  module: hass_apps_loader
  class: SchedyApp
  actor_type: thermostat

  rooms:

    slaapkamer_links:
      allow_manual_changes: true
      rescheduling_delay: 90
      actors:
        climate.slaapkamer_links
      schedule:
      - value: 18
        rules:
        - weekdays: "1-5"
          rules:
          - { start: "21:00", end: "8:00" }
        - weekdays: "6, 7"
          rules:
          - { start: "22:00", end: "9:00" }
      - value: 4

    slaapkamer_rechts:
      allow_manual_changes: true
      rescheduling_delay: 90
      actors:
        climate.slaapkamer_links
      schedule:
      - value: 18
        rules:
        - weekdays: "1-5"
          rules:
          - { start: "21:00", end: "23:00" }
        - weekdays: "6, 7"
          rules:
          - { start: "22:00", end: "0:00" }
      - value: 4

    gang:
      allow_manual_changes: true
      rescheduling_delay: 90
      actors:
        climate.slaapkamer_links
      schedule:
      - value: 20
        rules:
        - weekdays: "1-5"
          rules:
          - { start: "7:00", end: "23:00" }
        - weekdays: "6, 7"
          rules:
          - { start: "8:00", end: "24:00" }
      - value: 15

What am I doing wrong here?