syssi / esphome-pipsolar

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

PI18 inverters support #54

Open preussal opened 1 year ago

preussal commented 1 year ago

Hello, can you also adjust this project so that the Mppsolar Hybrid V2 is supported with the P18 Protocoll?

At that time I adjusted the code at JBlance / MPP solar so that almost all functions of the P18 protocoll are present. But somehow I can't get along with the ESP code.

I have already flashed an ESP and I don't get an answer with the "normal" queries. Unfortunately, I don't find the place in the code where the Commando is handed over. If someone can help me there would be great.

With the piri e.g. means the request ^P007PIRI instead of only QPIRI

syssi commented 1 year ago
# pipsolar.h

#define PIPSOLAR_SENSOR(name, polling_command, value_type) \
  PIPSOLAR_VALUED_ENTITY_(sensor::Sensor, name, polling_command, value_type)
#define PIPSOLAR_SWITCH(name, polling_command) PIPSOLAR_ENTITY_(switch_::Switch, name, polling_command)

[...]

class Pipsolar : public uart::UARTDevice, public PollingComponent {

[...]

  // QPIRI values
  PIPSOLAR_SENSOR(grid_rating_voltage, QPIRI, float)
  PIPSOLAR_SENSOR(grid_rating_current, QPIRI, float)
  PIPSOLAR_SENSOR(ac_output_rating_voltage, QPIRI, float)
  PIPSOLAR_SENSOR(ac_output_rating_frequency, QPIRI, float)
  PIPSOLAR_SENSOR(ac_output_rating_current, QPIRI, float)
  PIPSOLAR_SENSOR(ac_output_rating_apparent_power, QPIRI, int)
  PIPSOLAR_SENSOR(ac_output_rating_active_power, QPIRI, int)
  PIPSOLAR_SENSOR(battery_rating_voltage, QPIRI, float)
  PIPSOLAR_SENSOR(battery_recharge_voltage, QPIRI, float)
  PIPSOLAR_SENSOR(battery_under_voltage, QPIRI, float)

Does this help already?

syssi commented 1 year ago

In other words: If you use an entity (f.e. the battery_rating_voltage sensor) the implementation registers an additional polling_command here:

 public: \
  void set_##name(type *name) { /* NOLINT */ \
    this->name##_ = name; \
    this->add_polling_command_(#polling_command, POLLING_##polling_command); \
  }

If there are multiple sensors/entities requiring the same command the command is registered just once. You should get an idea which sensor measurements does ^P007PIRI return and define a sensor per value. The second task is to update this parser to the format/response of the P18 command: https://github.com/esphome/esphome/blob/dev/esphome/components/pipsolar/pipsolar.cpp#L428-L441

Thats all!

If you want to share your implementation here I would be happy to create another feature branch for the P18 protocol implementation.

preussal commented 1 year ago

Hi syssi,

Thank you that will help. But now I have to wait for my new inverter comunucations board. This has said goodbye. I don't even get a connection using Mppsolar Monitoring software. Apparently it dismantled the TX Optocopler. The board is ordered and already on the go. Should arrive the next few days.

syssi commented 1 year ago

Sorry for your loss. Let me know if you get stuck converting this component.

preussal commented 1 year ago

Hi Syssi, the board come today, and i can comunicate with my old Script, now i try it with the esp

preussal commented 1 year ago

I have now adjusted and tested a few things, but come to the conclusion that I absolutely need the character "^", i.e. "^P007PIRI" but POLLING_^P007PIRI = 0, that does not work because the code is not compiled

how can i add this magic character to every request ?

preussal commented 1 year ago

in the python script the debug looks like this

2023-02-18 14:01:11,386:DEBUG:hidrawio:send_and_receive@50: send: b'^P007PIR', to_send: b'I\xee8\r'
2023-02-18 14:01:11,738:DEBUG:hidrawio:send_and_receive@47: multiple chunk send
2023-02-18 14:01:11,738:DEBUG:hidrawio:send_and_receive@50: send: b'I\xee8\r', to_send: b''
2023-02-18 14:01:14,143:DEBUG:hidrawio:send_and_receive@69: usb response was: b'^D0882300,217,2300,500,217,5000,5000,480,500,000,440,560,553,2,10,070,1,1,1,9,0,0,0,1,1,00[/\r'

This is from the Python Code

