mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-30 06:06:36 +00:00
[Solax X1] Rework request and respond processing
Complete rework of the request cycle and the respond processing. This is more reliable and reusable for more and further requests. Right now the serial number of the converter is requested and displayed in the WebUI.
This commit is contained in:
parent
e47b0c7356
commit
3679ec4c08
@ -1,7 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
xnrg_12_solaxX1.ino - Solax X1 inverter RS485 support for Tasmota
|
xnrg_12_solaxX1.ino - Solax X1 inverter RS485 support for Tasmota
|
||||||
|
|
||||||
Copyright (C) 2021 Pablo Zerón
|
Copyright (C) 2021 by Pablo Zerón
|
||||||
|
Copyright (C) 2022 by Stefan Wershoven
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -35,12 +36,6 @@
|
|||||||
|
|
||||||
#include <TasmotaSerial.h>
|
#include <TasmotaSerial.h>
|
||||||
|
|
||||||
enum solaxX1_Error
|
|
||||||
{
|
|
||||||
solaxX1_ERR_NO_ERROR,
|
|
||||||
solaxX1_ERR_CRC_ERROR
|
|
||||||
};
|
|
||||||
|
|
||||||
union {
|
union {
|
||||||
uint32_t ErrMessage;
|
uint32_t ErrMessage;
|
||||||
struct {
|
struct {
|
||||||
@ -90,10 +85,6 @@ const char kSolaxError[] PROGMEM =
|
|||||||
D_SOLAX_ERROR_0 "|" D_SOLAX_ERROR_1 "|" D_SOLAX_ERROR_2 "|" D_SOLAX_ERROR_3 "|" D_SOLAX_ERROR_4 "|" D_SOLAX_ERROR_5 "|"
|
D_SOLAX_ERROR_0 "|" D_SOLAX_ERROR_1 "|" D_SOLAX_ERROR_2 "|" D_SOLAX_ERROR_3 "|" D_SOLAX_ERROR_4 "|" D_SOLAX_ERROR_5 "|"
|
||||||
D_SOLAX_ERROR_6 "|" D_SOLAX_ERROR_7 "|" D_SOLAX_ERROR_8;
|
D_SOLAX_ERROR_6 "|" D_SOLAX_ERROR_7 "|" D_SOLAX_ERROR_8;
|
||||||
|
|
||||||
/*********************************************************************************************/
|
|
||||||
|
|
||||||
TasmotaSerial *solaxX1Serial;
|
|
||||||
|
|
||||||
struct SOLAXX1 {
|
struct SOLAXX1 {
|
||||||
int16_t temperature = 0;
|
int16_t temperature = 0;
|
||||||
float energy_today = 0;
|
float energy_today = 0;
|
||||||
@ -104,25 +95,10 @@ struct SOLAXX1 {
|
|||||||
uint32_t runtime_total = 0;
|
uint32_t runtime_total = 0;
|
||||||
float dc1_power = 0;
|
float dc1_power = 0;
|
||||||
float dc2_power = 0;
|
float dc2_power = 0;
|
||||||
|
|
||||||
int16_t runMode = 0;
|
int16_t runMode = 0;
|
||||||
uint32_t errorCode = 0;
|
uint32_t errorCode = 0;
|
||||||
} solaxX1;
|
} solaxX1;
|
||||||
|
|
||||||
union {
|
|
||||||
uint8_t status;
|
|
||||||
struct {
|
|
||||||
uint8_t freeBit7:1; // Bit7
|
|
||||||
uint8_t freeBit6:1; // Bit6
|
|
||||||
uint8_t freeBit5:1; // Bit5
|
|
||||||
uint8_t queryOffline:1; // Bit4
|
|
||||||
uint8_t queryOfflineSend:1; // Bit3
|
|
||||||
uint8_t hasAddress:1; // Bit2
|
|
||||||
uint8_t inverterAddressSend:1; // Bit1
|
|
||||||
uint8_t inverterSnReceived:1; // Bit0
|
|
||||||
};
|
|
||||||
} protocolStatus;
|
|
||||||
|
|
||||||
uint8_t header[2] = {0xAA, 0x55};
|
uint8_t header[2] = {0xAA, 0x55};
|
||||||
uint8_t source[2] = {0x00, 0x00};
|
uint8_t source[2] = {0x00, 0x00};
|
||||||
uint8_t destination[2] = {0x00, 0x00};
|
uint8_t destination[2] = {0x00, 0x00};
|
||||||
@ -131,15 +107,16 @@ uint8_t functionCode[1] = {0x00};
|
|||||||
uint8_t dataLength[1] = {0x00};
|
uint8_t dataLength[1] = {0x00};
|
||||||
uint8_t data[16] = {0};
|
uint8_t data[16] = {0};
|
||||||
|
|
||||||
|
TasmotaSerial *solaxX1Serial;
|
||||||
uint8_t message[30];
|
uint8_t message[30];
|
||||||
|
bool AddressAssigned = true;
|
||||||
|
uint8_t solaxX1_send_retry = 20;
|
||||||
|
uint8_t solaxX1_queryData_count = 0;
|
||||||
|
uint8_t solaxX1_QueryID_count = 240;
|
||||||
|
uint8_t solaxX1SerialNumber[16] = {0x6e, 0x2f, 0x61}; // "n/a"
|
||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
|
|
||||||
bool solaxX1_RS485ReceiveReady(void)
|
|
||||||
{
|
|
||||||
return (solaxX1Serial->available() > 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void solaxX1_RS485Send(uint16_t msgLen)
|
void solaxX1_RS485Send(uint16_t msgLen)
|
||||||
{
|
{
|
||||||
memcpy(message, header, 2);
|
memcpy(message, header, 2);
|
||||||
@ -151,8 +128,7 @@ void solaxX1_RS485Send(uint16_t msgLen)
|
|||||||
memcpy(message + 9, data, sizeof(data));
|
memcpy(message + 9, data, sizeof(data));
|
||||||
uint16_t crc = solaxX1_calculateCRC(message, msgLen); // calculate out crc bytes
|
uint16_t crc = solaxX1_calculateCRC(message, msgLen); // calculate out crc bytes
|
||||||
|
|
||||||
while (solaxX1Serial->available() > 0)
|
while (solaxX1Serial->available() > 0) { // read serial if any old data is available
|
||||||
{ // read serial if any old data is available
|
|
||||||
solaxX1Serial->read();
|
solaxX1Serial->read();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,12 +147,11 @@ void solaxX1_RS485Send(uint16_t msgLen)
|
|||||||
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, message, msgLen);
|
AddLogBuffer(LOG_LEVEL_DEBUG_MORE, message, msgLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t solaxX1_RS485Receive(uint8_t *value)
|
bool solaxX1_RS485Receive(uint8_t *value)
|
||||||
{
|
{
|
||||||
uint8_t len = 0;
|
uint8_t len = 0;
|
||||||
|
|
||||||
while (solaxX1Serial->available() > 0)
|
while (solaxX1Serial->available() > 0) {
|
||||||
{
|
|
||||||
value[len++] = (uint8_t)solaxX1Serial->read();
|
value[len++] = (uint8_t)solaxX1Serial->read();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,14 +159,7 @@ uint8_t solaxX1_RS485Receive(uint8_t *value)
|
|||||||
|
|
||||||
uint16_t crc = solaxX1_calculateCRC(value, len - 2); // calculate out crc bytes
|
uint16_t crc = solaxX1_calculateCRC(value, len - 2); // calculate out crc bytes
|
||||||
|
|
||||||
if (value[len - 1] == lowByte(crc) && value[len - 2] == highByte(crc))
|
return !(value[len - 1] == lowByte(crc) && value[len - 2] == highByte(crc));
|
||||||
{ // check calc crc with received crc
|
|
||||||
return solaxX1_ERR_NO_ERROR;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return solaxX1_ERR_CRC_ERROR;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t solaxX1_calculateCRC(uint8_t *bExternTxPackage, uint8_t bLen)
|
uint16_t solaxX1_calculateCRC(uint8_t *bExternTxPackage, uint8_t bLen)
|
||||||
@ -200,13 +168,23 @@ uint16_t solaxX1_calculateCRC(uint8_t *bExternTxPackage, uint8_t bLen)
|
|||||||
uint16_t wChkSum;
|
uint16_t wChkSum;
|
||||||
wChkSum = 0;
|
wChkSum = 0;
|
||||||
|
|
||||||
for (i = 0; i < bLen; i++)
|
for (i = 0; i < bLen; i++) {
|
||||||
{
|
|
||||||
wChkSum = wChkSum + bExternTxPackage[i];
|
wChkSum = wChkSum + bExternTxPackage[i];
|
||||||
}
|
}
|
||||||
return wChkSum;
|
return wChkSum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void solaxX1_QueryOfflineInverters(void)
|
||||||
|
{
|
||||||
|
source[0] = 0x01;
|
||||||
|
destination[0] = 0x00;
|
||||||
|
destination[1] = 0x00;
|
||||||
|
controlCode[0] = 0x10;
|
||||||
|
functionCode[0] = 0x00;
|
||||||
|
dataLength[0] = 0x00;
|
||||||
|
solaxX1_RS485Send(9);
|
||||||
|
}
|
||||||
|
|
||||||
void solaxX1_SendInverterAddress(void)
|
void solaxX1_SendInverterAddress(void)
|
||||||
{
|
{
|
||||||
source[0] = 0x00;
|
source[0] = 0x00;
|
||||||
@ -230,6 +208,17 @@ void solaxX1_QueryLiveData(void)
|
|||||||
solaxX1_RS485Send(9);
|
solaxX1_RS485Send(9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void solaxX1_QueryIDData(void)
|
||||||
|
{
|
||||||
|
source[0] = 0x01;
|
||||||
|
destination[0] = 0x00;
|
||||||
|
destination[1] = INVERTER_ADDRESS;
|
||||||
|
controlCode[0] = 0x11;
|
||||||
|
functionCode[0] = 0x03;
|
||||||
|
dataLength[0] = 0x00;
|
||||||
|
solaxX1_RS485Send(9);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t solaxX1_ParseErrorCode(uint32_t code){
|
uint8_t solaxX1_ParseErrorCode(uint32_t code){
|
||||||
ErrCode.ErrMessage = code;
|
ErrCode.ErrMessage = code;
|
||||||
|
|
||||||
@ -247,26 +236,25 @@ uint8_t solaxX1_ParseErrorCode(uint32_t code){
|
|||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
|
|
||||||
uint8_t solaxX1_send_retry = 20;
|
|
||||||
uint8_t solaxX1_queryData_count = 0;
|
|
||||||
|
|
||||||
void solaxX1250MSecond(void) // Every 250 milliseconds
|
void solaxX1250MSecond(void) // Every 250 milliseconds
|
||||||
{
|
{
|
||||||
uint8_t value[61] = {0};
|
uint8_t value[70] = {0};
|
||||||
bool data_ready = solaxX1_RS485ReceiveReady();
|
uint8_t i;
|
||||||
|
|
||||||
if (data_ready)
|
if (solaxX1Serial->available()) {
|
||||||
{
|
if (solaxX1_RS485Receive(value)) { // CRC-error -> no further action
|
||||||
if (protocolStatus.hasAddress)
|
|
||||||
{
|
|
||||||
uint8_t error = solaxX1_RS485Receive(value);
|
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
DEBUG_SENSOR_LOG(PSTR("SX1: Data response CRC error"));
|
DEBUG_SENSOR_LOG(PSTR("SX1: Data response CRC error"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
solaxX1_send_retry = 20; // Inverter is responding
|
||||||
solaxX1_send_retry = 20;
|
|
||||||
|
if (value[0] != 0xAA || value[1] != 0x55) { // Check for header
|
||||||
|
DEBUG_SENSOR_LOG(PSTR("SX1: Check for header failed"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value[6] == 0x11 && value[7] == 0x82) { // received "Response for query (live data)"
|
||||||
Energy.data_valid[0] = 0;
|
Energy.data_valid[0] = 0;
|
||||||
|
|
||||||
solaxX1.temperature = (value[9] << 8) | value[10]; // Temperature
|
solaxX1.temperature = (value[9] << 8) | value[10]; // Temperature
|
||||||
@ -296,103 +284,76 @@ void solaxX1250MSecond(void) // Every 250 milliseconds
|
|||||||
solaxX1.dc2_power = solaxX1.dc2_voltage * solaxX1.dc2_current;
|
solaxX1.dc2_power = solaxX1.dc2_voltage * solaxX1.dc2_current;
|
||||||
|
|
||||||
EnergyUpdateTotal(); // 484.708 kWh
|
EnergyUpdateTotal(); // 484.708 kWh
|
||||||
}
|
DEBUG_SENSOR_LOG(PSTR("SX1: received live data"));
|
||||||
} else { // end hasAddress
|
return;
|
||||||
// check address confirmation from inverter
|
} // end received "Response for query (live data)"
|
||||||
if (protocolStatus.inverterAddressSend)
|
|
||||||
{
|
|
||||||
uint8_t error = solaxX1_RS485Receive(value);
|
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
DEBUG_SENSOR_LOG(PSTR("SX1: Address confirmation response CRC error"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (value[6] == 0x10 && value[7] == 0x81 && value[9] == 0x06)
|
|
||||||
{
|
|
||||||
DEBUG_SENSOR_LOG(PSTR("SX1: Set hasAddress"));
|
|
||||||
protocolStatus.status = 0b00100000; // hasAddress
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check inverter serial number and send the set address request
|
if (value[6] == 0x11 && value[7] == 0x83) { // received "Response for query (ID data)"
|
||||||
if (protocolStatus.queryOfflineSend)
|
for (i = 49; i <= 62; i++) { // get "real" serial number
|
||||||
{
|
solaxX1SerialNumber[i - 49] = value[i];
|
||||||
uint8_t error = solaxX1_RS485Receive(value);
|
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
DEBUG_SENSOR_LOG(PSTR("SX1: Query Offline response CRC error"));
|
|
||||||
}
|
}
|
||||||
else
|
AddLog(LOG_LEVEL_INFO, PSTR("SX1: Inverter serial number: %s"),(char*)solaxX1SerialNumber);
|
||||||
{
|
DEBUG_SENSOR_LOG(PSTR("SX1: received ID data"));
|
||||||
// Serial number from query response
|
return;
|
||||||
if (value[6] == 0x10 && value[7] == 0x80 && protocolStatus.inverterSnReceived == false)
|
} // end received "Response for query (ID data)"
|
||||||
{
|
|
||||||
for (uint8_t i = 9; i <= 22; i++)
|
if (value[6] == 0x10 && value[7] == 0x80) { // received "register request"
|
||||||
{
|
solaxX1_queryData_count = 5; // give time for next query
|
||||||
|
for (i = 9; i <= 22; i++) { // store serial number for register
|
||||||
data[i - 9] = value[i];
|
data[i - 9] = value[i];
|
||||||
}
|
}
|
||||||
solaxX1_SendInverterAddress();
|
DEBUG_SENSOR_LOG(PSTR("SX1: received register request and send register address"));
|
||||||
protocolStatus.status = 0b1100000; // inverterSnReceived and inverterAddressSend
|
solaxX1_SendInverterAddress(); // "send register address"
|
||||||
DEBUG_SENSOR_LOG(PSTR("SX1: Set inverterSnReceived and inverterAddressSend"));
|
return;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (protocolStatus.hasAddress) {
|
if (value[6] == 0x10 && value[7] == 0x81 && value[9] == 0x06) { // received "address confirm (ACK)"
|
||||||
if (solaxX1_queryData_count <= 0) {
|
solaxX1_queryData_count = 5; // give time for next query
|
||||||
|
AddressAssigned = true;
|
||||||
|
DEBUG_SENSOR_LOG(PSTR("SX1: received \"address confirm (ACK)\""));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end solaxX1Serial->available()
|
||||||
|
|
||||||
|
// DEBUG_SENSOR_LOG(PSTR("SX1: AddressAssigned: %d, solaxX1_queryData_count: %d, solaxX1_send_retry: %d, solaxX1_QueryID_count: %d"), AddressAssigned, solaxX1_queryData_count, solaxX1_send_retry, solaxX1_QueryID_count);
|
||||||
|
if (AddressAssigned) {
|
||||||
|
if (!solaxX1_queryData_count) { // normal periodically query
|
||||||
solaxX1_queryData_count = 5;
|
solaxX1_queryData_count = 5;
|
||||||
DEBUG_SENSOR_LOG(PSTR("SX1: Send Retry count: %d"), solaxX1_send_retry);
|
if (solaxX1_QueryID_count) { // normal live query
|
||||||
|
DEBUG_SENSOR_LOG(PSTR("SX1: Send periodically live query"));
|
||||||
solaxX1_QueryLiveData();
|
solaxX1_QueryLiveData();
|
||||||
|
} else { // normal ID query
|
||||||
|
DEBUG_SENSOR_LOG(PSTR("SX1: Send periodically ID query"));
|
||||||
|
solaxX1_QueryIDData();
|
||||||
}
|
}
|
||||||
|
solaxX1_QueryID_count++; // query ID every 256th time
|
||||||
|
} // end normal periodically query
|
||||||
solaxX1_queryData_count--;
|
solaxX1_queryData_count--;
|
||||||
}
|
if (!solaxX1_send_retry) { // Inverter went "off"
|
||||||
|
|
||||||
// request to the inverter the serial number if offline
|
|
||||||
if (protocolStatus.queryOffline)
|
|
||||||
{
|
|
||||||
// We sent the message to query inverters in offline status
|
|
||||||
source[0] = 0x01;
|
|
||||||
destination[1] = 0x00;
|
|
||||||
controlCode[0] = 0x10;
|
|
||||||
functionCode[0] = 0x00;
|
|
||||||
dataLength[0] = 0x00;
|
|
||||||
solaxX1_RS485Send(9);
|
|
||||||
protocolStatus.status = 0b00010000; // queryOfflineSend
|
|
||||||
solaxX1_send_retry = 20;
|
solaxX1_send_retry = 20;
|
||||||
DEBUG_SENSOR_LOG(PSTR("SX1: Query Offline Send"));
|
DEBUG_SENSOR_LOG(PSTR("SX1: Inverter went \"off\""));
|
||||||
}
|
|
||||||
|
|
||||||
if (solaxX1_send_retry == 0) {
|
|
||||||
if (protocolStatus.hasAddress) {
|
|
||||||
protocolStatus.status = 0b00001000; // queryOffline
|
|
||||||
Energy.data_valid[0] = ENERGY_WATCHDOG;
|
Energy.data_valid[0] = ENERGY_WATCHDOG;
|
||||||
|
|
||||||
solaxX1.temperature = solaxX1.dc1_voltage = solaxX1.dc2_voltage = solaxX1.dc1_current = solaxX1.dc2_current = solaxX1.dc1_power = 0;
|
solaxX1.temperature = solaxX1.dc1_voltage = solaxX1.dc2_voltage = solaxX1.dc1_current = solaxX1.dc2_current = solaxX1.dc1_power = 0;
|
||||||
solaxX1.dc2_power = Energy.current[0] = Energy.voltage[0] = Energy.frequency[0] = Energy.active_power[0] = 0;
|
solaxX1.dc2_power = Energy.current[0] = Energy.voltage[0] = Energy.frequency[0] = Energy.active_power[0] = 0;
|
||||||
solaxX1.runMode = -1; // off(line)
|
solaxX1.runMode = -1; // off(line)
|
||||||
} else {
|
AddressAssigned = false;
|
||||||
if (protocolStatus.queryOfflineSend) {
|
} // end Inverter went "off"
|
||||||
protocolStatus.status = 0b00001000; // queryOffline
|
} else { // sent query for inverters in offline status
|
||||||
DEBUG_SENSOR_LOG(PSTR("SX1: Set Query Offline"));
|
if (!solaxX1_send_retry) {
|
||||||
}
|
|
||||||
solaxX1_send_retry = 20;
|
solaxX1_send_retry = 20;
|
||||||
|
DEBUG_SENSOR_LOG(PSTR("SX1: Sent query for inverters in offline state"));
|
||||||
|
solaxX1_QueryOfflineInverters();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
solaxX1_send_retry--;
|
||||||
|
|
||||||
if (!data_ready && solaxX1_send_retry > 0) { solaxX1_send_retry--; }
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void solaxX1SnsInit(void)
|
void solaxX1SnsInit(void)
|
||||||
{
|
{
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("SX1: Solax X1 Inverter Init"));
|
AddLog(LOG_LEVEL_INFO, PSTR("SX1: Init - RX-pin: %d, TX-pin: %d, RTS-pin: %d"), Pin(GPIO_SOLAXX1_RX), Pin(GPIO_SOLAXX1_TX), Pin(GPIO_SOLAXX1_RTS));
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("SX1: RX-pin: %d, TX-pin: %d, RTS-pin: %d"), Pin(GPIO_SOLAXX1_RX), Pin(GPIO_SOLAXX1_TX), Pin(GPIO_SOLAXX1_RTS));
|
|
||||||
// DEBUG_SENSOR_LOG(PSTR("SX1: RX pin: %d, TX pin: %d"), Pin(GPIO_SOLAXX1_RX), Pin(GPIO_SOLAXX1_TX));
|
|
||||||
protocolStatus.status = 0b00100000; // hasAddress
|
|
||||||
|
|
||||||
solaxX1Serial = new TasmotaSerial(Pin(GPIO_SOLAXX1_RX), Pin(GPIO_SOLAXX1_TX), 1);
|
solaxX1Serial = new TasmotaSerial(Pin(GPIO_SOLAXX1_RX), Pin(GPIO_SOLAXX1_TX), 1);
|
||||||
if (solaxX1Serial->begin(SOLAXX1_SPEED)) {
|
if (solaxX1Serial->begin(SOLAXX1_SPEED)) {
|
||||||
if (solaxX1Serial->hardwareSerial()) { ClaimSerial(); }
|
if (solaxX1Serial->hardwareSerial()) { ClaimSerial(); }
|
||||||
@ -426,7 +387,8 @@ const char HTTP_SNS_solaxX1_DATA2[] PROGMEM =
|
|||||||
const char HTTP_SNS_solaxX1_DATA3[] PROGMEM =
|
const char HTTP_SNS_solaxX1_DATA3[] PROGMEM =
|
||||||
"{s}" D_SOLAX_X1 " " D_UPTIME "{m}%s " D_UNIT_HOUR "{e}"
|
"{s}" D_SOLAX_X1 " " D_UPTIME "{m}%s " D_UNIT_HOUR "{e}"
|
||||||
"{s}" D_SOLAX_X1 " " D_STATUS "{m}%s"
|
"{s}" D_SOLAX_X1 " " D_STATUS "{m}%s"
|
||||||
"{s}" D_SOLAX_X1 " " D_ERROR "{m}%s";
|
"{s}" D_SOLAX_X1 " " D_ERROR "{m}%s"
|
||||||
|
"{s}" D_SOLAX_X1 " Inverter SN{m}%s";
|
||||||
#endif // USE_WEBSERVER
|
#endif // USE_WEBSERVER
|
||||||
|
|
||||||
void solaxX1Show(bool json)
|
void solaxX1Show(bool json)
|
||||||
@ -452,8 +414,7 @@ void solaxX1Show(bool json)
|
|||||||
char status[33];
|
char status[33];
|
||||||
GetTextIndexed(status, sizeof(status), solaxX1.runMode + 1, kSolaxMode);
|
GetTextIndexed(status, sizeof(status), solaxX1.runMode + 1, kSolaxMode);
|
||||||
|
|
||||||
if (json)
|
if (json) {
|
||||||
{
|
|
||||||
ResponseAppend_P(PSTR(",\"" D_JSON_SOLAR_POWER "\":%s,\"" D_JSON_PV1_VOLTAGE "\":%s,\"" D_JSON_PV1_CURRENT "\":%s,\"" D_JSON_PV1_POWER "\":%s"),
|
ResponseAppend_P(PSTR(",\"" D_JSON_SOLAR_POWER "\":%s,\"" D_JSON_PV1_VOLTAGE "\":%s,\"" D_JSON_PV1_CURRENT "\":%s,\"" D_JSON_PV1_POWER "\":%s"),
|
||||||
solar_power, pv1_voltage, pv1_current, pv1_power);
|
solar_power, pv1_voltage, pv1_current, pv1_power);
|
||||||
#ifdef SOLAXX1_PV2
|
#ifdef SOLAXX1_PV2
|
||||||
@ -477,7 +438,8 @@ void solaxX1Show(bool json)
|
|||||||
WSContentSend_Temp(D_SOLAX_X1, solaxX1.temperature);
|
WSContentSend_Temp(D_SOLAX_X1, solaxX1.temperature);
|
||||||
char errorCodeString[33];
|
char errorCodeString[33];
|
||||||
WSContentSend_PD(HTTP_SNS_solaxX1_DATA3, runtime, status,
|
WSContentSend_PD(HTTP_SNS_solaxX1_DATA3, runtime, status,
|
||||||
GetTextIndexed(errorCodeString, sizeof(errorCodeString), solaxX1_ParseErrorCode(solaxX1.errorCode), kSolaxError));
|
GetTextIndexed(errorCodeString, sizeof(errorCodeString), solaxX1_ParseErrorCode(solaxX1.errorCode), kSolaxError),
|
||||||
|
solaxX1SerialNumber);
|
||||||
#endif // USE_WEBSERVER
|
#endif // USE_WEBSERVER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user