esphome / feature-requests

ESPHome Feature Request Tracker
https://esphome.io/
413 stars 26 forks source link

GUI: Clock Timer in WebServer? #2347

Open autox86 opened 1 year ago

autox86 commented 1 year ago

Describe the problem you have/What new integration you would like I would love to schedule a Start and Stop Time thru the webserver of ESPHome. E.g. Select the weekdays Select the weeks Select the month Select Start Time Select Stop Time

So more or less a graphical UI what translates into the givens of on_time trigger https://esphome.io/components/time/index.html#on-time-trigger

Please describe your use case for this integration and alternatives you've tried:

I want to create a ESPHome based PoolManager. A pool outside of your house does have some critical aspects:

So to say: The measurements of ORP, PH and its controlling of chlorid and PH must safely run without any external dependcies.

Additional context

Here is what I try to do from hardware perspective: image

The Tuya W2839 is just the measuring part and connected to the ESP by serial (RX/TX/GND) image

The ESP is a device with 4 Relays and 8 GPIO inputs from rocketcontroller.com image

https://rocketcontroller.com/product/astra-controller-4-relays-16a-8-gpio-input-dc-power-led-br4g8al/

With these I would like to control my Pool chemistry. Means the Chlorid and PH value as well as the run time of the SFA and heat pump.

image

If there is any possibility that you consider implementing the WebServer "Timer Clock" feature, this would be great and appreciated. I would even donate some amount to supporting this.

Thanks & BR Chris

EternityForest commented 1 year ago

What about a more general user configurability framework, so that you could eventually change settings from an app, or via the native API some other way?

Then a component could register itself and the web server could automatically show it's config options?

EternityForest commented 1 year ago

If the devs are interested, I started working on this just to see how hard it would be.

Parsing the actual expressions seems to only be around 180 lines of not very dense code: https://github.com/esphome/esphome/compare/dev...EternityForest:esphome:user_prefs

My idea for implementing this(Assuming the team doesn't tell me not to waste my time!): (Edited, latest version as i learn more while implementing and iterating)

Problem: Serial flashing data loss

If someone flashed via serial they might find it highly infuriating to lose all their settings if they were doing significant manual setup. https://github.com/esphome/issues/issues/4370 might be important.

autox86 commented 1 year ago

What about a more general user configurability framework, so that you could eventually change settings from an app, or via the native API some other way?

Then a component could register itself and the web server could automatically show it's config options?

Indeed, configuring thru HA and only saving in ESP is also fine. Unfortunately I don't know how this must be achieved. Probably some translation from a time to a cron-like syntax?

Anything you have for that, I am happy to test with :)

autox86 commented 1 year ago

If the devs are interested, I started working on this just to see how hard it would be.

Parsing the actual expressions seems to only be around 180 lines of not very dense code: esphome/esphome@dev...EternityForest:esphome:user_prefs

