MQTT data for A1790, SOLIX F3800 #241
Replies: 26 comments 45 replies
0410Uncertain what a 'param_info' message is, but this is the first result from the monitor Received message on topic: dt/anker_power/A1790/AZxxxxxxxxxxxx41/param_info
{'head': {'version': '1.0.0.1', 'client_id': 'AZxxxxxxxxxxxx41', 'sess_id': '6131-7549', 'msg_seq': 15165, 'cmd': 16, 'cmd_status': 1, 'sign_code': 0, 'seed': 'null', 'timestamp': 1761317549}, 'payload': '{"data":"/wl3AAMBDwQQoQE0ohkEQVpWRzhQMEU0ODUwMDI3Mh4AAW8AnQAAoxoEQVpWNzQ0MEQ1MjIwMDA0MfAAATIRAAAAAKQaBEFaVjc0NDBENDc2MDAwNTTwAAE0EAAAAAGlBgBBMTc5MKYGAEExNzkw/gUDuVD6aMI=","sn":"AZxxxxxxxxxxxx41","pn":"A1790"}'}
07:52:29 INFO: 2025-10-24 07:52:29 Device hex data:
ff:09:77:00:03:01:0f:04:10:a1:01:34:a2:19:04:41:5a:56:47:38:50:30:45:34:38:35:30:30:32:37:32:1e:00:01:6f:00:9d:00:00:a3:1a:04:41:5a:56:37:34:34:30:44:35:32:32:30:30:30:34:31:f0:00:01:32:11:00:00:00:00:a4:1a:04:41:5a:56:37:34:34:30:44:34:37:36:30:30:30:35:34:f0:00:01:34:10:00:00:00:01:a5:06:00:41:31:37:39:30:a6:06:00:41:31:37:39:30:fe:05:03:b9:50:fa:68:c2
07:52:29 INFO: ------------------------- Pps / A1790 / 0410 / Header --------------------------
ff 09 : 2 Byte Anker Solix message marker (supposed 'ff 09')
77 00 : 2 Byte total message length (119) in Bytes (Little Endian format)
03 01 0f: 3 Byte fixed message pattern (supposed `03 00/01 0f` for send/receive)
04 10 : 2 Byte message type pattern (varies per device model and message type)
: 1 Byte optional message increment ( 0)
-- Fields --|- Value (Hex/Decode Options)---------------------------------------
Fld Len Typ uIntLe/var sIntLe floatLe dblLe/4int
a1 01 -- 34
└-> 1 unk b'4'
a2 19 04 41:5a:56:47:38:50:30:45:34:38:35:30:30:32:37:32:1e:00:01:6f:00:9d:00:00
└-> 25 bin b'AZVG8P0E48500272\x1e\x00\x01o\x00\x9d\x00\x00'
a3 1a 04 41:5a:56:37:34:34:30:44:35:32:32:30:30:30:34:31:f0:00:01:32:11:00:00:00:00
└-> 26 bin b'AZxxxxxxxxxxxx41\xf0\x00\x012\x11\x00\x00\x00\x00'
a4 1a 04 41:5a:56:37:34:34:30:44:34:37:36:30:30:30:35:34:f0:00:01:34:10:00:00:00:01
└-> 26 bin b'AZV7440D47600054\xf0\x00\x014\x10\x00\x00\x00\x01'
a5 06 00 41:31:37:39:30
└-> 6 str b'A1790'
a6 06 00 41:31:37:39:30
└-> 6 str b'A1790'
fe 05 03 b9:50:fa:68
└-> 5 var 20665;26874 1761235129 9456645527185640673771520.000 185;80;250;104 |
|
Dual Power Hub is a cable bridging the 2 F3800s. |
|
From monitor.py Device [A1790] : SOLIX F3800 Alias : SOLIX F3800 A
Serialnumber : AZxxxxxxxxxxxx41 Admin : YES
Wireless Type : Bluetooth MAC : E8xxxxxxxxx6
Wifi SSID : Hxxxxxxxs Wifi MAC : E8xxxxxxxxx5
Wifi State : Online Signal : 100 % (-50 dBm)
SW Version : v2.4.0 (Latest) Auto-Upgrade : Enabled (OTA v2.4.0)
-Component : A1790_15Ah (Latest) -Version : v4.7.9
-Component : A1790_A17B2 (Latest) -Version : v0.3.0
-Component : A1790_esp32_low (Latest) -Version : v0.2.3.1
-Component : A1790_mcu_low (Latest) -Version : v2.4.0
Battery Energy : ---- Wh Capacity : 3840 Wh
Device [A1790] : SOLIX F3800 Alias : SOLIX F3800 B
Serialnumber : AZxxxxxxxxxxxx54 Admin : YES
Wireless Type : Bluetooth MAC : E8xxxxxxxxx4
Wifi SSID : Hxxxxxxxs Wifi MAC : E8xxxxxxxxx3
Wifi State : Online Signal : 86 % (-55 dBm)
SW Version : v2.4.0 (Latest) Auto-Upgrade : Enabled (OTA v2.4.0)
-Component : A1790_15Ah (Latest) -Version : v4.7.9
-Component : A1790_A17B2 (Latest) -Version : v0.3.0
-Component : A1790_esp32_low (Latest) -Version : v0.2.3.1
-Component : A1790_mcu_low (Latest) -Version : v2.4.0
Battery Energy : ---- Wh Capacity : 3840 Wh |
|
BA and BB could be versions if you compare them with the Api output. |
|
ad appears to be your battery %. This also appears to be the same for my A1790P |
|
I've had some delays (cloudy days and loss of power) A1790_0405 = {
# F3800 unknown message 405
"topic": "param_info",
"a4": {"name": "remaining_usage_time_?", "factor": 0.1},
"a6": {"name": "total_ac_power_out_?"},
"ad": {"name": "battery_soc_?"},
"ae": {"name": "solar_input_total_power_?"},
"af": {"name": "xt60_frontinput_power_?"},
"b0": {"name": "xt60_rearinput_power_?"},
"b1": {"name": "solar_something_?"},
"b2": {"name": "110ac_power_out_?"},
"be": {"name": "temperature"},
"cd": {"name": "ac_recharging_power"},
"fe": {"name": "msg_timestamp"},
}
A1790_040a = {
# F3800 unknown message 40a
"topic": "param_info",
}
A1790_0410 = {
# F3800 unknown message 410
"topic": "param_info",
}
A1790_0804 = {
# F3800 unknown message 804
"topic": "param_info",
}
A1790_0830 = {
# F3800 Version info
"topic": "param_info",
"a1": {"name": "sw_version?", "values": 4},
"a2": {"name": "fw_version", "values": 4},
} |
|
@gitTinker, for the naming keep in mind that this should be scalable if other PPS have mor sockets of same type. |
|
In general I think it might be ok to describe only one type for A1790 and A1790P, unless there is a significant shift in fields. Typically newer models may just add fields, that will mot be provided by old models. So descrption of newer model can be reused also for old one. |
|
@stockmopar do you happen to have additional batteries? |
|
Should the labels include the units. This would reduce misinterpretation. examples: |
|
If you describe command messages, each field need to be described including the type. This must become consumable for code to compose the whole cmd message per device and only vary the adjustable parameter. I think I'm also going to separate cmd messages in their own map, but you may start describing them as you see them when doing changes. |
|
@thomluther It appears that the majority of the most interesting pieces of data requires the realtime trigger. I'm most interested in getting this data in Home Assistant. I guess a few questions, what is the best way to get this there? Should we create the PRs for both here and ha-anker-solix? (assuming yes). Regarding the realtime trigger to get these pieces of data to show. Is that already built in to the home assistant integration to enable that to have this data flow? Or are there any challenges you anticipate for enabling that? |
|
I put up #243 to share the progress and make it easier to point out where this needs to be changed to match intent for going forward! @thomluther it looks like most of the commands are almost exactly the same as the C1000x for controlling the F3800P. |
|
@gitTinker , @stockmopar A1790_040a = {
# F3800 param info
"topic": "param_info",
}
A1790_0804 = {
# F3800 param info
"topic": "param_info",
}
A1790_0830 = {
# F3800 param info
"topic": "param_info",
"a1": {"name": "sw_version?", "values": 4},
"a2": {"name": "fw_version", "values": 4},
}Standalone F3800(p) may send less message types than coupled F3800 or even if attached to power panel. |
|
This is to track the missing parts for F3800 (P) in the MQTTMAP descriptions:
|
|
The realtime trigger is not enabled by default, because that spams with messages. 'r' will toggle on and off. |
|
@stockmopar , some questions on your log file:
16:48:11 INFO: ------------------------- Pps / A1790P / 0840 / Header -------------------------
ff 09 : 2 Byte Anker Solix message marker (supposed 'ff 09')
a7 01 : 2 Byte total message length (423) in Bytes (Little Endian format)
03 01 0f: 3 Byte fixed message pattern (supposed `03 00/01 0f` for send/receive)
08 40 : 2 Byte message type pattern (varies per device model and message type)
00 : 1 Byte optional message increment ( 0)
-- Fields --|- Value (Hex/Decode Options)---------------------------------------
Fld Len Typ uIntLe/var sIntLe floatLe dblLe/4int
...
f9 02 01 01
└-> 2 ui 1 1
fa 02 01 0c
└-> 2 ui 12 12
fd 0c 00 41:31:37:39:30:50:5f:31:35:41:68
└-> 12 str b'A1790P_15Ah' --> exp_1_typeMessage 0840 may show expansion pack num in F9?
cd 03 02 c8:00
└-> 3 sile 200 200 200;0 --> ac_input_limit
...
e6 03 02 08:07
└-> 3 sile 1800 1800 8;7
f6 03 02 55:53
└-> 3 sile 21333 21333 85;83 --> region?
f7 05 03 01:00:00:00The 200 seem to be the charge limit that you can modify.
|
|
Comparing the C1000, which seem to have both: The C1000 has the max_load command described as message 0044, but has not described it for ac_charge_limit. |
|
Adding @ohadlevy for commenting on the commands, namings and state for the following PPS settings:
In the C1000 descriptions and coded commands, there is only command described as message 0044 and coded in that way. Altough the parameter checks in the device class show "ac_charge_limit": lambda v: 100 <= v <= 800,, this is not coded in any way. So the question is what is the command message and content for those 2 features? We must not intermix max_load and ac_charge_limit in the namings across the devices as this becomes confusing. If both features are not available on every PPS, this must be documented accordingly and excluded from the PPS feature list for each particular PN. Even if the setting may not be available, the fix limit (state) could still be found in the mqtt messages... Each PN that supports both features must also describe them both in their PN mapping for the particular message type they are using for the command. The state names must be descibed accordingly, since each command will need a corresponding state field in the messages, otherwise it cannot be configured as HA control entity. |
|
I also found another weird command in your logs: Since the value is a binary field type, it may be difficult to understand what this is about. Part of it could be your SN string, but you would need to compare... |
|
@stockmopar did you ever get the BP3800 extensions? ------------------------- Pps / A1790 / 0405 / Header --------------------------
ff 09 : 2 Byte Anker Solix message marker (supposed 'ff 09')
78 01 : 2 Byte total message length (376) in Bytes (Little Endian format)
03 01 0f: 3 Byte fixed message pattern (supposed `03 00/01 0f` for send/receive)
04 05 : 2 Byte message type pattern (varies per device model and message type)
: 1 Byte optional message increment ( 0)
-- Fields --|- Value (Hex/Decode Options)---------------------------------------
Fld Len Typ uIntLe/var sIntLe floatLe dblLe/4int
a1 01 -- 34
└-> 1 unk b'4'
a2 05 03 00:00:00:00
└-> 5 var 0;0 0 0.000 0;0;0;0
a3 05 03 00:00:00:00
└-> 5 var 0;0 0 0.000 0;0;0;0
a4 03 02 f0:00
└-> 3 sile 240 240 240;0 --> remaining_time_hours (factor 0.1)
a5 03 02 00:00
└-> 3 sile 0 0 0;0 --> ac_input_power
a6 03 02 3f:00
└-> 3 sile 63 63 63;0 --> ac_output_power
a7 03 02 00:00
└-> 3 sile 0 0 0;0 --> usbc_1_power
a8 03 02 00:00
└-> 3 sile 0 0 0;0 --> usbc_2_power
a9 03 02 00:00
└-> 3 sile 0 0 0;0 --> usbc_3_power
aa 03 02 00:00
└-> 3 sile 0 0 0;0 --> usba_1_power?
ab 03 02 00:00
└-> 3 sile 0 0 0;0 --> usba_2_power?
ac 03 02 00:00
└-> 3 sile 0 0 0;0 --> dc_12v_output_power_switch?
ad 03 02 49:00
└-> 3 sile 73 73 73;0 --> battery_soc_total
ae 03 02 df:00
└-> 3 sile 223 223 223;0 --> photovoltaic_power
af 03 02 8d:00
└-> 3 sile 141 141 141;0 --> pv_1_power
b0 03 02 52:00
└-> 3 sile 82 82 82;0 --> pv_2_power
b1 03 02 df:00
└-> 3 sile 223 223 223;0 --> bat_charge_power
b2 03 02 3f:00
└-> 3 sile 63 63 63;0 --> output_power
b3 03 02 00:00
└-> 3 sile 0 0 0;0
b4 03 02 67:00
└-> 3 sile 103 103 103;0 --> bat_discharge_power?
b5 03 02 f0:00
└-> 3 sile 240 240 240;0 --> sw_version?
b6 03 02 00:00
└-> 3 sile 0 0 0;0
b7 03 02 8c:00
└-> 3 sile 140 140 140;0
b8 03 02 6f:00
└-> 3 sile 111 111 111;0
b9 03 02 00:00
└-> 3 sile 0 0 0;0
ba 03 02 df:01
└-> 3 sile 479 479 223;1 --> sw_expansion?
bb 03 02 f0:00
└-> 3 sile 240 240 240;0
bc 03 02 00:00
└-> 3 sile 0 0 0;0 --> ac_output_power_switch
bd 02 01 01
└-> 2 ui 1 1 --> charging_status
be 02 01 06
└-> 2 ui 6 6 --> temperature
bf 02 01 02
└-> 2 ui 2 2 --> display_status
c0 02 01 52
└-> 2 ui 82 82 --> battery_soc_total_dup?
c1 02 01 62
└-> 2 ui 98 98 --> max_soc
c2 02 01 00
└-> 2 ui 0 0 --> usbc_1_status
c3 02 01 00
└-> 2 ui 0 0 --> usbc_2_status
c4 02 01 00
└-> 2 ui 0 0 --> usbc_3_status
c5 02 01 00
└-> 2 ui 0 0 --> usba_1_status?
c6 02 01 00
└-> 2 ui 0 0 --> usba_2_status?
c7 02 01 00
└-> 2 ui 0 0 --> dc_output_power_switch
c8 02 01 00
└-> 2 ui 0 0
c9 02 01 00
└-> 2 ui 0 0
ca 02 01 00
└-> 2 ui 0 0
cb 02 01 00
└-> 2 ui 0 0
cc 11 00 41:5a:56:xxxxxxxxxxxxxx:30:30:30:35:34
└-> 17 str b' xxxxxxxxxxxxx' --> device_sn
cd 03 02 2c:01
└-> 3 sile 300 300 44;1 --> ac_input_limit
ce 03 02 00:00
└-> 3 sile 0 0 0;0
cf 03 02 3c:00
└-> 3 sile 60 60 60;0 --> display_timeout_seconds
d0 03 02 3c:00
└-> 3 sile 60 60 60;0
d1 03 02 00:00
└-> 3 sile 0 0 0;0
d2 03 02 00:00
└-> 3 sile 0 0 0;0
d3 02 01 00
└-> 2 ui 0 0 --> ac_output_power_switch_dup?
d4 02 01 00
└-> 2 ui 0 0 --> dc_output_power_switch_dup?
d5 02 01 02
└-> 2 ui 2 2 --> display_mode
d6 02 01 3c
└-> 2 ui 60 60
d7 02 01 00
└-> 2 ui 0 0
d8 02 01 00
└-> 2 ui 0 0 --> temp_unit_fahrenheit
d9 02 01 00
└-> 2 ui 0 0 --> light_mode
da 02 01 03
└-> 2 ui 3 3
db 02 01 14
└-> 2 ui 20 20
dc 02 01 00
└-> 2 ui 0 0
dd 02 04 00
└-> 2 bin b'\x00'
e4 02 01 00
└-> 2 ui 0 0
fe 05 03 af:f2:3e:69
└-> 5 var -3409;26942 1765733039 14427621662240431031713792.000 175;242;62;105 --> msg_timestamp (2025-12-14 09:23:59)
de 02 01 00
└-> 2 ui 0 0
f6 03 02 55:53
└-> 3 sile 21333 21333 85;83 --> region?
f7 05 03 01:00:00:00
└-> 5 var 1;0 1 0.000 1;0;0;0 --> port_memory_switch
f8 15 04 02:00:01:01:00:01:01:00:00:00:00:00:00:00:00:00:00:00:00:00
└-> 21 bin b'\x02\x00\x01\x01\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
f9 02 01 01
└-> 2 ui 1 1
fa 02 01 0a
└-> 2 ui 10 10
fd 0b 00 41:31:37:39:30:5f:31:35:41:68
└-> 11 str b'A1790_15Ah' --> exp_1_type
--------------------------------------------------------------------------------------------------------- Pps / A1790 / 040a / Header --------------------------
ff 09 : 2 Byte Anker Solix message marker (supposed 'ff 09')
48 00 : 2 Byte total message length (72) in Bytes (Little Endian format)
03 01 0f: 3 Byte fixed message pattern (supposed `03 00/01 0f` for send/receive)
04 0a : 2 Byte message type pattern (varies per device model and message type)
: 1 Byte optional message increment ( 0)
-- Fields --|- Value (Hex/Decode Options)---------------------------------------
Fld Len Typ uIntLe/var sIntLe floatLe dblLe/4int
a1 01 -- 34
└-> 1 unk b'4'
a2 02 01 01
└-> 2 ui 1 1
a3 02 01 40
└-> 2 ui 64 64
a4 27 04 31:30:31:41:4d:32:35:30:37:32:35:30:30:33:38:32:6a:01:00:08:02:40:64:00:01:00:01:00:41:31:37:39:30:5f:31:35:41:68
└-> 39 bin b'101AM25072500382j\x01\x00\x08\x02@d\x00\x01\x00\x01\x00A1790_15Ah'
a5 01 -- 01
└-> 1 unk b'\x01'
fe 05 03 af:f2:3e:69
└-> 5 var -3409;26942 1765733039 14427621662240431031713792.000 175;242;62;105
--------------------------------------------------------------------------------
```
<img width="640" height="622" alt="image" src="https://github.com/user-attachments/assets/856b2be5-ee90-4589-a4b2-61750f4955a6" />
|
|
Adding a data point that may help with the Setup: F3800 + 1× BP3800 expansion (15Ah model, type string "A1790_15Ah"), continuous MQTT captures running since early May 2026. Concurrent reading from a single sniff window, 2026-05-05 23:15 UTC:
Anker app at the same moment displayed 91% — the user-facing total. What I think this might meanIf both batteries contribute equally to the user-displayed total (which assumes equal capacity per Interpretation A — ad = whole system, c0 = F3800-only Interpretation B — c0 = whole system, ad = F3800-only Interpretation A is what the math points to, which would mean the two labels are flipped vs reality. The Where I might be wrongA few things I don't fully understand and would value input on:
If the interpretation holds upI could open a small PR to update the labels and remove the Either way, glad to share more captures or test specific hypotheses against ongoing data if it's useful. |
|
Is it the F3800 that also supports a usage mode? That may reveal the plan structure, and the set_device_attr can eventually be used to set the same and change the mode... More details here: |
|
Hi @thomluther, sorry for the long gap on my end, and thanks for the 040a work. Picking this back up with a lot more decoded data on our side, so instead of hypothesizing I can answer the power-field questions with a real frame. Here is a representative 0405 frame from our F3800 + 1x BP3800 during midday solar charging (values little-endian decoded, device SN redacted): On the "charge and AC output at the same time" puzzle: in our data the field that resolves it is bd (charging status), not b4. In the frame above bd=1 (solar), b1=832 W charge, and a6/b2=103 W AC output, all at once. That is consistent with normal off-grid behavior: PV can feed the AC load while charging the pack, so this frame does not establish a separate battery-discharge value. A "discharge" field reading around 113 W there is not trustworthy on its own, since this capture cannot confirm the pack is net-discharging. So I would treat bd as the mode selector, and I would not trust b4 as a discharge value. On b4/b7/b8 specifically: your sample had b4=113, b7=140, b8=111, and ours reads b4=84, b7=140, b8=111. b7 and b8 are identical to yours, and across our charging captures they stayed rock stable while solar (and therefore b1 charge power) varied a lot. So this b4..b8 group is not tracking charge power, since b1 already does that. It clusters with b5=bb=243 and ba=487, which looks more like a voltage or current group on some rail than a power channel. My guess is b5/bb is a pack or bus voltage times 10 and ba is a charge current, with b4/b7/b8 as related current or voltage readings, but I have not confirmed those against the app yet. Where discharge actually shows up: I cannot hand you a confirmed discharge-power field yet, because every raw frame we have archived is from a daytime charging session (our decode day was all solar). The clean way to isolate it is a night frame with bd=0, zero PV, and a real AC load, where the pack is the only source. We run overnight on base load every night, so I can capture that on purpose and send the decoded frame. Comparing a bd=1 charging frame against a bd=0 discharging frame side by side should make the discharge channel fall out, and by contrast tell us what b4/b7/b8 really are. That feels like the one capture worth doing next. Two extra fields we mapped that might help elsewhere:
Happy to send the overnight discharge frame plus a matched charging frame, same export and scrub as before, in whatever set is most useful (0405 alone, or 0405 + 040a + 0840 together). Just say which and I will grab them on the next clear night. |




Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
I have two F3800 (the original model, not F3800+) and a Dual Power Hub to connect them. Completely off-grid; charged via solar on the XT60 ports. All 4 ports used (two on each F3800).
This setup may affect the values received from MQTT.
For reference: I am running mqtt_monitor.py on a Raspberry Pi 4B with the trixie version of RPiOS.
I am using the same account, simultaneously, for the app (IOS) and anker-solix-api.
Device awake publish interval: TBD
Device standby publish interval: TBD
Device real time trigger publish: TBD
All reactions