-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[OmniLink] Fix daylight savings when setting date/time #12546
Conversation
Signed-off-by: Ethan Dye <[email protected]>
This pull request has been mentioned on openHAB Community. There might be relevant details there: |
Assuming that this goes through before the 3.3 release a breaking change notice is already present for this channel due to unrelated changes made previously see #12246. |
Signed-off-by: Ethan Dye <[email protected]>
Why a date should be stored in a string item rather than a date item? I don't understand the logic. |
Because in order to allow calculation of DST we need to preserve the location data but DateTimeType does not do that which causes the DST flag to always be false. This was brought up in the forum discussion that was auto posted here above. |
The problem is that the DateTimeType lacks timezone information. As a solution DateTimeType is switched to a StringType item so one can add the timezone and convert that string to a ZonedDateTime, right? Not very user friendly and intuitive. Not sure how feasible this is, but you might look into another scenario: Get the openhab Time Zone Settings from the i18n services. But not sure if that is always available to the binding. I also wonder how other bindings solve this problem. |
|
Sorry, i meant not only timezone. It is the combination timezone / locale that is needed to determine if DST is active or not. |
Correct, time zone and locale are required for DST calculation. However, DateTimeType drops the locale information when converting to/from ZonedDateTime. I forgot to update the rules documentation to describe how to send the command with the changes but will do that in the morning. |
IMHO I still don't understand the need, so as also requested by @lolodomo - maybe a description of the exact problem being solved would help? |
Hi, The need for the request is the following. The Ommi system requires you to identify if your current location is in DST. In openHAB, @jlaur @lolodomo What exactly are you recommending so that we can be unambiguous about the location of the UTC offset? |
@@ -492,7 +493,7 @@ private void getSystemStatus() throws IOException, OmniNotConnectedException, Om | |||
.append(String.format("%02d", status.getHour())).append(":") | |||
.append(String.format("%02d", status.getMinute())).append(":") | |||
.append(String.format("%02d", status.getSecond())).toString(); | |||
updateState(CHANNEL_SYSTEM_DATE, new DateTimeType(dateString)); | |||
updateState(CHANNEL_SYSTEM_DATE, new StringType(dateString)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaving DateTimeType/StringType discussion aside for a moment, I wonder if something like this would have been a better approach:
updateState(CHANNEL_SYSTEM_DATE,
new DateTimeType(
ZonedDateTime.ofLocal(
LocalDateTime.of(status.getYear() + 2000, status.getMonth(), status.getDay(),
status.getHour(), status.getMinute(), status.getSecond()),
ZoneId.systemDefault(), null)));
Also, I can see that SystemStatus
returned by the controller contains daylightSavings
, but unfortunately that seems useless without also knowing the time zone. Do you need time zone/DST information from the controller, or simply from the openHAB system, so you can assume that system time returned by the controller is local time in openHAB's timezone?
The example is for simplicity using system time zone. Using TimeZoneProvider
it's possible to get the time zone configured in openHAB.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps, but I actually didn't write that code in the first place. I migrated the existing code and got it up to spec for inclusion in the openHAB addons proper repo and never really changed it. At this point it doesn't make a to much sense to have it be a date time type because of the issues discussed above but that has yet to be resolved, so for the moment I plan to leave it.
ZonedDateTime zdt = ZonedDateTime.parse(((StringType) command).toString(), | ||
DateTimeFormatter.ISO_ZONED_DATE_TIME); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just for my understanding: This seems like logic used for setting the system time on the controller in local time with provided DST flag - correct? Is this needed to be called twice per year in order to set correct DST flag, or what is the actual need? I assume the controller cannot automatically adjust since it's not aware of the time zone it's in?
As to the actual change, is the difference that using ISO_ZONED_DATE_TIME you will be able to provide something like [Europe/Paris]
to exactly get DST right?
Would it be good enough to deduct time zone and DST flag from system or openHAB configuration?
When setting the date/time on the controller, or for what purpose?
Thanks for clarifying this part. I think I'm beginning to understand the issue, but I'm still not entirely there. :-) I guess I still don't understand why and when the Omni system needs the DST flag.
No recommendation yet, but getting there. Please see my code comments - for now raises more questions than answered, but hopefully that will turn around soon. Is this problem inconsistency in the controller wanting DST, but not time zone? What can the controller do when having this information? Is the controller configured with local time (and DST on/off)? How do you experience the current problem as a user - what exactly happens? |
We are writing to the controller to set its time. The Omni controllers are notoriously bad a keeping a good clock. My clock drifts by 2-3min per day. Therefore at 1am nightly, I set the controller time through openHAB. The set time API to the controller requires you to let the controller know if the user is currently in DST. It has nothing to do with setting DST or ST, it simply part of the API to the controller Doing this
Its not a problem with the controller not wanting time zone, the controller can figure out the correct time if you tell it whether or not you are actively in DST while setting the time.
Yes. Thats exactly how you set the time on the controller
The controller figures out what time Sunset, Sunrise, etc is based on the DST flag and your Lat/Long.
Because the DST flag isnt set when you set the controller time, all of the controller rules happen an hour too early. For instance, I lower a blackout shade when it gets dark via the controller. Its lowered an hour earlier. I turn on my landscape lights when it get dark -- they turn on too early. I water my lawn at dawn, it gets watered earlier than when I want. Etc. I could use openHAB rules for all of that, but the controller is really reliable (except for the time drift) and I lose network more frequently than I lose the controller. Let me know if I can answer any other questions. Thanks, Jerry |
Everything that @jlekhter said is correct, sorry about the silence on my part, I have been extra busy these last two days. Let me know if there are any further questions. |
Thanks for this additional explanation, I think I finally understand the details at play now.
Will you need to manually flip the DST flag twice per year when switching between summer time and normal time, or will the controller automatically do that when you are not interfering in any way by using the API to set the clock? If it can do that automatically, all you would need to do is read the DST flag from the controller and apply this again when setting the new time. That should fix the issue, but it wouldn't give you full control, i.e. the ability to flip the flag by openHAB - will be addressed in next comment.
Completely understandable. I have the same situation with my shades having automations defined in a Hunter Douglas PowerView Hub. I have winter and summer automations depending on sunrise time (and DST actually), so recently added ability from openHAB to just flip the automations four times per year instead of letting openHAB actually be in charge of them: #11516
Thanks for the insight. I now have some propositions:
|
The controller should flip the flag when DST occurs. Its not something that I've tested, but the controller does have settings for changing to Daylight Savings. The DST flag could be read using a REQUEST SYSTEM STATUS command to the controller. So that's an option. Having a separate switch channel would only store data in the binding, not really update the controller. The DST flag cannot be set without setting the controller date and time. It seems more complicated than necessary to use 2 channels to update the date/time of the controller. My favorite option is the Thing action which would synch the controller time with openHAB time. But that would leave the current channel broken. I think to fix the current channel, @ecdye's idea of using a String to store the ZonedDateTime value is a good idea. We could always add Thing action later. That's just my opinion though :) |
Why is it better than keeping the DateTime and simply reapplying the current DST flag? The String solution seems like a work-around that could easily be avoided this way:
Anything I'm missing?
That channel would only be needed if there is any need/requirement to be able to change the controller's DST flag from the binding. It could work the same way as described above:
But if changing DST is not needed, there is no reason to introduce this channel.
We could have both. :-) |
I don't think that it actually does flip it automatically on all models. I can't test but at least in my testing of the models I have only the OmniPro II controller did, the LTE mode didn't. EDIT: And besides that, what if the user wants to update the daylight savings setting because for some reason it is wrong? Then your approach won't work. |
Signed-off-by: Ethan Dye <[email protected]>
Signed-off-by: Ethan Dye <[email protected]>
It will when introducing an additional Switch channel for managing the DST flag: #12546 (comment) |
Once again that leaves the issue of in order to change the DST flag on the controller you have to update the time too. I personally think that separating the channels in this case is more complicated and less user friendly. I would prefer to stick with the string approach. What would be most ideal is if DateTimeType could be fixed to properly preserve the locale information so at some point in the future we could move back to it. Also given the user base of the binding this change is not going to have a large impact as to may knowledge there are only a handful of users who use the binding. |
Can we also consider the use cases being solved? There is no use case in the HAI controller for flipping the DST flag. The only use case we're considering is to set the time of the controller properly. The controller requires local date/time + DST flag. As @ecdye mentioned, the real fix is to fix DateTimeType. Everything else is a work around. The StringType is a good workaround for now. This allows people to update the time of a remote controller and a local controller through openHAB, which is really the only use case. |
No, that was addressed here: #12546 (comment)
Well, IMHO is actually simplifies the logic when separating time and DST flag:
With the String approach:
I disagree here. DateTimeType should actually internally store an Instant instead of a ZonedDateTime. At any moment this Instant could be converted to ZonedDateTime or LocalDateTime using TimeZoneProvider and/or LocationProvider. |
If that's the only use case, we are back to: #12546 (comment) without need for a separate channel. So DateTime can be preserved at the same time as solving the issue? @ecdye however brought up this need: #12546 (comment) |
Signed-off-by: Ethan Dye <[email protected]>
@jlaur I've updated the code to address all of your review comments. |
bump |
I'm currenty on Easter holiday, will be able to resume review within the next couple of days. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, looks good! Only a few additional minor comments.
...ing.omnilink/src/main/java/org/openhab/binding/omnilink/internal/action/OmnilinkActions.java
Outdated
Show resolved
Hide resolved
...ing.omnilink/src/main/java/org/openhab/binding/omnilink/internal/action/OmnilinkActions.java
Show resolved
Hide resolved
bundles/org.openhab.binding.omnilink/src/main/resources/OH-INF/i18n/omnilink.properties
Outdated
Show resolved
Hide resolved
Signed-off-by: Ethan Dye <[email protected]>
@jlaur Concerns addressed, I think we are ready for merge now. |
Let's get it merged then - thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@ecdye - now it would be nice if you could create separate PR for correcting this line in the upgrade notes: |
@ecdye sorry, for the late testing. It looks like the javascript version of this fix is working fine, but the DSL Rules portion is not working. I get the following error when I run DSL rules: It seems like the DSL interpreter cant find the action. |
@jlekhter Did you delete and re-add your controller after updating the binding? |
@ecdye. Yes I did. I can try doing it again when I get home, but I deleted the controller several times during the upgrade to make sure. Using JavaScript works, but if I use a rules file or a script from within OpenHAB I get the same error as above. I never restarted OpenHAB. I could try restarting openhab too later today. |
I deleted the controller, re-added it, restarted openHAB and still the same problem with DSL rules. Here is the error from within the script interface in openHAB
|
Here is the problem: Lines 77 to 78 in fdc3206
|
Yes that works. Changing the DSL rule to synchronizeSystemTime works. Javascript still wants synchronizeControllerTime as the method. The methods should be consistent across both rule sets. As an aside, is there a way to see what Thing Actions are available in openHAB? VSCode doesn't seem to complete possible options (at least for DSL). |
Created #12655 for that. |
Ahh, silly me. Got to love those mistakes in code that are hard to find. Thanks for fixing that @jlaur. |
Related openhab/openhab-addons#12546 Signed-off-by: Ethan Dye <[email protected]>
* Fix daylight savings when setting date/time * Use an action to set date/time * Add default time zone detection and i18n Signed-off-by: Ethan Dye <[email protected]> Signed-off-by: Nick Waterton <[email protected]>
Just to finish this off, I retested with the fix and it seems to work with DSL rules now. Thank you. But is this also supposed to work when you do not pass an argument into the action? If its supposed to work, then it doesnt. I was under the impression that you could write this and it would work:
But I get a scripting error when the parameter is not there. |
That is because of the JavaScript, it requires a parameter try |
Thanks -- an empty string works fine. All good then, Also as an FYI, this does require an openHab restart. Works like a charm after that. Thanks for all the work. Jerry |
* Fix daylight savings when setting date/time * Use an action to set date/time * Add default time zone detection and i18n Signed-off-by: Ethan Dye <[email protected]>
* Fix daylight savings when setting date/time * Use an action to set date/time * Add default time zone detection and i18n Signed-off-by: Ethan Dye <[email protected]> Signed-off-by: Andras Uhrin <[email protected]>
* Fix daylight savings when setting date/time * Use an action to set date/time * Add default time zone detection and i18n Signed-off-by: Ethan Dye <[email protected]>
Signed-off-by: Ethan Dye [email protected]