    "PIRI": {
        "name": "PIRI",
        "prefix": "^P007",
        "description": "Device rated information",
        "help": " -- queries rated information",
        "type": "QUERY",
        "response": [
            ["10int", "AC input rated voltage", "V"],
            ["10int", "AC input rated current", "A"],
            ["10int", "AC output rated voltage", "V"],
            ["10int", "AC output rated frequency", "Hz"],
            ["10int", "AC output rated current", "A"],
            ["int", "AC output rating apparent power", "VA"],
            ["int", "AC output rating active power", "W"],
            ["10int", "Battery rated voltage", "V"],
            ["10int", "Battery re-charge voltage", "V"],
            ["10int", "Battery re-discharge voltage", "V"],
            ["10int", "Battery under voltage", "V"],
            ["10int", "Battery bulk voltage", "V"],
            ["10int", "Battery float voltage", "V"],
            ["option", "Battery type", ["AGM", "Flooded", "User"]],
            ["int", "Max AC charging current", "A"],
            ["int", "Max charging current", "A"],
            ["option", "Input voltage rang", ["Appliance", "UPS"]],
            [
                "option",
                "Output source priority",
                ["Solar-Utility-Battery", "Solar-Battery-Utility"],
            ],
            [
                "option",
                "Charger source priority",
                ["Solar First", "Solar and Utility", "Only Solar"],
            ],
            ["int", "Parallel max num", ""],
            ["option", "Machine type", ["Off-Grid", "Grid-Tie"]],
            ["option", "Topology", ["transformerless", "transformer"]],
            [
                "option",
                "Output model setting",
                [
                    "Single module",
                    "parallel output",
                    "Phase 1 of three phase output",
                    "Phase 2 of three phase output",
                    "Phase 3 of three phase output",
                ],
            ],
            [
                "option",
                "Solar power priority",
                ["Battery-Load-Utiliy + AC Charger", "Load-Battery-Utiliy"],
            ],
            ["int", "MPPT strings", ""],
        ],
        "test_responses": [
            b"^D0882300,217,2300,500,217,5000,5000,480,500,540,450,552,545,2,10,060,1,1,1,9,1,0,0,0,1,00\r",
            b"^D0882300,217,2300,500,217,5000,5000,480,500,540,450,560,560,2,02,060,1,0,1,9,1,0,0,0,1,00\xe9\r",
        ],
    },

and then I have to split the response into the respective components

        ESP_LOGD(TAG, "Decode P007PIRI");
        sscanf(tmp, "(%f %f %f %f %f %d %d %f %f %f %f %f %d %d %d %d %d %d %d %d %d %d %f %d %d",          // NOLINT
               &value_grid_rating_voltage_,
               &value_grid_rating_current_,
               &value_ac_output_rating_voltage_,
               &value_ac_output_rating_frequency_,
               &value_ac_output_rating_current_,
               &value_ac_output_rating_apparent_power_,
               &value_ac_output_rating_active_power_,
               &value_battery_rating_voltage_,
               &value_battery_recharge_voltage_,
               &value_battery_redischarge_voltage_,
               &value_battery_under_voltage_,
               &value_battery_bulk_voltage_,
               &value_battery_float_voltage_,
               &value_battery_type_,
               &value_current_max_ac_charging_current_,
               &value_current_max_charging_current_,
               &value_input_voltage_range_,
               &value_parallel_max_num_,
               &value_machine_type_,
               &value_topology_,
               &value_output_mode_,
               &value_output_source_priority_,
               &value_charger_source_priority_,
               &value_pv_ok_condition_for_parallel_,
               &value_pv_power_balance_);

...

syssi commented 1 year ago

You could register the sensor like this:

  PIPSOLAR_SENSOR(grid_rating_voltage, P007PIR, float)
  PIPSOLAR_SENSOR(grid_rating_current, P007PIR, float)

And extend/change the

Pipsolar::add_polling_command_(const char *command, ENUMPollingCommand polling_command)

method and prefix the used_polling_command.command with the ^. The used_polling_command.identifier should stay untouched because it's used the match the ENUM values.

BanannaJoe commented 1 year ago

Hello, since I have the same problem I'm trying for days to insert the ^ character in the used_polling_command.command method. Since I am not very fit in the programming language c, I get this unfortunately not. can someone give me a tip how I can implement this? Many greetings Christian

preussal commented 1 year ago

I gave it up. And prefer to use Python again, it runs stable and does what it should. https://github.com/jblance/mpp-solar/

BanannaJoe commented 1 year ago

Hello and thanks for the info.

I could not be satisfied with it because I want to change settings from HA too. I have now put something together myself. is still a bit fluffy, but it serves its purpose. I would like to change everything in the future still on Lambda but here I have to work myself in first.

I have a simple component for the UART communication erstell or copied from the Internet

#############################################################################
#include "esphome.h"

class UartReadLineSensor : public Component, public UARTDevice, public TextSensor {
 public:
  UartReadLineSensor(UARTComponent *parent) : UARTDevice(parent) {}

  void setup() override {
    // nothing to do here
  }

