Hej
potrzebuję pomocy przy w zasadzie gotowym projekcie z github ( https://github.com/syssi/esphome-pipsolar)
wszystko śmiga tylko problem z parsowaniem odpowiedzi na QPIGS
Sending polling command : QPIGS with length 5 17:59:04 [D] [uart_debug:114] >>> 51:50:49:47:53:B7:A9:0D 17:59:05 [D] [uart_debug:114] <<< 28:32:31:37:2E:31:20:35:30:2E:30:20:32:31:37:2E:31:20:35:30:2E:30:20:30:31:39:35:20:30:31:38:31:20:30:30:33:20:32:39:39:20:30:30:2E:34:30:20:30:30:30:20:30:30:30:20:30:30:32:30:20:30:30:2E:30:20:30:30:30:2E:30:20:30:30:2E:30:30:20:30:30:30:30:30:20:30:30:30:31:30:30:30:30:20:30:30:20:30:30:20:30:30:30:30:30:20:30:31:30:20:30:20:30:31:20:30:30:30:30:44:E3:0D 17:59:05 [VV ][scheduler:226] Running interval 'update' with interval=1000 last_execution=5664057 (now=5665057) 17:59:06 [VV ][scheduler:226] Running interval 'update' with interval=1000 last_execution=5665057 (now=5666061) 17:59:07 [VV ][scheduler:226] Running interval 'update' with interval=1000 last_execution=5666057 (now=5667057) 17:59:08 [VV ][scheduler:226] Running interval 'update' with interval=1000 last_execution=5667057 (now=5668062) 17:59:09 [VV ][scheduler:226] Running interval '' with interval=10000 last_execution=5658901 (now=5668901) 17:59:09 [VV ][scheduler:226] Running interval 'update' with interval=1000 last_execution=5668057 (now=5669057) 17:59:09 [D] [pipsolar:759] timeout command to poll: QPIGS 17:59:09 [D] [pipsolar:842]
przekroczony czas raczej wynika z przekroczeniem czasu biblioteki pipsolar a nie odczytem z portu który wygląda poprawnie.
Analiza QPIGS
Podział na pola (przykład):
- Grid voltage:
217.1
- Grid frequency:
50.0
- AC output voltage:
217.1
- AC output frequency:
50.0
- AC output apparent power:
0195
- AC output active power:
0181
- Output load percent:
003
- Bus voltage:
299
- Battery voltage:
00.40
- Battery charging current:
000
- Battery capacity:
000
- Inverter heat sink temperature:
0020
- PV input current:
00.0
- PV input voltage:
000.0
- SCC battery voltage:
00.00
- Battery discharge current:
00000
- Flags (
b7b6b5b4b3b2b1b0
):01 0 01
- Extra:
0000D
Miał ktoś podobny problem? O co to może chodzić?
Prawdopodobnie problem w tym że dane są rozdzielone są spacją nie przecinkiem. Ale nie wiem jak to sprawdzić ;(
Poddaje się
prawdopodobnie popełniłem głupotę ale nie wiem gdzie wiec znalazłem wyjście na ten moment
# ========================== # KONFIGURACJA OGÓLNA # ========================== substitutions: name: easun_falownik_pv tx_pin: GPIO16 rx_pin: GPIO17 esphome: name: ${name} platform: ESP32 board: esp32dev wifi: ssid: !secret wifi_ssid password: !secret wifi_password manual_ip: static_ip: 192.168.86.78 gateway: 192.168.86.1 subnet: 255.255.255.0 dns1: 8.8.8.8 dns2: 8.8.4.4 logger: level: DEBUG api: encryption: key: !secret key ota: password: !secret ota_password platform: esphome web_server: port: 80 # ========================== # KONFIGURACJA UART # ========================== uart: id: uart_0 baud_rate: 2400 tx_pin: GPIO16 rx_pin: GPIO17 debug: direction: BOTH after: delimiter: "\r" # Koniec wiadomości # Wysyłanie poleceń QPIGS interval: - interval: 10s then: - logger.log: level: INFO format: "Wysyłanie QPIGS..." - uart.write: [0x51, 0x50, 0x49, 0x47, 0x53, 0xB7, 0xA9, 0x0D] - delay: 3s - script.execute: parse_qpigs # Wysyłanie poleceń QPIRI - interval: 11s then: - logger.log: level: INFO format: "Wysyłanie QPIRI..." - uart.write: [0x51, 0x50, 0x49, 0x52, 0x49, 0xD7, 0xA9, 0x0D] - delay: 3s - script.execute: parse_qpiri # Wysyłanie poleceń QFLAG - interval: 12s then: - logger.log: level: INFO format: "Wysyłanie polecenia UART QFLAG..." - uart.write: [0x51, 0x46, 0x4C, 0x41, 0x47, 0xA9, 0x0D] # Polecenie QFLAG - delay: 2s - script.execute: parse_qflag # Uruchom skrypt przetwarzający dane QFLAG # QMOD - interval: 15s then: - logger.log: level: INFO format: "Wysyłanie polecenia UART QMOD..." - uart.write: [0x51, 0x4D, 0x4F, 0x44, 0x49, 0x0D] # Polecenie QMOD - delay: 2s - script.execute: parse_qmod # Uruchom skrypt przetwarzający dane QMOD # ========================== # SKRYPTY DO PARSOWANIA # ========================== # Skrypt przetwarzający dane QPIGS script: - id: parse_qpigs then: - lambda: |- static std::string buffer; uint8_t byte; while (id(uart_0).read_byte(&byte)) { char c = static_cast<char>(byte); buffer += c; if (c == '\r') { ESP_LOGI("UART", "Odebrano QPIGS: %s", buffer.c_str()); if (buffer[0] == '(' && buffer.length() > 70) { id(grid_voltage).publish_state(atof(buffer.substr(1, 5).c_str())); id(grid_frequency).publish_state(atof(buffer.substr(7, 4).c_str())); id(output_voltage).publish_state(atof(buffer.substr(12, 5).c_str())); id(output_frequency).publish_state(atof(buffer.substr(18, 4).c_str())); id(output_power).publish_state(atof(buffer.substr(20, 4).c_str())); id(load_percent).publish_state(atof(buffer.substr(25, 4).c_str())); id(battery_voltage_qpigs).publish_state(atof(buffer.substr(39, 5).c_str())); id(charge_current).publish_state(atof(buffer.substr(30, 3).c_str())); id(discharge_current).publish_state(atof(buffer.substr(34, 4).c_str())); id(system_status).publish_state(atoi(buffer.substr(68, 2).c_str())); id(pv_voltage).publish_state(atof(buffer.substr(58, 4).c_str())); id(pv_power).publish_state(atof(buffer.substr(63, 4).c_str())); } buffer.clear(); break; } } # Skrypt przetwarzający dane QPIRI - id: parse_qpiri then: - lambda: |- static std::string buffer; uint8_t byte; while (id(uart_0).read_byte(&byte)) { char c = static_cast<char>(byte); buffer += c; if (c == '\r') { ESP_LOGI("UART", "Odebrano QPIRI: %s", buffer.c_str()); if (buffer[0] == '(' && buffer.length() > 100) { id(ac_output_voltage).publish_state(atof(buffer.substr(1, 5).c_str())); id(battery_voltage_qpiri).publish_state(atof(buffer.substr(7, 5).c_str())); id(ac_input_voltage).publish_state(atof(buffer.substr(13, 5).c_str())); id(ac_output_frequency).publish_state(atof(buffer.substr(19, 4).c_str())); id(battery_charging_voltage).publish_state(atof(buffer.substr(24, 5).c_str())); id(ac_output_max_apparent_power).publish_state(atof(buffer.substr(30, 5).c_str())); id(ac_output_max_active_power).publish_state(atof(buffer.substr(36, 5).c_str())); id(battery_max_voltage).publish_state(atof(buffer.substr(42, 5).c_str())); id(battery_min_voltage).publish_state(atof(buffer.substr(48, 5).c_str())); id(battery_cutoff_voltage).publish_state(atof(buffer.substr(54, 5).c_str())); id(battery_recovery_voltage).publish_state(atof(buffer.substr(60, 5).c_str())); id(battery_float_charge_voltage).publish_state(atof(buffer.substr(66, 5).c_str())); id(battery_number).publish_state(atoi(buffer.substr(72, 2).c_str())); id(max_battery_charging_current).publish_state(atof(buffer.substr(75, 3).c_str())); id(inverter_temperature).publish_state(atof(buffer.substr(92, 4).c_str())); id(fan_mode).publish_state(atoi(buffer.substr(97, 1).c_str())); id(end_code).publish_state(atoi(buffer.substr(101, 3).c_str())); } buffer.clear(); break; } } # QFLAG - id: parse_qflag then: - lambda: |- static std::string buffer; uint8_t byte; while (id(uart_0).read_byte(&byte)) { char c = static_cast<char>(byte); buffer += c; if (c == '\r') { ESP_LOGI("UART", "Odebrano QFLAG: %s", buffer.c_str()); if (buffer[0] == '(' && buffer.length() > 15) { id(grid_bypass_flag).publish_state(atoi(buffer.substr(1, 1).c_str())); // Flaga bypassu sieci id(output_short_circuit_flag).publish_state(atoi(buffer.substr(2, 1).c_str())); // Flaga zwarcia wyjścia id(power_saving_mode_flag).publish_state(atoi(buffer.substr(3, 1).c_str())); // Flaga trybu oszczędzania energii id(battery_weak_flag).publish_state(atoi(buffer.substr(4, 1).c_str())); // Flaga słabej baterii id(load_on_flag).publish_state(atoi(buffer.substr(5, 1).c_str())); // Flaga włączenia obciążenia id(battery_overcharge_flag).publish_state(atoi(buffer.substr(6, 1).c_str())); // Flaga przeładowania baterii id(system_overheat_flag).publish_state(atoi(buffer.substr(7, 1).c_str())); // Flaga przegrzania systemu id(system_shutdown_flag).publish_state(atoi(buffer.substr(8, 1).c_str())); // Flaga wyłączenia systemu id(inverter_fault_flag).publish_state(atoi(buffer.substr(9, 1).c_str())); // Flaga awarii falownika id(charger_fault_flag).publish_state(atoi(buffer.substr(10, 1).c_str())); // Flaga awarii ładowarki id(pv_power_saving_flag).publish_state(atoi(buffer.substr(11, 1).c_str())); // Flaga oszczędzania PV id(internal_com_error_flag).publish_state(atoi(buffer.substr(12, 1).c_str())); // Flaga błędu komunikacji wewnętrznej id(emergency_shutdown_flag).publish_state(atoi(buffer.substr(13, 1).c_str())); // Flaga awaryjnego wyłączenia id(low_frequency_flag).publish_state(atoi(buffer.substr(14, 1).c_str())); // Flaga niskiej częstotliwości } buffer.clear(); break; } } # QMOD - id: parse_qmod then: - lambda: |- static std::string buffer; uint8_t byte; while (id(uart_0).read_byte(&byte)) { char c = static_cast<char>(byte); buffer += c; if (c == '\r') { ESP_LOGI("UART", "Odebrano QMOD: %s", buffer.c_str()); // Sprawdź poprawność odpowiedzi if (buffer[0] == '(' && buffer.length() == 3) { // Oczekiwany format QMOD: np. "(S)" char mode = buffer[1]; // Drugi znak to tryb pracy std::string mode_str; switch (mode) { case 'S': mode_str = "Standby"; break; case 'L': mode_str = "Line"; break; case 'B': mode_str = "Battery"; break; case 'F': mode_str = "Fault"; break; case 'P': mode_str = "Power Saving"; break; case 'H': mode_str = "Standby Heating"; break; default: mode_str = "Unknown"; break; } id(inverter_mode).publish_state(mode_str); } else { ESP_LOGW("QMOD", "Nieprawidłowa odpowiedź: %s", buffer.c_str()); id(inverter_mode).publish_state("Invalid Data"); } buffer.clear(); break; } } # ========================== # SENSORY # ========================== sensor: # Sensory dla QPIGS - platform: template name: "Napięcie Sieci (AC)" id: grid_voltage unit_of_measurement: "V" - platform: template name: "Częstotliwość Sieci (AC)" id: grid_frequency unit_of_measurement: "Hz" - platform: template name: "Napięcie Wyjściowe (AC)" id: output_voltage unit_of_measurement: "V" - platform: template name: "Częstotliwość Wyjściowa (AC)" id: output_frequency unit_of_measurement: "Hz" - platform: template name: "Moc Wyjściowa (W)" id: output_power unit_of_measurement: "W" - platform: template name: "Obciążenie (%)" id: load_percent unit_of_measurement: "%" - platform: template name: "Napięcie Baterii (QPIGS)" id: battery_voltage_qpigs unit_of_measurement: "V" - platform: template name: "Prąd Ładowania (A)" id: charge_current unit_of_measurement: "A" - platform: template name: "Prąd Rozładowania (A)" id: discharge_current unit_of_measurement: "A" - platform: template name: "Napięcie PV (V)" id: pv_voltage unit_of_measurement: "V" - platform: template name: "Moc PV (W)" id: pv_power unit_of_measurement: "W" - platform: template name: "Stan Systemu" id: system_status unit_of_measurement: "" # Sensory QPIRI - platform: template name: "Napięcie Wyjściowe (AC)" id: ac_output_voltage unit_of_measurement: "V" - platform: template name: "Napięcie Wejściowe (AC)" id: ac_input_voltage unit_of_measurement: "V" - platform: template name: "Częstotliwość Wyjściowa (AC)" id: ac_output_frequency unit_of_measurement: "Hz" - platform: template name: "Napięcie Ładowania Baterii (V)" id: battery_charging_voltage unit_of_measurement: "V" - platform: template name: "Maksymalna Moc Wyjściowa (VA)" id: ac_output_max_apparent_power unit_of_measurement: "VA" - platform: template name: "Maksymalna Moc Wyjściowa (W)" id: ac_output_max_active_power unit_of_measurement: "W" - platform: template name: "Maksymalne Napięcie Akumulatora (V)" id: battery_max_voltage unit_of_measurement: "V" - platform: template name: "Minimalne Napięcie Akumulatora (V)" id: battery_min_voltage unit_of_measurement: "V" - platform: template name: "Napięcie Odcięcia Akumulatora (V)" id: battery_cutoff_voltage unit_of_measurement: "V" - platform: template name: "Napięcie Odzysku Zasilania (V)" id: battery_recovery_voltage unit_of_measurement: "V" - platform: template name: "Napięcie Zakończenia Ładowania (V)" id: battery_float_charge_voltage unit_of_measurement: "V" - platform: template name: "Liczba Podłączonych Akumulatorów" id: battery_number unit_of_measurement: "" - platform: template name: "Maksymalny Prąd Ładowania Akumulatorów (A)" id: max_battery_charging_current unit_of_measurement: "A" - platform: template name: "Temperatura Falownika (°C)" id: inverter_temperature unit_of_measurement: "°C" - platform: template name: "Tryb Wentylatora" id: fan_mode unit_of_measurement: "" - platform: template name: "Kod Końcowy" id: end_code unit_of_measurement: "" - platform: template name: "Napięcie Baterii (QPIGS)" id: battery_voltage_qpiri unit_of_measurement: "V" binary_sensor: # Flagi QFLAG - platform: template name: "Bypass Sieci" id: grid_bypass_flag lambda: |- return id(grid_bypass_flag).state == 1; device_class: power - platform: template name: "Zwarcie Wyjścia" id: output_short_circuit_flag lambda: |- return id(output_short_circuit_flag).state == 1; device_class: safety - platform: template name: "Tryb Oszczędzania Energii" id: power_saving_mode_flag lambda: |- return id(power_saving_mode_flag).state == 1; device_class: power - platform: template name: "Słaba Bateria" id: battery_weak_flag lambda: |- return id(battery_weak_flag).state == 1; device_class: battery - platform: template name: "Obciążenie Włączone" id: load_on_flag lambda: |- return id(load_on_flag).state == 1; device_class: power - platform: template name: "Przeładowanie Baterii" id: battery_overcharge_flag lambda: |- return id(battery_overcharge_flag).state == 1; device_class: safety - platform: template name: "Przegrzanie Systemu" id: system_overheat_flag lambda: |- return id(system_overheat_flag).state == 1; device_class: problem - platform: template name: "Wyłączenie Systemu" id: system_shutdown_flag lambda: |- return id(system_shutdown_flag).state == 1; device_class: problem - platform: template name: "Awaria Falownika" id: inverter_fault_flag lambda: |- return id(inverter_fault_flag).state == 1; device_class: problem - platform: template name: "Awaria Ładowarki" id: charger_fault_flag lambda: |- return id(charger_fault_flag).state == 1; device_class: problem - platform: template name: "Tryb Oszczędzania PV" id: pv_power_saving_flag lambda: |- return id(pv_power_saving_flag).state == 1; device_class: power - platform: template name: "Błąd Komunikacji Wewnętrznej" id: internal_com_error_flag lambda: |- return id(internal_com_error_flag).state == 1; device_class: problem - platform: template name: "Awaryjne Wyłączenie" id: emergency_shutdown_flag lambda: |- return id(emergency_shutdown_flag).state == 1; device_class: safety - platform: template name: "Niska Częstotliwość" id: low_frequency_flag lambda: |- return id(low_frequency_flag).state == 1; device_class: problem # ========================== # TEKSTOWE SENSORY (QMOD) # ========================== text_sensor: - platform: template name: "Tryb Pracy Falownika" id: inverter_mode icon: "mdi:transmission-tower"
QMOD jeszcze nie działa reszta z grubsza poprawnie
Chętni sobie doszlifują.....lub nie 😉