syssi / esphome-pipsolar

ESPHome component to monitor and control a pipsolar inverter via RS232
Apache License 2.0
78 stars 35 forks source link

set_level action expects a percentage and clips values above 1.0 #112

Closed 20after4 closed 3 months ago

20after4 commented 3 months ago

Here is example code that attempts to set the values of output_source_priority and charger_source_priority by using a select and a lambda:

select:
  - platform: template
    id: ${inverter_id}_output_source_priority_select
    name: "${inverter_name} Output Source Priority"
    options:
      - 'Utility'
      - 'Solar'
      - 'Battery'
    update_interval: 30s
    lambda: !lambda |-
      auto sensor = id(${inverter_id}_output_source_priority);
      if (sensor->has_state()) {
        int index = static_cast<int>(sensor->state);
        auto option = id(${inverter_id}_output_source_priority_select).at(index);
        if (option.has_value()) {
          return option.value();
        }
      }
      return std::string("Utility");
    set_action:
      then:
        - lambda: |-
            float value = 1;
            auto select = id(${inverter_id}_output_source_priority_select);
            auto index = select->index_of(x.c_str());
            ESP_LOGI("pip", "set_action: %s", x.c_str());
            ESP_LOGI("pip", "state: %s", select->state.c_str());
            if (index.has_value()) {
              value = static_cast<float>(index.value());
              ESP_LOGI("pip", "value: %f", value);
              id(${inverter_id}_output_source_priority_out).set_level(value);
            }

When I attempt to set, for example, output_source_priority to battery (value == 2.0) then here is the debug output from my esphome device:

[07:59:19][I][pip:208]: set_action: Battery
[07:59:19][I][pip:209]: state: Solar
[07:59:19][I][pip:212]: value: 2.000000
[07:59:19][D][pipsolar.output:015]: Will write: POP01 out of value 1.000000 / 01
[07:59:19][D][pipsolar:857]: got command: POP01

See how the value gets clipped to 1.0 even though I'm passing 2.0 as the argument to set_level. If I set it to "Utility" (value == 0.0) then it works correctly, only because the value is within the expected range of 0.0 to 1.0

20after4 commented 3 months ago

I think it would make more sense for the pipsolar component to expose these settings as a select instead of the switch and output components. The switches behavior is a bit glitchy acting as a radio-button group but only after a long delay. The output component obviously wasn't meant for arbitrary integers as the value, it seems to be designed for dimmers, mainly.

I may make an attempt at implementing the select behavior as a native component instead of yaml+lambda. If I make any progress I will open a PR.

20after4 commented 3 months ago

25 is related. Apparently I'm not the only one who thought this should be a select.

20after4 commented 3 months ago

Now I see that the pip8048 branch already has a prototype for a select component. Is there any plan to merge that? Also are there any compatibility concerns if I tried to run that branch with an older model inverter?

20after4 commented 3 months ago

Ok I was able to get it working using the pip8048 branch. No compatibility issues with my older PIP inverter. It seems to me that the code in that branch is good enough to be merged. It's much less broken than main is currently (or what is currently included with the main esphome distribution)