  int readline(int readch, char *buffer, int len)
  {
    static int pos = 0;
    int rpos;

    if (readch > 0) {
      switch (readch) {
        case '\n': // Ignore new-lines
          break;
        case '\r': // Return on CR
          rpos = pos;
          pos = 0;  // Reset position index ready for next time
          return rpos;
        default:
          if (pos < len-1) {
            buffer[pos++] = readch;
            buffer[pos] = 0;
          }
      }
    }
    // No end of line has been found, so return -1.
    return -1;
  }

  void loop() override {
    const int max_line_length = 80;
    static char buffer[max_line_length];
    while (available()) {
      if(readline(read(), buffer, max_line_length) > 0) {
        publish_state(buffer);
      }
    }
  }
};
#############################################################################

in ESPHome I set certain values via a button and read the return value.

#############################################################################
substitutions:
  name: pipsolar

esphome:
  name: ${name}
  platform: ESP8266
  board: d1_mini
  includes:
    - uart_read_line_sensor.h

wifi:
  ssid: "xxx"
  password: "xxx"

captive_portal:

ota:
  password: "12345678"

api:

# Enable logging
logger:  
  baud_rate: 0
  level: VERY_VERBOSE
  hardware_uart: UART1

# Enable Home Assistant

uart:
  id: uart0
  baud_rate: 2400
  tx_pin: TX
  rx_pin: RX

text_sensor:
- platform: custom
  lambda: |-
    auto my_custom_sensor = new UartReadLineSensor(id(uart0));
    App.register_component(my_custom_sensor);
    return {my_custom_sensor};
  text_sensors:
    id: "uart_readline"
    name: "EASUN_UART_Return"

button:
  - platform: template
    name: "GetInfos"
    on_press:
      - uart.write: "^P005GS\r"
  - platform: template
    name: "Solar_first"
    on_press:
      - uart.write: "^S009PCP0,0\xAC\r"
  - platform: template
    name: "Solar_Utiluty"
    on_press:
      - uart.write: "^S009PCP0,1\xAC\r"
  - platform: template
    name: "Solar_Only"
    on_press:
      - uart.write: "^S009PCP0,2\xAC\r"
  - platform: template
    name: "Battery_load_40A"
    on_press:
      - uart.write: "^S013MCHGC0,040"
  - platform: template
    name: "Battery_load_50A"
    on_press:
      - uart.write: "^S013MCHGC0,050"
  - platform: template
    name: "Battery_load_40A"
    on_press:
      - uart.write: "^S013MCHGC0,040"
  - platform: template
    name: "GetInfos_II"
    on_press:
      - uart.write: "^SP007PIRI"

interval:
  - interval: 10s
    then:
      - uart.write: "^P005GS\r"
#############################################################################

I then extract the power values from the string via a homeassitant sensor..

#############################################################################
- platform: template
  sensors:
    # EASUN1 Power
    easun1_power_watt:
      friendly_name: Easun1PowerWatt
      unit_of_measurement: W
      device_class: power
      value_template: >-
        {% set m = ((states.sensor.easun_uart_return.state.split(","))[0] )[:2]   %}
        {% if m == "^D" %}  
        {% set easun1_value = ((states.sensor.easun_uart_return.state.split(","))[16] )%}
        {% else %}  
        {% set easun1_value = ((states.sensor.easun1_power_watt.state ))%}
        {% endif %}
        {{easun1_value}}

    easun1_battery_voltage:
      friendly_name: Easun1BatteryVoltage
      unit_of_measurement: V
      device_class: voltage
      value_template: >-
        {% set m = ((states.sensor.easun_uart_return.state.split(","))[0] )[:2]   %}
        {% if m == "^D" %}  
        {% set easun1_value = ((states.sensor.easun_uart_return.state.split(","))[7] )%}
        {% else %}  
        {% set easun1_value = ((states.sensor.easun1_power_watt.state ))%}
        {% endif %}
        {{(easun1_value | int / 10 ) | round(1)}}

    easun1_battery_charging_current:
      friendly_name: Easun1ChargingBatteryCurrent
      unit_of_measurement: A
      device_class: current
      value_template: >-
        {% set m = ((states.sensor.easun_uart_return.state.split(","))[0] )[:2]   %}
        {% if m == "^D" %}  
        {% set easun1_value = ((states.sensor.easun_uart_return.state.split(","))[11] )%}
        {% else %}  
        {% set easun1_value = ((states.sensor.easun1_power_watt.state ))%}
        {% endif %}
        {{easun1_value | int}}

