Integracja z HA inwertera jsdsolar j12000hc

Jak prawidłowo zamieszczać YAML, inny kod lub logi w postach na forum

To issue to piękny przykład dlaczego nie pisać na githubie po polsku, ukraińsku, czy chińsku…
ale OK widzę z jakiego YAMLa wystartowałeś

substitutions:
  hostname: jdsolar-j5500hpc
  device_name: "Jdsolar J5500HPC"
  uart_rx_pin: GPIO16
  uart_tx_pin: GPIO17

esphome:
  name: ${hostname}
  friendly_name: ${device_name}

esp32:
  board: esp32dev
  framework:
    type: arduino

logger:
  level: DEBUG
  baud_rate: 0

api:
  encryption:
    key: !secret api_key

ota:
  - platform: esphome
    password: !secret ota_password

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: "${hostname} Fallback"
    password: "12345678"

captive_portal:
web_server:
  port: 80

uart:
  - id: jd_uart
    tx_pin: ${uart_tx_pin}
    rx_pin: ${uart_rx_pin}
    baud_rate: 2400
    stop_bits: 1
    data_bits: 8
    parity: NONE

# ========== СЕНСОРИ ==========

sensor:
  - platform: uptime
    name: "${device_name} Uptime"
  - platform: wifi_signal
    name: "${device_name} WiFi Signal"
    update_interval: 60s

  # === БАТАРЕЯ ===
  - platform: template
    name: "${device_name} Battery Voltage"
    id: battery_voltage
    unit_of_measurement: "V"
    device_class: voltage
    state_class: measurement
    accuracy_decimals: 1
    
  - platform: template
    name: "${device_name} Battery Current"
    id: battery_current
    unit_of_measurement: "A"
    device_class: current
    state_class: measurement
    accuracy_decimals: 2
    
  - platform: template
    name: "${device_name} Battery Cells"
    id: battery_cells
    state_class: measurement
    
  - platform: template
    name: "${device_name} Battery EOD Voltage"
    id: battery_eod
    unit_of_measurement: "V"
    device_class: voltage
    state_class: measurement
    accuracy_decimals: 1
    
  - platform: template
    name: "${device_name} Battery Low Alarm"
    id: battery_low_alarm
    unit_of_measurement: "V"
    device_class: voltage
    state_class: measurement
    accuracy_decimals: 1
    
  - platform: template
    name: "${device_name} Battery Capacity"
    id: battery_capacity
    unit_of_measurement: "%"
    device_class: battery
    state_class: measurement

  # === МЕРЕЖА ===
  - platform: template
    name: "${device_name} Grid Voltage"
    id: grid_voltage
    unit_of_measurement: "V"
    device_class: voltage
    state_class: measurement
    accuracy_decimals: 1
    
  - platform: template
    name: "${device_name} Grid Frequency"
    id: grid_frequency
    unit_of_measurement: "Hz"
    device_class: frequency
    state_class: measurement
    accuracy_decimals: 2
    
  - platform: template
    name: "${device_name} Load Percentage"
    id: load_percentage
    unit_of_measurement: "%"
    state_class: measurement
    
  - platform: template
    name: "${device_name} Grid Daily Energy"
    id: grid_daily_energy
    unit_of_measurement: "Wh"
    device_class: energy
    state_class: total_increasing
    
  - platform: template
    name: "${device_name} Grid Total Energy"
    id: grid_total_energy
    unit_of_measurement: "Wh"
    device_class: energy
    state_class: total_increasing

  # === ВИХІД ===
  - platform: template
    name: "${device_name} Output Voltage"
    id: output_voltage
    unit_of_measurement: "V"
    device_class: voltage
    state_class: measurement
    accuracy_decimals: 1
    
  - platform: template
    name: "${device_name} Output Frequency"
    id: output_frequency
    unit_of_measurement: "Hz"
    device_class: frequency
    state_class: measurement
    accuracy_decimals: 2
    
  - platform: template
    name: "${device_name} Output Current"
    id: output_current
    unit_of_measurement: "A"
    device_class: current
    state_class: measurement
    accuracy_decimals: 2
    
  - platform: template
    name: "${device_name} Output Power"
    id: output_power
    unit_of_measurement: "W"
    device_class: power
    state_class: measurement
    
  - platform: template
    name: "${device_name} Output Apparent Power"
    id: output_apparent_power
    unit_of_measurement: "VA"
    device_class: apparent_power
    state_class: measurement
    
  - platform: template
    name: "${device_name} Output Daily Energy"
    id: output_daily_energy
    unit_of_measurement: "Wh"
    device_class: energy
    state_class: total_increasing
    
  - platform: template
    name: "${device_name} Output Total Energy"
    id: output_total_energy
    unit_of_measurement: "Wh"
    device_class: energy
    state_class: total_increasing

  # === PV ===
  - platform: template
    name: "${device_name} PV Voltage"
    id: pv_voltage
    unit_of_measurement: "V"
    device_class: voltage
    state_class: measurement
    accuracy_decimals: 1
    
  - platform: template
    name: "${device_name} PV Current"
    id: pv_current
    unit_of_measurement: "A"
    device_class: current
    state_class: measurement
    accuracy_decimals: 2
    
  - platform: template
    name: "${device_name} PV Charge Current"
    id: pv_charge_current
    unit_of_measurement: "A"
    device_class: current
    state_class: measurement
    accuracy_decimals: 2
    
  - platform: template
    name: "${device_name} PV Power"
    id: pv_power
    unit_of_measurement: "W"
    device_class: power
    state_class: measurement
    
  - platform: template
    name: "${device_name} PV Daily Energy"
    id: pv_daily_energy
    unit_of_measurement: "Wh"
    device_class: energy
    state_class: total_increasing
    
  - platform: template
    name: "${device_name} PV Total Energy"
    id: pv_total_energy
    unit_of_measurement: "Wh"
    device_class: energy
    state_class: total_increasing

  # === ЗАРЯД ===
  - platform: template
    name: "${device_name} Bus Voltage"
    id: bus_voltage
    unit_of_measurement: "V"
    device_class: voltage
    state_class: measurement
    accuracy_decimals: 1
    
  - platform: template
    name: "${device_name} Charge Voltage"
    id: charge_voltage
    unit_of_measurement: "V"
    device_class: voltage
    state_class: measurement
    accuracy_decimals: 1
    
  - platform: template
    name: "${device_name} Charge Current"
    id: charge_current
    unit_of_measurement: "A"
    device_class: current
    state_class: measurement
    accuracy_decimals: 1
    
  - platform: template
    name: "${device_name} Max Charge Current"
    id: max_charge_current
    unit_of_measurement: "A"
    device_class: current
    state_class: measurement
    accuracy_decimals: 2

  # === ІНВЕРТОР ===
  - platform: template
    name: "${device_name} Inverter Voltage"
    id: inv_voltage
    unit_of_measurement: "V"
    device_class: voltage
    state_class: measurement
    accuracy_decimals: 1
    
  - platform: template
    name: "${device_name} Inverter Frequency"
    id: inv_frequency
    unit_of_measurement: "Hz"
    device_class: frequency
    state_class: measurement
    accuracy_decimals: 2
    
  - platform: template
    name: "${device_name} Inverter Current"
    id: inv_current
    unit_of_measurement: "A"
    device_class: current
    state_class: measurement
    accuracy_decimals: 1

  # === ТЕМПЕРАТУРА ===
  - platform: template
    name: "${device_name} PV Temp"
    id: temp_pv
    unit_of_measurement: "°C"
    device_class: temperature
    state_class: measurement
    accuracy_decimals: 1
    
  - platform: template
    name: "${device_name} Charger Temp"
    id: temp_charger
    unit_of_measurement: "°C"
    device_class: temperature
    state_class: measurement
    accuracy_decimals: 1
    
  - platform: template
    name: "${device_name} Ambient Temp"
    id: temp_ambient
    unit_of_measurement: "°C"
    device_class: temperature
    state_class: measurement
    accuracy_decimals: 1
    
  - platform: template
    name: "${device_name} MPPT1 Temp"
    id: temp_mppt1
    unit_of_measurement: "°C"
    device_class: temperature
    state_class: measurement
    accuracy_decimals: 1

  # === ВЕНТИЛЯТОР ===
  - platform: template
    name: "${device_name} Fan Speed"
    id: fan_speed
    unit_of_measurement: "%"
    state_class: measurement
    
  - platform: template
    name: "${device_name} Fan1 RPM"
    id: fan1_rpm
    unit_of_measurement: "RPM"
    state_class: measurement
    
  - platform: template
    name: "${device_name} Fan2 RPM"
    id: fan2_rpm
    unit_of_measurement: "RPM"
    state_class: measurement

