delfick / photons

Python3.6+ asyncio framework for interacting with LIFX devices
https://photons.delfick.com
MIT License
73 stars 6 forks source link

[interactor] adding server long tasks (including circadian) #58

Closed delfick closed 3 years ago

delfick commented 3 years ago

@Djelibeybi can you give this a shot.

There's no unit tests or documentation and I don't personally have much knowledge of how to make a circadian light change.

These are configured via settings at startup or in memory via commands at runtime. Saving them to database will happen when I have schedules in interactor.

So something like:

interactor:
    tasks:
       name_of_my_task:
           type: circadian
           # optionally skip:false if you want this to be ignored
           options:
               update_every: 5
               matcher:
                  group_name: livingroom
               location: Melbourne

See apps/interactor/interactor/tasks/registered/circadian/options.py for all the available options (note the class it inherits from adds things like matcher and timeouts).

There's also a "stay_off" task and you can find options for that in interactor/tasks/registered/stay_off.py

There's also new commands, tasks/pause, tasks/resume, tasks/add, tasks/remove, tasks/status.

Djelibeybi commented 3 years ago

I spent most of last night and this morning finally fixing all my motion-and-other-sensor triggered lighting, so this is perfectly timed. I'm assuming it uses a similar circadian calculation to the HASS component?

I'll try and get it deployed tonight but if not, it'll get done tomorrow.

Djelibeybi commented 3 years ago

My initial thought after reviewing the code and working out how it works is that you might want to consider renaming or perhaps just referring to these as "continuous" or "background" tasks, with (the to be implemented) scheduled tasks getting a higher priority on certain characteristics.

The use case for the combination of background and foreground would be slow rise alarms and bedtime routines, i.e. a scheduled ("foreground") taks gets brightness and power priority for 30 to 60 minutes while the continuous ("background") task just gets to change kelvin for that period.

As for actual testing, I have the container image built, but it's a bit late to start stuffing with Monday morning's alarm sequences, so I'm going to defer actual configuration changes until tomorrow.

delfick commented 3 years ago

yeah, forget schedules for now, I'm not gonna look into how that works till APSchedule next version comes out. For now I decided to at least get a continuous circadian implementation.

delfick commented 3 years ago

Though it'd be easy to create task types that are temporary so you could add a task that goes away after half an hour using tasks/add

Djelibeybi commented 3 years ago

Oh, I know schedules are only a roadmap item, but I'm a product manager, remember? I've already sold that feature plus a few more to the customer. πŸ˜‚

Djelibeybi commented 3 years ago

Looking forward to playing with this tomorrow.

delfick commented 3 years ago

hehehhe :D

Djelibeybi commented 3 years ago

So I got this working and it immediately turned all my office lights off which was unexpected, but totally correct per the configuration I provided. This has made me reconsider using my office as the test lab. πŸ˜‚ I have a couple of spare White to Warm bulbs I'll use instead, so I can get a sense for what actual/real circadian lighting looks like.

delfick commented 3 years ago

So I got this working and it immediately turned all my office lights off which was unexpected

Can do change_power: false or change lights_on_range

Djelibeybi commented 3 years ago

Can do change_power: false or change lights_on_range

Yes, I realised this (almost) immediately. I went with change_power: false so they can be controlled by the motion sensort system.

delfick commented 3 years ago

Ok, you can get progress messages now. I haven't added many but it should be easy for you to add more to your local copy

https://gist.github.com/delfick/52846555881dd56f0d05b22d71b1799c

Djelibeybi commented 3 years ago

So I've been running this for a few days and it just works. However, it turns out I'm not a huge fan of real circadian lighting. πŸ˜‚ Though, I haven't actually adjusted the sunrise/sunset offsets to make them more appropriate.

What I would love to be able to do is define the values I want by hour of the day so that I can adjust the kelvin/brightness quasi-manually.