    easun1_battery_discharging_current:
      friendly_name: Easun1DischargingBatteryCurrent
      unit_of_measurement: A
      device_class: current
      value_template: >-
        {% set m = ((states.sensor.easun_uart_return.state.split(","))[0] )[:2]   %}
        {% if m == "^D" %}  
        {% set easun1_value = ((states.sensor.easun_uart_return.state.split(","))[10] )%}
        {% else %}  
        {% set easun1_value = ((states.sensor.easun1_power_watt.state ))%}
        {% endif %}
        {{easun1_value | int}}
#############################################################################

It is not very already solved but it works

syssi commented 1 year ago

I've pushed a feature branch to visualize the required changes to implement the PI18 protocol.

I would be happy about some example responses retrieved using:

https://github.com/syssi/esphome-pipsolar/blob/pi18/esp8266-example.yaml

I'm a bit confused by the response example above because it doesn't match with the frame structure.

BanannaJoe commented 1 year ago

Hello Syssi and thank you for your commitment. I have flashed the firmware once but with me still no feedback comes from the esp. However, I have seen that the special character is sent. I think I can cope with it now. I will make the days times a few test and give a feedback. which concerns the Frames agrees however with my documentation of P18. I am however also not at the PIRI command but at the P005GS around the achievement values. Kind regards Christian

image

syssi commented 1 year ago

The proper decoding of the ^P007PIRI isn't implemented yet. Some example responses would be helpful here. I would like to add new commands step by step.

BanannaJoe commented 1 year ago

Thanks again, happy to support you with tester results. Here the response in my environment

[09:43:02][D][uart_debug:158]: >>> "^P007PIRI\xEE8\r"
[09:43:02][D][pipsolar:838]: Sending polling command : ^P007PIRI with length 9
[09:43:07][D][pipsolar:755]: timeout command to poll: ^P007PIRI
syssi commented 1 year ago

Alright. It looks like you cannot support here because your inverter doesn't support the command? ;-)

BanannaJoe commented 1 year ago

I have done a test with sending the command directly by uart. here i get a proper response for both commands

[10:48:08][D][uart_debug:158]: >>> "^P005GSX\x14\r"
[10:48:08][VV][scheduler:026]: set_timeout(name='', timeout=2000)
[10:48:08][D][uart_debug:158]: <<< "^D1062312,500,0000,000,0000,0000,000,518,000,000,000,004,036,027,000,000,0302,0000,2438,0000,0,2,0,0,1,2,2,0\xDC\x8E\r"
[10:48:10][VV][scheduler:206]: Running timeout '' with interval=2000 last_execution=3185572 (now=3187573)
[10:48:10][D][uart_debug:158]: >>> "^P007PIRI\xC3\xAE8\r"
[10:48:10][VV][scheduler:026]: set_timeout(name='', timeout=2000)
[10:48:10][D][uart_debug:158]: <<< "^D0892300,243,2300,500,243,5600,5600,480,500,520,480,554,540,2,010,060,0,0,2,9,1,0,0,0,1,00\xD6x\r"
syssi commented 1 year ago

Do you have an idea why the checksum of your ^P007PIRI request is different?

BanannaJoe commented 1 year ago

Sorry, i dont have an idea but that is what i senp via uart for the test

  - uart.write: "^P007PIRI\xEE8\r"
  - delay: 2s
BanannaJoe commented 1 year ago

I am also a little puzzled about the command that comes from the ESP. In the test in which I simply send the command via uart is sent a coherent string. Image

when I compile your code the ESP sends the following Image

syssi commented 1 year ago

Did you use the same baud rate for both tests?

BanannaJoe commented 1 year ago

Yes always 2400

BeckoPopov commented 1 year ago

Hi Sebastian, Will this help? I released the following commands in Easun-Test.yaml

      # Query protocol ID
      - uart.write: "^P005PI\r"
      - delay: 2s

      #  Query current time
      - uart.write: "^P004T\r"
      - delay: 2s

      #  Query total generated energy
      - uart.write: "^P005ET\r"
      - delay: 2s

      #  Query generated energy of year
      - uart.write: "^P009EY\r"
      - delay: 2s

      #  Query generated energy of month
      - uart.write: "^P011EM\r"
      - delay: 2s

      #  Query generated energy of day
      - uart.write: "^P013ED\r"
      - delay: 2s

      #  Device Serial Number inquiry
      - uart.write: "^P005ID\r"
      - delay: 2s

      #  Device CPU version inquiry
      - uart.write: "^P006VFW\r"
      - delay: 2s

      #  Query Max. charging current selectable values
      - uart.write: "^P009MCHGCR\r"
      - delay: 2s

      #  Query Max. AC charging current selectable values
      - uart.write: "^MUCHGCR\r"
      - delay: 2s

      # Query different rated information of parallel system
      - uart.write: "^P007PRI\r"
      - delay: 2s

      #  Query general status of parallel system
      - uart.write: "^P007PGS\r"
      - delay: 2s

      #  Query fault and warning status
      - uart.write: "^P005FWS\r"
      - delay: 2s