# ===== ТЕКСТОВІ СЕНСОРИ =====
text_sensor:
  - platform: wifi_info
    ip_address:
      name: "${device_name} IP"
  - platform: template
    name: "${device_name} Mode"
    id: working_mode
  - platform: template
    name: "${device_name} Battery Type"
    id: battery_type
  - platform: template
    name: "${device_name} Charge Stage"
    id: charge_stage
  - platform: template
    name: "${device_name} PV Status"
    id: pv_status
  - platform: template
    name: "${device_name} Fault"
    id: fault_code
  - platform: template
    name: "${device_name} Warning"
    id: warning_code

# ===== БІНАРНІ СЕНСОРИ =====
binary_sensor:
  - platform: template
    name: "${device_name} Grid OK"
    id: grid_ok
    device_class: connectivity
  - platform: template
    name: "${device_name} PV Charging"
    id: pv_charging
    device_class: battery_charging
  - platform: template
    name: "${device_name} Battery Charging"
    id: battery_charging
    device_class: battery_charging
  - platform: template
    name: "${device_name} EQ Mode"
    id: eq_mode
  - platform: template
    name: "${device_name} Fan1 Fault"
    id: fan1_fault
    device_class: problem
  - platform: template
    name: "${device_name} Fan2 Fault"
    id: fan2_fault
    device_class: problem
  - platform: template
    name: "${device_name} Overload"
    id: overload
    device_class: problem
  - platform: template
    name: "${device_name} Over Temp"
    id: over_temp
    device_class: problem
  - platform: template
    name: "${device_name} Battery Low"
    id: battery_low
    device_class: problem

