Closed rneswold closed 1 year ago
I'm starting to like the alternative.
The driver would provide seven devices: year
, month
, day
, hour
, minute
, second
, day-of-week
. Its configuration would specify the timezone so you could have several instances; one for UTC and one for local time, for instance.
Or, should we define a new device data type, Time
. The time driver would only create one device, time
. Then the logic block grammar could have operators/functions to extract the various pieces of information.
Or, the time driver provides the broken out values AND the combined.
So many choices.
This seems like it could be a very commonly used driver. So, leaning toward the most general implementation would be my suggestion.
The Time
driver providing a single time
device with functions for manipulation seems very flexible. The device shouldn't ever have to change and adding functionally with new methods should avoid disruption.
Possibly tangential question, do you see value in making a guarantee about determining or synchrony with this driver?
I imagine there are better ways to do this but I could imagine someone wanting to use this to trigger at some frequency. What precision will this provide?
Thinking about synchrony, if I need many things to happen at once, can I use this to tell them all to trigger at a time without delay? Imagine lights coming on but if they aren't synchronized then they come on in a wave.
To argue against my own opinion 😁, I think the multiple device model for this driver is more transparent and possibly easier to get started using because of that.
Possibly tangential question, do you see value in making a guarantee about determining or synchrony with this driver?
I imagine there are better ways to do this but I could imagine someone wanting to use this to trigger at some frequency. What precision will this provide?
This is a time-of-day value and it updates once a second. So, for timing at 1Hz or slower, this device could be used. If a driver needs to sample faster, it should use the tokio::interval
timer in the driver.
There are a couple of drawbacks for using drivers for "utility" values (like time-of-day):
Thinking about synchrony, if I need many things to happen at once, can I use this to tell them all to trigger at a time without delay? Imagine lights coming on but if they aren't synchronized then they come on in a wave.
Yes. If you used a logic block to use this driver to control lights, for instance, they would all be changed at nearly the same time. As an example:
# Define a Wyze bulb (not an actual driver, at the moment!)
[[driver]]
name = "wyze"
path = "bulb-1"
# Define another Wyze bulb (still not an actual driver, at the moment!)
[[driver]]
name = "wyze"
path = "bulb-2"
# Proposed time driver which makes time-related devices.
[[driver]]
name = "time"
path = "local"
cfg = { tz = "cstcdt" }
# Turn both bulbs ON from 7pm to midnight. ('defs' is not part of
# logic blocks, yet.)
[[logic]]
inputs = { hour = "local:hour" }
outputs = { bulb_1 = "bulb-1:state", bulb_2 = "bulb-2:state" }
defs = { on_time = "{hour} >= 19" }
exprs = [ "{on_time} -> {bulb_1}",
"{on_time} -> {bulb_2}" ]
For now, making a driver seems to be the simplest solution. This feature will be tracked in #74.
Although DrMem can be used for control loops, another common use would be for home automation. This includes controlling devices based on time-of-day. To support this, we need to add time expressions to the logic block grammar.
Time-of-day Task
An async task will be created that sends the UTC and local time over a broadcast channel once a second. Logic blocks can receive these broadcasts to use in their expression(s).
Grammar Additions
These variables will be added to the logic block grammar:
UYEAR
,UMONTH
,UDAY
,UHOUR
correspond to UTC values. All of these are unsigned integers that range from 0 to the max value of the time type.YEAR
,MONTH
,DAY
,HOUR
correspond to local time values.MINUTE
andSECOND
are the same for UTC and local time.UDOW
andDOW
are "day of week" to UTC and local time, respectively. Monday is 0 and Sunday is 6.All these variables are unsigned integers and can be used in expressions and comparisons.
The parser could recognize
MONDAY
as 0,TUESDAY
as 1, etc. And it could do the same for month names, so the expressions are more readable.Alternative
Another way this could be achieved is to have a built-in driver that provides time-of-day devices. This would be much simpler to implement. I find it a bit distasteful, however, because it'll be writing uninteresting time values to the storage layer. Maybe forcing the
max_history
to 1 would make it feel less distasteful.In its defense, this would remove some complications with logic block support; we would have to conditionally add the time-of-day channel only if any expression used a time value.