Repository navigation
Replies: 5 comments 6 replies
|
Follow-up on my unit (FTXM12WVJU9, protocol 3.40), this time a readout issue.
this->energy_.cooling.add_sample(bytes_to_num(payload.first(8), 16));
this->energy_.heating.add_sample(bytes_to_num(payload.subspan(8, 8), 16));and the sensor divides by 10, so Home Assistant receives for both Worth noting that Would it make sense to discard an all-ones sample in that handler, the way an unsupported query is discarded? Something like treating I have disabled both sensors in my YAML for now. Happy to test a patch. |
|
Thanks! For some reason github's notifications don't go to my phone and I miss them unless I manually check so sorry about the delay. Without a range of hardware to test against I've tried to err on allowing features to be configured rather than enforcing detected features. Daikin compounds this by reporting unit capabilities that might not be controllable over S21 (like your D6 issue). Perhaps GU00 is protocol support and GK is hardware support? I've wanted to make some of the capabilities detection and registering components more dynamic, but it feels like a bit of a chore in ESPHome at my skill level. The system would need to do a few rounds of communication with the unit in the setup phase before the components are exposed to HA. Though I think some indication where there's no support detected at runtime would be beneficial and spare users some debugging efforts. I'll happily make some changes for you:
I'll add your unit to the Faikout wiki and think more on how to best support reporting when there's a configuration/capabilities mismatch... |
|
Disclosure first. I am working with an AI assistant on this one. The hardware is mine and I ran every test myself on my own unit, so the logs and the observed behaviour are real and I can rerun anything you ask. But the protocol decoding, the local patch and the write-up below are assisted, and a good part of it is frankly over my head. So please treat the conclusions as something to verify rather than take on trust, and if you spot me asserting something wrong, say so bluntly — it will not offend me. The analysis took a couple of wrong turns before further testing settled them, and I kept one of those below rather than quietly dropping it, since the false reading is informative in itself. Tested For the rest I patched your code locally to see the responses. I enabled your response logging
static constexpr std::array debug_commands{""};
const bool is_debug = this->debug_protocol && (std::ranges::find(debug_commands, tx_str) != debug_commands.end());
...
if (/*this->debug_protocol ||*/ is_debug) {
ESP_LOGD(TAG, "ACK: %" PRI_SV " -> %s %s", ...
DecodingPayloads are reversed ASCII with the sign last:
|
|
Follow-up. I think I found why Same disclosure as before: AI-assisted analysis, my hardware, my tests, please verify rather than trust. The root cause is the support detection
this->vertical_swing.active = s21_to_vertical_swing_mode(payload[0]);
this->louvres.command_support = true; // TODO move check to initialization
My IR remote confirms it from the other side: it only has swing on/off, no fixed vane positions. So this indoor unit has no manual angle setting at all, yet it answers Forcing the fallback makes it workI changed that one line to Swing starts, the angle is watched, the louvre stops near the setpoint. It physically works, and the entity reflects reality instead of a value the unit ignored. So the mechanism is all there. From the outside the missing piece looks like the support detection rather than anything in the fallback itself, though you will know better than me whether that holds everywhere. I did not try to fix the detection myself, since your Two scaling problems the fallback then runs intoMy unit reports vane angles on a different scale from yours. The wiki's examples are The preset validator caps at 255.
Two out of three landed; the third sailed past twice. A tolerance derived from the observed travel per poll, or simply from the spacing between presets, would behave the same on your units and work on mine. Logs for any of this on request, and I can rerun anything. |
|
Thanks for going through all of it. On Here is all the evidence I actually have. 20:22:21.414 — 20:22:55.448 — Two samples, one of which contradicts the reading I published. So: no, I cannot support "sentinel". Your 10x idea probably dissolves the questionIf the finer scale is a 10x factor, then on a unit like mine That is consistent with the rest of my readings. My unit sweeps 128 to 279 and parks at 404, which on a 10x scale is 12.8° to 27.9° with a 40.4° park. Plausible for a wall unit. At 1x those same numbers are impossible. I am not claiming this is settled either — it is a hypothesis that happens to fit, and it is yours, not mine. A test that would settle the scaleIf it is useful, I can power the unit off, let the louvre close fully, and capture If the closed position lands somewhere sane on a 10x reading and the full travel spans a believable physical range, the 10x factor stops being a guess. And if other users ran the same short capture, the minimum at rest might be the per-unit discriminator you need, since a 1x unit and a 10x unit should separate cleanly on that one number. Say the word and I will run it. Same for anything else once you have looked at the Unrelated: the setpoint step looks like it could be 0.5Different subject, and no rush on it.
Worth heading off the obvious objection, since this is a North American unit: it is configured in Celsius, and these are real Celsius setpoints rather than an artefact of whole-degree Fahrenheit being converted. The values land exactly on the 0.5 °C grid. A Fahrenheit-native setpoint would show up as 22.2 or 22.8, never as a clean 24.5. The constant does double duty: it is both the step advertised to Home Assistant and the rounding applied to the setpoint before it is written. So a I changed it to I have no idea whether every unit tolerates this — plenty of them may only want whole degrees, and you would know. If some do and some do not, this looks like something that belongs with the other per-unit traits rather than as a compile-time constant. Happy to leave it as my local patch if it is not worth the complexity. |

Uh oh!
There was an error while loading. Please reload this page.
First, thanks for this component. It works well and the 60 s debug dump made diagnosing my unit straightforward.
Reporting as requested in the Contributing section: a protocol 3.40 indoor unit that answers every readout query but refuses both extended write commands.
Setup
R32 / A2L, 208-230 V single phase. Installed in North America in 2026.
module on a separate link, which stays connected and does not interfere.
30239f599d870c0e7a97ad7db1bde6b17e9339f060 s debug dump
No readout query was NAK'd. Every sensor and binary sensor I enabled reports plausible values, including power and the three energy counters unlocked at 3.20.
What works and what does not
D1D5DRD6D7The climate entity is fully functional: on/off, all six modes, setpoint, all seven fan speeds, and swing in both axes.
Every special mode switch reverts within one or two poll cycles. The log line is always the same:
Econo fails the same way through
D7.The part that may interest you
GU00reads31:30:30:30:30, i.e. the ASCII string"10000", sosupport.powerful,support.econoandsupport.streamerare all correctly computed as false. That matches the unit's behaviour and your capability decoding looks right for this model.But
GKreads31:3B:3D:30("1;=0"), which sets both:support.ac_led = GK[0] & 0x01→0x31bit 0 → truesupport.motion_detect = GK[1] & 0x08→0x3Bbit 3 → trueSo the unit declares the LED and motion-sensor features as supported, yet writing them NAKs, because they ride in the same
D6frame as the modes it does not support. The refusal is at the frame level, not per bit — I confirmed this by toggling only the LED switch, whose support bit is set, and gettingNAK for D6.If that is worth distinguishing, it means
ac_led/motion_detectfromGKcannot be used on its own to decide whetherD6is writable on a unit. On mine,GU00is the only reliable gate, and it gates the whole frame.Two smaller observations
1.
dump_config()never logs the brightness select.In
components/daikin_s21/select/daikin_s21_select.cpp:brightness_select_is missing, so a configured brightness select never appears in the boot enumeration. It is instantiated and does work — it just looks absent. This briefly led me to think my YAML had not applied.2. The model name comes back empty.
FU05(ModelName) is enabled at 3.40 and appears in theStaticlist, but themodeltext sensor publishes an empty string.ModelV0isFFFF,ModelV2is1348,ModelV3isC008. I have not dug further; happy to run debug queries if you want to chase it.One suggestion, take it or leave it
Since the component already computes
support.powerful,support.econo,support.streamerandsupport.demand, it could log a warning at boot when a switch or number is configured for a feature the unit has declared unsupported. That would have pointed me straight atGU00instead of at my own wiring, which is where I started looking. A one-line hint in the README next to the switch list would do the same job.I am happy to run any debug query or patched build on this unit. It answers everything, so it may be a useful reference for the higher protocol versions you do not have on hand.
All reactions