Clock Synchronization - celsworth/lxp-bridge GitHub Wiki
The inverter obviously has its own internal clock and keeping that synced to the real time is important if you're using the built-in scheduling to enable/disable AC Charge etc.
Unfortunately my inverter actually seems pretty crap at keeping the time and I've noticed it drift quite a lot, in the order of drifting by seconds in every hour.
LuxPower do appear to check this quite frequently, and I've seen them issue clock corrections of their own if my inverter drifts more than 2 minutes away from actual time, with an exchange like this:
[2022-06-16T05:53:08.773 DEBUG lxp_bridge::lxp::packet_decoder] 43 bytes in: [161, 26, 2, 0, 37, 0, 1, 194, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, 23, 0, 1, 3, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, 12, 0, 6, 22, 6, 16, 5, 55, 10, 4, 213]
[2022-06-16T05:53:08.774 DEBUG lxp_bridge::lxp::inverter] inverter XXXXXXXXXX: RX TranslatedData(TranslatedData { datalog: XXXXXXXXXX, device_function: ReadHold, inverter: XXXXXXXXXX, register: 12, values: [22, 6, 16, 5, 55, 10] })
[2022-06-16T05:53:08.774 DEBUG lxp_bridge::coordinator] RX: TranslatedData(TranslatedData { datalog: XXXXXXXXXX, device_function: ReadHold, inverter: XXXXXXXXXX, register: 12, values: [22, 6, 16, 5, 55, 10] })
[2022-06-16T05:53:08.775 DEBUG lxp_bridge::mqtt] publishing: lxp/XXXXXXXXXX/hold/12 = 1558
[2022-06-16T05:53:08.775 DEBUG lxp_bridge::mqtt] publishing: lxp/XXXXXXXXXX/hold/13 = 1296
[2022-06-16T05:53:08.775 DEBUG lxp_bridge::mqtt] publishing: lxp/XXXXXXXXXX/hold/14 = 2615
[2022-06-16T05:53:08.775 DEBUG rumqttc::state] Publish. Topic = lxp/XXXXXXXXXX/hold/12, Pkid = 25, Payload Size = 4
[2022-06-16T05:53:08.776 DEBUG rumqttc::state] Publish. Topic = lxp/XXXXXXXXXX/hold/13, Pkid = 26, Payload Size = 4
[2022-06-16T05:53:08.776 DEBUG rumqttc::state] Publish. Topic = lxp/XXXXXXXXXX/hold/14, Pkid = 27, Payload Size = 4
[2022-06-16T05:53:09.797 DEBUG lxp_bridge::lxp::packet_decoder] 38 bytes in: [161, 26, 2, 0, 32, 0, 1, 194, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, 18, 0, 1, 16, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, 12, 0, 3, 0, 93, 242]
[2022-06-16T05:53:09.797 DEBUG lxp_bridge::lxp::inverter] inverter XXXXXXXXXX: RX TranslatedData(TranslatedData { datalog: XXXXXXXXXX, device_function: WriteMulti, inverter: XXXXXXXXXX, register: 12, values: [3, 0] })
[2022-06-16T05:53:09.797 DEBUG lxp_bridge::coordinator] RX: TranslatedData(TranslatedData { datalog: XXXXXXXXXX, device_function: WriteMulti, inverter: XXXXXXXXXX, register: 12, values: [3, 0] })
This is seen in lxp-bridge logs without me doing anything; ie its just what lxp-bridge sees (since all data from the inverter is broadcast out to all clients).
So we can see that registers 12-14 were requested (we don't see the actual packet that requested them, just the reply), and even though this is undecoded you can just about see the reply makes sense; on the second line above note the values: [22, 6, 16, 5, 55, 10]
. This equates to 2022-06-16 05:55:10. Note that my logging shows we received this at 05:53:08; so the inverter is two minutes fast.
Then after the usual MQTT publishing of all this, a second later we get another packet. Note again this is the inverter's reply to an original packet which unfortunately we don't get to see. Here the inverter is simply replying to a WriteMulti
packet of register 3, and it had 3 values in it; this reply is just a confirmation that the values have been set. So this is LuxPower changing the time on the inverter.
The next time I saw any behaviour related to this was a few hours later:
[2022-06-16T11:19:24.631 DEBUG lxp_bridge::lxp::packet_decoder] 43 bytes in: [161, 26, 2, 0, 37, 0, 1, 194, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, 23, 0, 1, 3, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, 12, 0, 6, 22, 6, 16, 11, 19, 8, 255, 215]
[2022-06-16T11:19:24.631 DEBUG lxp_bridge::lxp::inverter] inverter XXXXXXXXXX: RX TranslatedData(TranslatedData { datalog: XXXXXXXXXX, device_function: ReadHold, inverter: XXXXXXXXXX, register: 12, values: [22, 6, 16, 11, 19, 8] })
[2022-06-16T11:19:24.632 DEBUG lxp_bridge::coordinator] RX: TranslatedData(TranslatedData { datalog: XXXXXXXXXX, device_function: ReadHold, inverter: XXXXXXXXXX, register: 12, values: [22, 6, 16, 11, 19, 8] })
So now at 11:19:24 the inverter thinks the time is 11:19:08. Still not great, but an improvement on the 2 minutes differential from before. I dare say they set it more accurately than this but its just drifted again in the time since. A bit odd that previously the inverter was running fast and now it seems to be running slow.
From v0.7.0, lxp-bridge can synchronize the time on the inverter to your local clock, but this is disabled by default for now. See the scheduler
section in the example config for obvious clues on how to enable it; the cron
line is standard cron syntax (the default being every day at midnight local time).
However, I think we're bumping into https://github.com/chronotope/chrono/issues/120 - if we fetch the inverter time during a DST transition hour, then try to construct a Time
object out of it, lxp-bridge panics and crashes. Still working on ideas to fix this :(