      #  Query default value of changeable parameters
      - uart.write: "^P005DI\r"
      - delay: 2s

      #  Device rated information
      - uart.write: "^P007PIRI\r"
      - delay: 2s

      #  Query general status
      - uart.write: "^P005GS\r"
      - delay: 2s

      #  Device working mode inquiry
      - uart.write: "^P006MOD\r"
      - delay: 2s

      #  Query enable/disable flag status
      - uart.write: "^P007FLAG\r"
      - delay: 2s

      #  Query AC charge time bucket
      - uart.write: "^P005ACCT\r"
      - delay: 2s

      #  Query AC supply load time bucket
      - uart.write: "^P005ACLT\r"
      - delay: 2s

this is the answer:

[11:02:48][D][uart_debug:158]: >>> "^P007PRI\r"
[11:02:48][D][uart_debug:158]: <<< "^D0401,00,0\x02001 020  00.000000,0,000,000,0]e\r"
[11:02:50][D][uart_debug:158]: >>> "^P007PGS\r"
[11:02:50][D][uart_debug:158]: <<< "^D1131,0,00,0000,171,0000,000,0000,0000,12338,12336,000,000,257,337,257,337,000,5535,2345,0514,0000,0,0,0,0,0,0,051e\xC1\r"
[11:02:52][D][uart_debug:158]: >>> "^P005FWS\r"
[11:02:52][D][uart_debug:158]: <<< "^D03900,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0\xA6|\r"
[11:02:54][D][uart_debug:158]: >>> "^P005DI\r"
[11:02:54][D][uart_debug:158]: <<< "^D0682300,500,0,408,540,564,460,540,060,30,0,0,1,0,0,0,1,0,0,1,1,0,1,1Q\xE6\r"
[11:02:56][D][uart_debug:158]: >>> "^P007PIRI\r"
[11:02:56][D][uart_debug:158]: <<< "^D0892300,243,2300,500,243,5600,5600,480,470,530,440,555,544,2,030,090,1,1,2,9,0,0,1,0,1,00\x82\xAE\r"
[11:02:58][D][uart_debug:158]: >>> "^P005GS\r"
[11:02:58][D][uart_debug:158]: <<< "^D1062422,499,2305,499,1475,1458,026,526,000,000,000,007,084,046,000,000,1924,0000,2654,0000,0,2,0,1,1,2,0,1\\\xE8\r"
[11:02:59][D][uart_debug:158]: >>> "^P005PI\r"
[11:02:59][D][uart_debug:158]: <<< "^D00518;\x03\r"
[11:03:00][D][uart_debug:158]: >>> "^P006MOD\r"
[11:03:00][D][uart_debug:158]: <<< "^D00503\xB9Y\r"
[11:03:01][D][uart_debug:158]: >>> "^P004T\r"
[11:03:01][D][uart_debug:158]: <<< "^D01720230320114613\x0E\xAE\r"
[11:03:02][D][uart_debug:158]: >>> "^P007FLAG\r"
[11:03:02][D][uart_debug:158]: <<< "^D0201,1,1,0,0,1,0,1,0\xF6=\r"
[11:03:03][D][uart_debug:158]: >>> "^P005ET\r"
[11:03:04][D][uart_debug:158]: <<< "^D01100802946\x0Ey\r"
[11:03:04][D][uart_debug:158]: >>> "^P005ACCT\r"
[11:03:04][D][uart_debug:158]: <<< "^D0120000,0000\xC2\x1C\r"
[11:03:05][D][uart_debug:158]: >>> "^P009EY\r"
[11:03:06][D][uart_debug:158]: <<< "^0\e\xE3\r"
[11:03:06][D][uart_debug:158]: >>> "^P005ACLT\r"
[11:03:06][D][uart_debug:158]: <<< "^D0120000,0000\xC2\x1C\r"
[11:03:07][D][uart_debug:158]: >>> "^P011EM\r"
[11:03:08][D][uart_debug:158]: <<< "^0\e\xE3\r"
[11:03:09][D][uart_debug:158]: >>> "^P013ED\r"
[11:03:10][D][uart_debug:158]: <<< "^0\e\xE3\r"
[11:03:11][D][uart_debug:158]: >>> "^P005ID\r"
[11:03:11][D][uart_debug:158]: <<< "^D0251496132209100190000000\xB2[\r"
[11:03:13][D][uart_debug:158]: >>> "^P006VFW\r"
[11:03:13][D][uart_debug:158]: <<< "^D02007601,08028,00000\x00\xC2\r"
[11:03:15][D][uart_debug:158]: >>> "^P009MCHGCR\r"
[11:03:16][D][uart_debug:158]: <<< "^D050010,020,030,040,050,060,070,080,090,100,110,120z\xCB\r"
[11:03:17][D][uart_debug:158]: >>> "^MUCHGCR\r"
[11:03:17][D][uart_debug:158]: <<< "(NAKss\r"
[11:03:19][D][uart_debug:158]: >>> "^P007PRI\r"
[11:03:20][D][uart_debug:158]: <<< "^D0401,00,0\x02001 010  00.000000,0,000,000,0\x93\xB9\r"
syssi commented 1 year ago

Yes. This is helpful. Could you provide another log? I would be happy about 2-3 responses per command in total. I will provide the same commands including a checksum at the end to get an idea your inverter supports command incl. checksum too.

BanannaJoe commented 1 year ago

I did the same test as BeckoPopov with all Commands 3 times. This is my result

[11:33:20][D][uart_debug:158]: >>> "^P004T\r"
[11:33:21][D][uart_debug:158]: <<< "^D01720230322113042a\x14\r"
[11:33:25][D][uart_debug:158]: >>> "^P005ET\r"
[11:33:26][D][uart_debug:158]: <<< "^D01100320400\x8Ac\r"
[11:33:30][D][uart_debug:158]: >>> "^P005ET\r"
[11:33:31][D][uart_debug:158]: <<< "^D01100320401\x9AB\r"
[11:33:35][D][uart_debug:158]: >>> "^P005ET\r"
[11:33:36][D][uart_debug:158]: <<< "^D01100320403\xBA\x00\r"
[11:33:40][D][uart_debug:158]: >>> "^P009EY\r"
[11:33:41][D][uart_debug:158]: <<< "^0\e\xE3\r"
[11:33:45][D][uart_debug:158]: >>> "^P009EY\r"
[11:33:46][D][uart_debug:158]: <<< "^0\e\xE3\r"
[11:33:50][D][uart_debug:158]: >>> "^P009EY\r"
[11:33:51][D][uart_debug:158]: <<< "^D01100000469;\x8F\r"
[11:33:55][D][uart_debug:158]: >>> "^P011EM\r"
[11:33:56][D][uart_debug:158]: <<< "^0\e\xE3\r"
[11:34:00][D][uart_debug:158]: >>> "^P011EM\r"
[11:34:01][D][uart_debug:158]: <<< "^0\e\xE3\r"
[11:34:06][D][uart_debug:158]: >>> "^P011EM\r"
[11:34:06][D][uart_debug:158]: <<< "^0\e\xE3\r"
[11:34:11][D][uart_debug:158]: >>> "^P013ED\r"
[11:34:11][D][uart_debug:158]: <<< "^0\e\xE3\r"
[11:34:16][D][uart_debug:158]: >>> "^P013ED\r"
[11:34:16][D][uart_debug:158]: <<< "^0\e\xE3\r"
[11:34:21][D][uart_debug:158]: >>> "^P013ED\r"
[11:34:21][D][uart_debug:158]: <<< "^D01100000473\xA9\xF4\r"
[11:34:26][D][uart_debug:158]: >>> "^P005ID\r"
[11:34:26][D][uart_debug:158]: <<< "^D0251496132203100542000000\x99\xAF\r"
[11:34:31][D][uart_debug:158]: >>> "^P005ID\r"
[11:34:31][D][uart_debug:158]: <<< "^D0251496132203100542000000\x99\xAF\r"
[11:34:36][D][uart_debug:158]: >>> "^P005ID\r"
[11:34:36][D][uart_debug:158]: <<< "^D0251496132203100542000000\x99\xAF\r"
[11:34:41][D][uart_debug:158]: >>> "^P006VFW\r"
[11:34:41][D][uart_debug:158]: <<< "^D02005600,08025,00000\xEF\xC2\r"
[11:34:46][D][uart_debug:158]: >>> "^P006VFW\r"
[11:34:46][D][uart_debug:158]: <<< "^D02005600,08025,00000\xEF\xC2\r"
[11:34:51][D][uart_debug:158]: >>> "^P006VFW\r"
[11:34:51][D][uart_debug:158]: <<< "^D02005600,08025,00000\xEF\xC2\r"
[11:34:56][D][uart_debug:158]: >>> "^P009MCHGCR\r"
[11:34:56][D][uart_debug:158]: <<< "^D050010,020,030,040,050,060,070,080,090,100,110,120z\xCB\r"
[11:35:01][D][uart_debug:158]: >>> "^P009MCHGCR\r"
[11:35:01][D][uart_debug:158]: <<< "^D050010,020,030,040,050,060,070,080,090,100,110,120z\xCB\r"
[11:35:06][D][uart_debug:158]: >>> "^P009MCHGCR\r"
[11:35:06][D][uart_debug:158]: <<< "^D050010,020,030,040,050,060,070,080,090,100,110,120z\xCB\r"
[11:35:11][D][uart_debug:158]: >>> "^MUCHGCR\r"
[11:35:11][D][uart_debug:158]: <<< "(NAKss\r"
[11:35:16][D][uart_debug:158]: >>> "^MUCHGCR\r"
[11:35:16][D][uart_debug:158]: <<< "(NAKss\r"
[11:35:21][D][uart_debug:158]: >>> "^MUCHGCR\r"
[11:35:21][D][uart_debug:158]: <<< "(NAKss\r"
[11:35:26][D][uart_debug:158]: >>> "^P007PRI\r"
[11:35:26][D][uart_debug:158]: <<< "^D0401,00,0\x02001 090 00.000000,0,000,000,0\x9E[\r"
[11:35:31][D][uart_debug:158]: >>> "^P007PRI\r"
[11:35:31][D][uart_debug:158]: <<< "^D0401,00,0\x02001 090 00.000000,0,000,000,0\x9E[\r"
[11:35:36][D][uart_debug:158]: >>> "^P007PRI\r"
[11:35:36][D][uart_debug:158]: <<< "^D0401,00,0\x02001 000 00.000000,0,000,000,0\xD6\x0E\r"
[11:35:41][D][uart_debug:158]: >>> "^P007PGS\r"
[11:35:41][D][uart_debug:158]: <<< "^D1131,9,00,0000,000,0000,000,0000,0000,12336,12336,000,000,000,336,000,336,000,5535,2336,0514,0000,0,0,0,0,0,0,033\x03@\r"
[11:35:46][D][uart_debug:158]: >>> "^P007PGS\r"
[11:35:46][D][uart_debug:158]: <<< "^D1131,9,00,0000,000,0000,000,0000,0000,12336,12336,000,000,000,336,000,336,000,5535,2336,0514,0000,0,0,0,0,0,0,033\x03@\r"
[11:35:51][D][uart_debug:158]: >>> "^P007PGS\r"
[11:35:51][D][uart_debug:158]: <<< "^D1131,9,00,0000,000,0000,000,0000,0000,12336,12336,000,000,000,336,000,336,000,5535,2336,0514,0000,0,0,0,0,0,0,033\x03@\r"
[11:35:56][D][uart_debug:158]: >>> "^P005FWS\r"
[11:35:56][D][uart_debug:158]: <<< "^D03900,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0\xA6|\r"
[11:36:01][D][uart_debug:158]: >>> "^P005FWS\r"
[11:36:01][D][uart_debug:158]: <<< "^D03900,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0\xA6|\r"
[11:36:06][D][uart_debug:158]: >>> "^P005FWS\r"
[11:36:06][D][uart_debug:158]: <<< "^D03900,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0\xA6|\r"
[11:36:11][D][uart_debug:158]: >>> "^P005DI\r"
[11:36:11][D][uart_debug:158]: <<< "^D0682300,500,0,408,540,564,460,540,060,30,0,0,1,0,0,0,1,0,0,1,1,0,1,1Q\xE6\r"
[11:36:16][D][uart_debug:158]: >>> "^P005DI\r"
[11:36:16][D][uart_debug:158]: <<< "^D0682300,500,0,408,540,564,460,540,060,30,0,0,1,0,0,0,1,0,0,1,1,0,1,1Q\xE6\r"
[11:36:21][D][uart_debug:158]: >>> "^P005DI\r"
[11:36:21][D][uart_debug:158]: <<< "^D0682300,500,0,408,540,564,460,540,060,30,0,0,1,0,0,0,1,0,0,1,1,0,1,1Q\xE6\r"
[11:36:26][D][uart_debug:158]: >>> "^P007PIRI\r"
[11:36:26][D][uart_debug:158]: <<< "^D0892300,243,2300,500,243,5600,5600,480,500,520,480,554,540,2,010,060,0,0,2,9,1,0,0,0,1,00\xD6x\r"
[11:36:31][D][uart_debug:158]: >>> "^P007PIRI\r"
[11:36:31][D][uart_debug:158]: <<< "^D0892300,243,2300,500,243,5600,5600,480,500,520,480,554,540,2,010,060,0,0,2,9,1,0,0,0,1,00\xD6x\r"
[11:36:36][D][uart_debug:158]: >>> "^P007PIRI\r"
[11:36:36][D][uart_debug:158]: <<< "^D0892300,243,2300,500,243,5600,5600,480,500,520,480,554,540,2,010,060,0,0,2,9,1,0,0,0,1,00\xD6x\r"
[11:36:41][D][uart_debug:158]: >>> "^P005GS\r"
[11:36:41][D][uart_debug:158]: <<< "^D1062301,499,0000,000,0000,0000,000,522,000,000,000,009,040,032,000,000,0557,0000,2436,0000,0,2,0,0,1,2,2,0\x13\f\r"
[11:36:46][D][uart_debug:158]: >>> "^P005GS\r"
[11:36:46][D][uart_debug:158]: <<< "^D1062304,499,0000,000,0000,0000,000,523,000,000,000,009,041,032,000,000,0556,0000,2431,0000,0,2,0,0,1,2,2,0\v\xA2\r"
[11:36:51][D][uart_debug:158]: >>> "^P005GS\r"
[11:36:52][D][uart_debug:158]: <<< "^D1062305,499,0000,000,0000,0000,000,523,000,000,000,009,041,032,000,000,0556,0000,2448,0000,0,2,0,0,1,2,2,0\x9B\xAF\r"
[11:36:56][D][uart_debug:158]: >>> "^P006MOD\r"
[11:36:56][D][uart_debug:158]: <<< "^D00505\xD9\x9F\r"
[11:37:01][D][uart_debug:158]: >>> "^P006MOD\r"
[11:37:01][D][uart_debug:158]: <<< "^D00505\xD9\x9F\r"
[11:37:06][D][uart_debug:158]: >>> "^P006MOD\r"
[11:37:06][D][uart_debug:158]: <<< "^D00505\xD9\x9F\r"
[11:37:14][D][uart_debug:158]: >>> "^P004T\r"
[11:37:14][D][uart_debug:158]: <<< "^D017202303221134334b\r"
[11:37:19][D][uart_debug:158]: >>> "^P004T\r"
[11:37:19][D][uart_debug:158]: <<< "^D01720230322113439\x95)\r"
BanannaJoe commented 1 year ago

I am also a little puzzled about the command that comes from the ESP. In the test in which I simply send the command via uart is sent a coherent string. Image

when I compile your code the ESP sends the following Image

OK, this problem has cleared up. I use the RX, TX pins and had forgotten to change that and switch the logger to UART1.

BeckoPopov commented 1 year ago

Hello, I made a local file pipsolar.h, pipsolar.cpp using P005GS. I created the various protocol sensors and I tried to decorate it. I get in HA only 0 I realized that the answer I got was empty or incorrectly decoded. I only left listening to the PIPSOLAR_TEXT_SENSOR(last_qpigs, P005GS)

easun1.yaml

text_sensor:

For the sample in the pipsolar.cpp file I added this: this->lastqpigs->publish_state("test test"); this->lastqpigs->publish_state(tmp); I get this: [15:51:28][D][pipsolar:848]: Sending polling command : ^P005GS with length 7 [15:51:29][D][pipsolar:453]: Decode P005GSs [15:51:29][D][text_sensor:067]: 'easun1 last_qpigs': Sending state 'test test' ' [15:51:29][D][pipsolar:848]: Sending polling command : ^P005GS with length 7 [15:51:30][D][pipsolar:453]: Decode P005GSs [15:51:30][D][text_sensor:067]: 'easun1 last_qpigs': Sending state 'test test' ' Here I have to see the answer to the buffer, and I see only " ' " Is it possible "^" yes, it interferes with the buffer and if so how I can remove it before I start processing it. My knowledge is insignificant

syssi commented 1 year ago

@BeckoPopov Could you upload your code somewhere? Do you know how to use git?

BeckoPopov commented 1 year ago

no

BeckoPopov commented 1 year ago

give me an email to send them to you

syssi commented 1 year ago

basti@***

BeckoPopov commented 1 year ago

Done, you have mail

BeckoPopov commented 1 year ago

I think I found the problem The buffer overflows and from there and the control amount is not true #pipsolar.h static const size_t PIPSOLAR_READ_BUFFER_LENGTH = 150; From 110 to change to 150. It works for me. I have already written almost all the sensors. After testing them, I will send them to Sebastian

syssi commented 1 year ago

Good job! I'm happy about your progress here.

BeckoPopov commented 1 year ago

I have been dealing with Esphome recently, I want to ask a question. How do I make the static data (serial number, QPIRI values P007PIRI), receive it only upon request from home assistant? If I configure a lot of memory sensors ends

syssi commented 1 year ago

The implementation doesn't allow a different handling for selected sensors. If the value doesn't change the value doesn't get published again and again. It gets published on every change only. I recommend to remove "useless" sensors from the YAML on the long run.

SeByDocKy commented 1 year ago

Nice adding :)

BanannaJoe commented 1 year ago

Hello all, I have today again started the attempt to connect my EASUN with PI18 with this module to HA. However, I get as soon as I connect tx after the first command was sentet only (NAKss\r from EASUN back. This does not stop by itself. Does anyone have an idea? Many greetings Christian Screenshot_20230726_124421_Home Assistant