My idea for implementing this(Assuming the team doesn't tell me not to waste my time!): (Edited, latest version as i learn more while implementing and iterating)

  • Make it so string global variables can be persisted to flash like numeric ones(Done!)
  • Add a runtime parser to the Time component for the cron expressions(Mostly done!)
  • UI Settings, which are just a lambda getter and setter and a name, configured on the WebServer component, that you can access in the API(Mostly done!)
  • Create frontend UI for the user preferences, building a nice forms based on metadata supplied on the web server component
  • Compress the JS, CSS, and HTML for the web server, to make it more practical to serve locally.

Problem: Serial flashing data loss

If someone flashed via serial they might find it highly infuriating to lose all their settings if they were doing significant manual setup. esphome/issues#4370 might be important.

Wow!!!

This sounds amazing! Loosing the settings when flashing is one thing, at the end it might not be very often and at least me, could live with that.

If you are really trying to tackle that, you might have a look at kaufha repo. Kaufha PLF10

Here is what he told about his modification:

The reason for the forced address: ESPHome assigns flash addresses to each entity in a certain order. I assume it is based on >the order that ESPHome processes the yaml config to generate C code. But, at the end of the day, it is not reliably predictable >long term. So any changes to the yaml configuration or to the ESPHome core code can potentially move where an entity's >state is stored in flash. That would result in device configuration being lost on update. Of most relevance for me is that if I >update to add a new configuration entity, then any configuration entity processed by the ESPHome C code generation process >after the new entity will have its state lost.

The reason for the forced hash: ESPHome stores all values in flash with a hash that is used to confirm that a valid value is >stored. The hash value for most entities is based on its name. For wifi credentials, the hash value is based on the firmware >compile time. I use a forced hash for each entity to ensure that when users rename entities, or when I compile a new update, >all configuration is not lost. Most importantly when I originally implemented this was to ensure that the user-configured Wi-Fi >credentials were not lost on every update I released. I also wanted users to be able to move from the precompiled binary to >their own yaml config without losing all previously modified settings due to renaming. ESPHome has since created a constant >hash for Wi-Fi credentials so those will not be lost as easily. However, I do not know if they also ensure Wi-Fi credentials are >always stored at address 0 or not. If Wi-Fi credentials moved to a different flash address they would be lost even if the same >hash were used.

The reason for global_forced_addr variable: Somehow each component has to be able to communicate its forced address to >the preferences component. So I use a global variable. I think this could be done in a more efficient manner, but this was >convenient for me and was the first way I figured out how to do it. I know for sure it could be done a lot more conveniently if I >could modify the ESPHome core code but I can only modify components.

BTW: If you are putting so much efforts into that, let me know where I can donate. This will be great if we can get a native timer in WebServer either displaying only or even setting the settings there 👍

EternityForest commented 1 year ago

That looks like pretty amazing work!

From what I can gather they do want to do persistence in the Text Input component, so that might solve that one there!

All the GUI cron expressions editors I see are pretty big in terms of code, and I think time recurrence is kind of an inherently hard problem to do well since there's so many variations and nobody wants all of the possible rules cluttering a GUI, but a basic editor for a subset of cron wouldn't be too hard. I think it would have to be pretty general and cover all the other use cases like sprinkler systems to be worth it though.

You could just store the hour as a number, if you wanted to do a really super basic once a day every day thing.

An extra challenge is that if you let people enter two separate cron expressions, there's a chance of messing up and accidentally putting in something that doesn't stop till days later, ideally you want them linked, but the current time component doesn't seem to be set up for that kind of thing.

Maybe an easier way to express it would be times plus a duration, so you don't say 6PM to 7PM, you say 6PM for 1 hour explicitly, implemented with a delay?

autox86 commented 1 year ago

All true! To keep it simple I see some nativ possibilities or some supported ones.

Natively:

Doing it like you told, but able to choose a frequency:

Or and this might be the easiest way:

Alternatively, we might need to think about only storing a value to the ESPHome and doing the front end in Home Assistent: (No clou how this must be achieved, as I am not a developer)

In HA we might be able to select the frequency of doing something in a nice way and paste just the cron syntax to ESPHome? Means, ESPHome does only display the different timers (probably with a while loop to an array to show everything?)

In all cases we also need to check that we would be able to delete the stuff again.

An example how an RFID tag is saved, read, modified and deleted is the RFID thing from Hausner: https://github.com/HausnerR/esphome-door-lock

Unfortunately, I am not able to create my own components to make use of all that and judge what fits natively and what is too complex.

The most reliable way is probably: 1.) Do the GUI stuff (creating, modifiying, deleting timers) in HA 2.) Converting the selection into cron syntax 3.) Sending to ESPHome Device into an array (is the cron syntax a string?) 4.) Displaying each value of the array in WebServer of ESPHome with a while loop into a template text sensor? 5.) Make use of Sensors to display the same in HA Frontend.

So it might that the ESP is not natively having enough resources to offer all possible setting ins WebServer.

At the end I am unable to judge what the ESP is able to cover and what not. Whats your opinion? If we decide on an approach I could do some research and design thinking on what we would need to have covered?

Reg. Chris

EternityForest commented 1 year ago

I actually don't know much of anything about HA myself, I'm using ESPHome for escape game props and things like that, in my Kaithem framework(Somewhat similar intent to HA, but a lot more basic, and focused on running well on cheap SD cards, and on sound, lighting, and signage).

I think at the very least the ESP could let you manually set a cron, expression. Anything more is really based on how much upstream wants it, more than any actual capability limit, there's plenty of space left but I'm sure they'll want to be careful with anything that uses space(Like cron editor JS).
Maybe they'd be up for having a way to add arbitrary "Plugins" to the web UI, so you could do just the perfect frontend for your stuff?

The cron syntax is a string at them moment, and I do have most of a on-device cron syntax parser(https://github.com/esphome/esphome/commit/bbc9683ffc785b78fc64576cdd0154a56f080ae0), and I just got the Text Input Component branch re-synced with upstream, just waiting to hear from the owner of that branch to see if that will save them any time in merging it.

The fewer things you make dynamic, the easier, so I'd imagine something closer to the UI of the LCD sprinkler timers, a fixed set of actions that each have a few "slots" for a "Start Time/How Long/How Often" controls, more than the full power of cron, would be the simplest route.

Maybe even moving away from Cron completely would be good. It was never meant for GUIs, and each element has multiple "Modes", like a specific list, or an interval, etc. It might be a bad idea because doing too much new stuff means more original code, but it might be easier to understand for users.

Something like a set of runtime entries, where each was:

Every N days On these weekdays(Instead of cron's logic, treat it as a "smart" filter, schedule a run every N days, and then actually do it on the first selected weekday after that, so that "Every 2 days" with M-F selected ever runs on weekends but always runs Monday). On these days of the month(Same smart filter logic) At this specific time Between these months of the year

marianomd commented 5 months ago

It seems this functionality is solved using this component: https://github.com/hostcc/esphome-component-dynamic-on-time