MQTT - celsworth/lxp-bridge GitHub Wiki
This page is WIP!
This page talks about how lxp-bridge interacts with MQTT. All the topics referenced below assume the default mqtt.namespace
in the configuration file; by default this is lxp
, but if you change it, you'll need to adjust the topics discussed below accordingly.
If you have not read Inverter Basics yet, that is suggested first to understand what we mean by hold
and input
etc.
Publishes
This describes messages that lxp-bridge sends to the broker when the inverter sends us data. See MQTT - Publishes.
Subscriptions
lxp-bridge subscribes to MQTT topics under lxp/cmd/
. The next part of the topic is the datalogger serial number or the special keyword all
. If you use all
, the message will be transmitted to all connected inverters. The examples below use $datalog
as a placeholder.
Depending what you're asking lxp-bridge to do you may get a few response messages.
You'll get a result
topic which contains a payload of OK
or FAIL
; these are useful for things like setting registers. These are identified by being under the lxp/result/
namespace; cmd
is replaced with result
. These generally contain FAIL
when lxp-bridge didn't get the expected response from the inverter.
For example:
lxp/cmd/$datalog/set/ac_charge
-> replies withlxp/result/$datalog/set/ac_charge
lxp/cmd/$datalog/read/hold/1
-> replies withlxp/result/$datalog/read/hold/1
You'll also get a message containing the data you're reading when appropriate. For example, publishing to lxp/cmd/$datalog/read/hold/1
will publish the response in lxp/$datalog/hold/1
containing the value of register 1.
boolean values recognised as true in payloads are 1
, t
, true
, on
, y
, and yes
. They're all equivalent. Anything else will be interpreted as false.
percent values should be an integer between 0 and 100.
See below for full details on each message.
lxp/cmd/$datalog/read/hold/X
, payload = optional int
Read holding register X. The unprocessed contents of the register will appear in lxp/$datalog/hold/X
. Depending on which register you're reading, this may need further post-processing to make sense.
If you provide a payload, it should be an integer which indicates the number of registers to read. For example, publishing lxp/cmd/all/read/hold/12
with a payload of 3
will get you registers 12-14 inclusive (in individual messages, one register per message), which contain the current time on the inverter.
Registers start at 0 and can go all the way up to 200 depending on your inverter model (some newer models or firmwares may go higher)
lxp/cmd/$datalog/read/input/X
, payload = optional int (added in v0.10)
Read input register X, where X should be 0 - 119. The unprocessed contents of the register will appear in lxp/$datalog/input/X
. Depending on which register you're reading, this may need further post-processing to make sense.
If you provide a payload, it should be an integer which indicates the number of registers to read. The number of registers to read cannot be larger than 80, otherwise you will face "TranslatedData::decode packet too short" error.
The full list of registers can be found in Inputs.
lxp/cmd/$datalog/read/inputs/X
, payload = empty
Prompt the inverter to broadcast a set of input registers.
X can be 1-3. 1
corresponds to input registers 0-39, 2
is 40-79, and 3
is 80-119.
These get published every few minutes anyway (assuming the inverter gets a heartbeat response - see the section in Inverter Basics) but with this you can read them on-demand. The processed contents appear in lxp/$datalog/inputs/X
as a JSON hash.
This is slightly different from the more raw approach of reading holdings and parameters, because this is where lxp-bridge started life, getting power data out of the inverter and into databases for graphing etc. Processing this data into a JSON hash makes it easier for consumers to process without needing to know too many internal inverter technical details.
lxp/cmd/$datalog/read/param/X
, payload = empty
Read datalogger parameter X. The unprocessed reply will appear in lxp/$datalog/param/X
. Depending on which parameter you're reading, this may need further post-processing to make sense.
TODO: separate doc with known parameters? For now only 0 is known to work, which is the interval between inputs being published, in seconds.
lxp/cmd/$datalog/read/ac_charge/X
, payload = empty (added in v0.10)
Read the holding registers associated with AC Charge schedule X (1-3) and publish them as a formatted JSON string, like so:
=> {"start":"20:00", "end":"21:00"}
See also lxp/cmd/$datalog/set/ac_charge/$x
.
lxp/cmd/$datalog/read/ac_first/X
, payload = empty (added in v0.11)
Read the holding registers associated with AC First schedule X (1-3) and publish them as a formatted JSON string, like so:
=> {"start":"20:00", "end":"21:00"}
See also lxp/cmd/$datalog/set/ac_first/$x
.
lxp/cmd/$datalog/read/charge_priority/X
, payload = empty (added in v0.10)
Read the holding registers associated with Charge Priority schedule X (1-3) and publish them as a formatted JSON string, like so:
=> {"start":"20:00", "end":"21:00"}
See also lxp/cmd/$datalog/set/charge_priority/$x
.
lxp/cmd/$datalog/read/forced_discharge/X
, payload = empty (added in v0.10)
Read the holding registers associated with Forced Discharging schedule X (1-3) and publish them as a formatted JSON string, like so:
=> {"start":"20:00", "end":"21:00"}
See also lxp/cmd/$datalog/set/forced_discharge/$x
.
lxp/cmd/$datalog/set/hold/X
, payload = int
Set holding register X to the value in the payload, which should be a 16-bit integer.
lxp/cmd/$datalog/set/param/X
, payload = int (added in v0.10)
Set datalogger parameter X to the value in the payload, which should be a 16-bit integer. Do not do this unless you know what you are doing. Datalogger parameters are largely unknown and untested.
The only verified parameter is 0, which is the interval in seconds between automated inputs broadcasting.
lxp/cmd/$datalog/set/ac_charge
, payload = boolean
Enable or disable AC Charging.
Note that if you have AC Charge schedules set, this may not immediately actually start charging.
This can be seen in registers 68 - 73 - AC_CHARGE_START_HOUR, AC_CHARGE_START_MINUTE, AC_CHARGE_END_HOUR, and AC_CHARGE_END_MINUTE (and _1 and _2). See the next section (lxp/cmd/$datalog/set/ac_charge/$x
) for a way to set these easily.
lxp/cmd/$datalog/set/ac_charge/$x
, payload = JSON (added in v0.10)
Set a start/end schedule for AC Charging. The inverter has 3 such pairs, so $x can be 1, 2, or 3. The payload should be a hash with start
and end
keys, and the values HH:MM
format, like this:
{"start":"20:00", "end":"21:00"}
lxp/cmd/$datalog/set/ac_first/$x
, payload = JSON (added in v0.11)
Set a start/end schedule for AC First. The inverter has 3 such pairs, so $x can be 1, 2, or 3. The payload should be a hash with start
and end
keys, and the values HH:MM
format, like this:
{"start":"20:00", "end":"21:00"}
lxp/cmd/$datalog/set/charge_priority
, payload = boolean
Enable or disable priority charging.
lxp/cmd/$datalog/set/charge_priority/$x
, payload = JSON (added in v0.10)
Set a start/end schedule for Priority Charging. The inverter has 3 such pairs, so $x can be 1, 2, or 3. The payload should be a hash with start
and end
keys, and the values HH:MM
format, like this:
{"start":"20:00", "end":"21:00"}
lxp/cmd/$datalog/set/forced_discharge/$x
, payload = JSON (added in v0.10)
Set a start/end schedule for Forced Discharging. The inverter has 3 such pairs, so $x can be 1, 2, or 3. The payload should be a hash with start
and end
keys, and the values HH:MM
format, like this:
{"start":"20:00", "end":"21:00"}
lxp/cmd/$datalog/set/charge_rate_pct
, payload = percent
Send an integer in the range 0-100 (%) to this to set the global system charge rate. 100% is full power (3.6kW or whatever your inverter is rated at).
This is exactly equivalent to writing the value to holding register 64.
lxp/cmd/$datalog/set/discharge_rate_pct
, payload = percent
Send an integer in the range 0-100 (%) to this to set the global system discharge rate. 100% is full power (3.6kW or whatever your inverter is rated at).
This is exactly equivalent to writing the value to holding register 65.
lxp/cmd/$datalog/set/ac_charge_rate_pct
, payload = percent
Send an integer in the range 0-100 (%) to this to set the charge rate when AC charging (from the grid). 100% is full power (3.6kW or whatever your inverter is rated at).
This is exactly equivalent to writing the value to holding register 66.
lxp/cmd/$datalog/set/ac_charge_soc_limit_pct
, payload = percent
Send an integer in the range 0-100 (%) to this to set the battery SOC at which AC charging will stop.
This is exactly equivalent to writing the value to holding register 67.
lxp/cmd/$datalog/set/discharge_cutoff_soc_limit_pct
, payload = percent
Send an integer in the range 0-100 (%) to this to set the battery SOC at which discharging will stop.
This is exactly equivalent to writing the value to holding register 105.