# ===== SWITCH =====
switch:
  - platform: template
    name: "${device_name} Power"
    id: inverter_power
    optimistic: true
    turn_on_action:
      - uart.write:
          id: jd_uart
          data: "SON\r"
    turn_off_action:
      - uart.write:
          id: jd_uart
          data: "SOFF\r"

# ===== ОПИТУВАННЯ =====
interval:
  - interval: 10s
    then:
      - uart.write: {id: jd_uart, data: "GBAT\r"}
      - delay: 500ms
      - uart.write: {id: jd_uart, data: "GLINE\r"}
      - delay: 500ms
      - uart.write: {id: jd_uart, data: "GOP\r"}
      - delay: 500ms
      - uart.write: {id: jd_uart, data: "GPV\r"}
      - delay: 500ms
      - uart.write: {id: jd_uart, data: "GCHG\r"}
      - delay: 500ms
      - uart.write: {id: jd_uart, data: "GTMP\r"}
      - delay: 500ms
      - uart.write: {id: jd_uart, data: "GINV\r"}
      - delay: 500ms
      - uart.write: {id: jd_uart, data: "GBUS\r"}
      - delay: 500ms
      - uart.write: {id: jd_uart, data: "FAN???\r"}
      - delay: 500ms
      - uart.write: {id: jd_uart, data: "BL\r"}
      - delay: 500ms
      - uart.write: {id: jd_uart, data: "GMOD\r"}

  # ===== ПАРСИНГ ВІДПОВІДЕЙ =====
  - interval: 100ms
    then:
      - lambda: |-
          static std::string buffer;
          
          while (id(jd_uart).available()) {
            uint8_t c;
            id(jd_uart).read_byte(&c);
            
            if (c == '\r') {
              if (buffer.length() > 0) {
                ESP_LOGD("jdsolar", "RX: %s", buffer.c_str());
                
                if (buffer[0] == '(') {
                  std::string data = buffer.substr(1);
                  std::vector<std::string> parts;
                  size_t pos = 0;
                  
                  while ((pos = data.find(" ")) != std::string::npos) {
                    parts.push_back(data.substr(0, pos));
                    data.erase(0, pos + 1);
                  }
                  if (data.length() > 0) parts.push_back(data);
                  
                  // GBAT - (AAA.A BBB.BB CC DD.D EE.E)
                  if (parts.size() == 5 && parts[0].find(".") != std::string::npos && parts[0].length() <= 5) {
                    id(battery_voltage).publish_state(atof(parts[0].c_str()));
                    id(battery_current).publish_state(atof(parts[1].c_str()));
                    id(battery_cells).publish_state(atoi(parts[2].c_str()));
                    id(battery_eod).publish_state(atof(parts[3].c_str()));
                    id(battery_low_alarm).publish_state(atof(parts[4].c_str()));
                  }
                  
                  // GLINE - (AAA.A BB.BB CCC.C DDD.D EEE.E FFF.F GG.GG HH.HH IIIII JJJ KKKKK LLLLL MMMMM)
                  else if (parts.size() == 13) {
                    id(grid_voltage).publish_state(atof(parts[0].c_str()));
                    id(grid_frequency).publish_state(atof(parts[1].c_str()));
                    id(load_percentage).publish_state(atof(parts[9].c_str()));
                    id(grid_daily_energy).publish_state(atof(parts[10].c_str()) * 10);
                    uint32_t ge_h = atoi(parts[11].c_str());
                    uint32_t ge_l = atoi(parts[12].c_str());
                    id(grid_total_energy).publish_state((ge_h * 100000 + ge_l) * 10);
                  }
                  
                  // GOP - (AAA.A BB.BB CCC.CC DD.DD EEEEE FFFFF GGGGG HHHHH IIIII JJJ KKKKK LLLLL MMMMM NNNNN OOOOO)
                  else if (parts.size() >= 15 && parts[0].find(".") != std::string::npos) {
                    id(output_voltage).publish_state(atof(parts[0].c_str()));
                    id(output_frequency).publish_state(atof(parts[1].c_str()));
                    id(output_current).publish_state(atof(parts[2].c_str()));
                    id(output_power).publish_state(atof(parts[4].c_str()));
                    id(output_apparent_power).publish_state(atof(parts[6].c_str()));
                    id(output_daily_energy).publish_state(atof(parts[13].c_str()) * 10);
                    if (parts.size() >= 16) {
                      uint32_t oe_h = atoi(parts[14].c_str());
                      uint32_t oe_l = atoi(parts[15].c_str());
                      id(output_total_energy).publish_state((oe_h * 100000 + oe_l) * 10);
                    }
                  }
                  
                  // GCHG - (AAA.A BBB.B CC DDD.D EEE.EE FFF.FF GG.G HH.H II.I JJJ.JJ KKKK LLL MMM NNN O P Q R ...)
                  else if (parts.size() >= 18) {
                    id(bus_voltage).publish_state(atof(parts[0].c_str()));
                    id(charge_voltage).publish_state(atof(parts[1].c_str()));
                    id(charge_current).publish_state(atof(parts[3].c_str()));
                    id(max_charge_current).publish_state(atof(parts[9].c_str()));
                    
                    id(eq_mode).publish_state(atoi(parts[14].c_str()) == 1);
                    
                    int btype = atoi(parts[15].c_str());
                    id(battery_type).publish_state(
                      btype == 0 ? "Lead Acid" : 
                      btype == 1 ? "Flooded" : 
                      btype == 2 ? "Lithium" : "Custom"
                    );
                    
                    int cmode = atoi(parts[17].c_str());
                    id(charge_stage).publish_state(
                      cmode == 0 ? "Stop" : 
                      cmode == 1 ? "CC" : 
                      cmode == 2 ? "CV" : "Float"
                    );
                    id(battery_charging).publish_state(cmode >= 1 && cmode <= 3);
                  }
                  
                  // GPV - (AAA.A BBB.B CC.CC DD.DD EEEEE FF G H ...)
                  else if (parts.size() >= 20 && parts[4].length() <= 5) {
                    id(pv_voltage).publish_state(atof(parts[0].c_str()));
                    id(pv_charge_current).publish_state(atof(parts[2].c_str()));
                    id(pv_current).publish_state(atof(parts[3].c_str()));
                    id(pv_power).publish_state(atof(parts[4].c_str()));
                    
                    int pvst = atoi(parts[5].c_str());
                    id(pv_status).publish_state(
                      pvst == 0 ? "Standby" : 
                      pvst == 1 ? "Ready" : 
                      pvst == 2 ? "CV" : "MPPT"
                    );
                    id(pv_charging).publish_state(atoi(parts[6].c_str()) == 1);
                    
                    if (parts.size() >= 21) {
                      id(pv_daily_energy).publish_state(atof(parts[18].c_str()) * 10);
                      uint32_t pe_h = atoi(parts[19].c_str());
                      uint32_t pe_l = atoi(parts[20].c_str());
                      id(pv_total_energy).publish_state((pe_h * 100000 + pe_l) * 10);
                    }
                  }
                  
                  // GTMP - (NNN.N MMM.M AAA.A III.I ZZZ.Z)
                  else if (parts.size() == 5 && parts[0].length() > 3) {
                    id(temp_pv).publish_state(atof(parts[0].c_str()));
                    id(temp_charger).publish_state(atof(parts[1].c_str()));
                    id(temp_ambient).publish_state(atof(parts[2].c_str()));
                    id(temp_mppt1).publish_state(atof(parts[3].c_str()));
                    
                    id(over_temp).publish_state(
                      atof(parts[0].c_str()) > 70 || 
                      atof(parts[1].c_str()) > 70 ||
                      atof(parts[2].c_str()) > 50
                    );
                  }
                  
                  // GINV - (AAA.A BB.BB CCC.C)
                  else if (parts.size() == 3 && parts[1].find(".") != std::string::npos) {
                    id(inv_voltage).publish_state(atof(parts[0].c_str()));
                    id(inv_frequency).publish_state(atof(parts[1].c_str()));
                    id(inv_current).publish_state(atof(parts[2].c_str()));
                  }
                  
                  // FAN - (AAA BBB CCC D E)
                  else if (parts.size() == 5 && parts[0].length() == 3) {
                    id(fan_speed).publish_state(atof(parts[0].c_str()));
                    id(fan1_rpm).publish_state(atof(parts[1].c_str()));
                    id(fan2_rpm).publish_state(atof(parts[2].c_str()));
                    id(fan1_fault).publish_state(atoi(parts[3].c_str()) == 1);
                    id(fan2_fault).publish_state(atoi(parts[4].c_str()) == 1);
                  }
                }
                
                // GMOD - (M)
                else if (buffer.length() == 3 && buffer[0] == '(') {
                  char mode = buffer[1];
                  id(working_mode).publish_state(
                    mode == 'P' ? "Power On" : 
                    mode == 'S' ? "Standby" : 
                    mode == 'L' ? "Line Mode" : 
                    mode == 'B' ? "Battery Mode" : 
                    mode == 'F' ? "Fault" : 
                    mode == 'D' ? "Shutdown" : "Test"
                  );
                  id(grid_ok).publish_state(mode == 'L');
                }
                
                // BL - BLAAA
                else if (buffer.substr(0, 2) == "BL" && buffer.length() == 5) {
                  int capacity = atoi(buffer.substr(2, 3).c_str());
                  id(battery_capacity).publish_state(capacity);
                  id(battery_low).publish_state(capacity < 20);
                }
              }
              buffer.clear();
            } else {
              buffer += (char)c;
            }
          }