(what? I just asked for scheduled transforms in disguise?! Say it ain't so!)

delfick commented 3 years ago

ahhahahah.

How about an overrides section of

overrides:
    - start: 06:00
      end: 08:00
      hsbk:
         kelvin: 4000

So during that period, any hsbk values are hard coded to that override (so in this scenario, brightness changes would continue but kelvin would remain the same). With optional power override and days filter.

Djelibeybi commented 3 years ago

So during that period, any hsbk values are hard coded to that override (so in this scenario, brightness changes would continue but kelvin would remain the same). With optional power override and days filter.

You've just defined a scheduled task. Well done! πŸ˜›

delfick commented 3 years ago

with that logic, every change it makes (every few seconds) is a scheduled task :p

On Sat, 24 Apr 2021, 11:22 am Avi Miller, @.***> wrote:

So during that period, any hsbk values are hard coded to that override (so in this scenario, brightness changes would continue but kelvin would remain the same). With optional power override and days filter.

You've just defined a scheduled task. Well done! πŸ˜›

β€” You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/delfick/photons/pull/58#issuecomment-826012089, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA2V5MFVJIGFETYXWHS5ADTKIMN5ANCNFSM43DZ4CVA .

Djelibeybi commented 3 years ago

with that logic, every change it makes (every few seconds) is a scheduled task :p

I'm trying to decide which reply to use. It's a toss up between "It's scheduled tasks all the way down." and "20 GOTO 10 WAS A SCHEDULED TASK."

delfick commented 3 years ago

hahahahaha

On Sat, 24 Apr 2021, 4:50 pm Avi Miller, @.***> wrote:

with that logic, every change it makes (every few seconds) is a scheduled task :p

I'm trying to decide which reply to use. It's a toss up between "It's scheduled tasks all the way down." and "20 GOTO 10 WAS A SCHEDULED TASK."

β€” You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/delfick/photons/pull/58#issuecomment-826045605, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA2V5IFC2TM4KOPXZGJWHDTKJS2BANCNFSM43DZ4CVA .

delfick commented 3 years ago

I will get to this btw, I've been unwell recently.

Djelibeybi commented 3 years ago

I will get to this btw, I've been unwell recently.

Your health >>>> my desire for scheduled tasks. Take care of yourself.

Djelibeybi commented 3 years ago

So I changed the sunrise/sunset times and I'm now getting this error in the logs:

2021-04-28 21:00:47,757 ERROR   photons_transport "Bad conversion. Failed trying to convert a value"    error=ushort format requires 0 <= number <= (0x7fff * 2 + 1)    fmt=<H  group=SetWaveformOptionalPayload    name=kelvin val=111945
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/photons_protocol/packing.py", line 135, in struct_format
    b.frombytes(struct.pack(fmt, val))
struct.error: ushort format requires 0 <= number <= (0x7fff * 2 + 1)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/photons_transport/__init__.py", line 27, in catch_errors
    yield error_catcher
  File "/usr/local/lib/python3.9/site-packages/photons_transport/targets/item.py", line 140, in run
    packets = self.make_packets(sender, serials)
  File "/usr/local/lib/python3.9/site-packages/photons_transport/targets/item.py", line 209, in make_packets
    simplified_parts = self.simplify_parts()
  File "/usr/local/lib/python3.9/site-packages/photons_transport/targets/item.py", line 197, in simplify_parts
    ps.append((p, p.simplify()))
  File "/usr/local/lib/python3.9/site-packages/photons_protocol/packets.py", line 403, in simplify
    final[last_group_name] = self[last_group_name].pack(parent=self, serial=serial)
  File "/usr/local/lib/python3.9/site-packages/photons_protocol/packets.py", line 103, in pack
    return packing_kls.pack(self, payload, parent, serial)
  File "/usr/local/lib/python3.9/site-packages/photons_protocol/packing.py", line 239, in pack
    result = info.to_sized_bitarray()
  File "/usr/local/lib/python3.9/site-packages/photons_protocol/packing.py", line 82, in to_sized_bitarray
    result = self.to_bitarray()
  File "/usr/local/lib/python3.9/site-packages/photons_protocol/packing.py", line 108, in to_bitarray
    return self.struct_format(fmt, val)
  File "/usr/local/lib/python3.9/site-packages/photons_protocol/packing.py", line 137, in struct_format
    raise BadConversion(
photons_protocol.errors.BadConversion: "Bad conversion. Failed trying to convert a value"   error=ushort format requires 0 <= number <= (0x7fff * 2 + 1)    fmt=<H  group=SetWaveformOptionalPayload    name=kelvin val=111945

Looks like they every 10 seconds for the minute after the fake sunset, i.e. at 21:00:07, :17, :27, :37, :47,:57`:

cat circadian.log | grep "21:00"
2021-04-24 21:00:07,758 ERROR   photons_transport "Bad conversion. Failed trying to convert a value"    error=ushort format requires 0 <= number <= (0x7fff * 2 + 1)    fmt=<H  group=SetWaveformOptionalPayload    name=kelvin val=112690
2021-04-24 21:00:17,762 ERROR   photons_transport "Bad conversion. Failed trying to convert a value"    error=ushort format requires 0 <= number <= (0x7fff * 2 + 1)    fmt=<H  group=SetWaveformOptionalPayload    name=kelvin val=112595
2021-04-24 21:00:27,754 ERROR   photons_transport "Bad conversion. Failed trying to convert a value"    error=ushort format requires 0 <= number <= (0x7fff * 2 + 1)    fmt=<H  group=SetWaveformOptionalPayload    name=kelvin val=112501
2021-04-24 21:00:37,756 ERROR   photons_transport "Bad conversion. Failed trying to convert a value"    error=ushort format requires 0 <= number <= (0x7fff * 2 + 1)    fmt=<H  group=SetWaveformOptionalPayload    name=kelvin val=112406
2021-04-24 21:00:47,753 ERROR   photons_transport "Bad conversion. Failed trying to convert a value"    error=ushort format requires 0 <= number <= (0x7fff * 2 + 1)    fmt=<H  group=SetWaveformOptionalPayload    name=kelvin val=112312
2021-04-24 21:00:57,759 ERROR   photons_transport "Bad conversion. Failed trying to convert a value"    error=ushort format requires 0 <= number <= (0x7fff * 2 + 1)    fmt=<H  group=SetWaveformOptionalPayload    name=kelvin val=112218

lifx.yml:

tasks:
    adaptive_lighting:
      type: circadian
      options:
        matcher: group_name=Circadian
        change_power: false
        min_kelvin: 1500
        max_kelvin: 9000
        sunset_at: "21:00"
        sunrise_at: "05:30"
        location:
          name: Bundoora
          region: Victoria
          timezone: Australia/Melbourne
          latitude: -37.685026414533716
          longitude: 145.08086927000966
        min_brightness: 0.01
        max_brightness: 0.9
delfick commented 3 years ago

lol. Sounds like the point where I determine kelvin produces a large value. Will need to enforce the min and max kelvin better.

Djelibeybi commented 3 years ago

I've updated my test instance. :)

Djelibeybi commented 3 years ago

This new algorithm is flawed somewhere, but I haven't had a chance to figure out where because of time-constraints. Essentially, bulbs will set themselves to wildly inaccurate brightness or kelvin at particular times of the day.

delfick commented 3 years ago

@Djelibeybi how about this fever dream https://gist.github.com/delfick/689550f7a0b64ea4f90384e7787b4314 ?

basically remove the magic maths and make it explicit, but in a way that's stupidly flexible.

Djelibeybi commented 3 years ago

@Djelibeybi how about this fever dream https://gist.github.com/delfick/689550f7a0b64ea4f90384e7787b4314 ?

basically remove the magic maths and make it explicit, but in a way that's stupidly flexible.

I think it may be too flexible, or at least too complex. I've read it once and I have no idea what's going on. There should be simplified shortcuts for creating default "stuff" with this complexity hidden away for advanced users.

delfick commented 3 years ago

hehhee, valid feedback.

Making it simpler I think will come when I implement the base power.

There's a number of features I try to explain there with just examples.

delfick commented 3 years ago

I'm gonna close this PR. I have very limited time for programming these days and I wanna work on other things. I'm sure I'll pick this up another day but keeping this open would be lying about when that's gonna happen.

Djelibeybi commented 3 years ago

I haz a (completely understandable, you do you) sad.

delfick commented 3 years ago

yeah, I know. it'll happen one day, but to do it now would be forcing myself and I really shouldn't

On Sun, 15 Aug 2021, 3:06 pm Avi Miller, @.***> wrote:

I haz a (completely understandable, you do you) sad.

β€” You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/delfick/photons/pull/58#issuecomment-898996446, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA2V5O6NNLJTZZNT6ZJWRDT45DNPANCNFSM43DZ4CVA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email .

Djelibeybi commented 3 years ago

All good, I completely understand.