Add support for Solax X1 inverter by Pablo Zerón

Add support for Solax X1 inverter by Pablo Zerón
This commit is contained in:
Theo Arends 2019-08-09 16:42:16 +02:00
parent 039a4f10b5
commit e0f08ec764
5 changed files with 98 additions and 97 deletions

View File

@ -3,6 +3,7 @@
* Add support for CHIRP soil moisture sensor by Christian Baars * Add support for CHIRP soil moisture sensor by Christian Baars
* Add debug compile features using defines DEBUG_TASMOTA_CORE, DEBUG_TASMOTA_DRIVER and DEBUG_TASMOTA_SENSOR. * Add debug compile features using defines DEBUG_TASMOTA_CORE, DEBUG_TASMOTA_DRIVER and DEBUG_TASMOTA_SENSOR.
* See DEBUG_CORE_LOG example in sonoff.ino and DEBUG_DRIVER_LOG example in xdrv_09_timers.ino * See DEBUG_CORE_LOG example in sonoff.ino and DEBUG_DRIVER_LOG example in xdrv_09_timers.ino
* Add support for Solax X1 inverter by Pablo Zerón
* *
* 6.6.0.3 20190725 * 6.6.0.3 20190725
* Change filename of configuration backup from using FriendlyName1 to Hostname solving diacritic issues (#2422) * Change filename of configuration backup from using FriendlyName1 to Hostname solving diacritic issues (#2422)

View File

@ -123,6 +123,7 @@
#define D_JSON_RESTARTING "Restarting" #define D_JSON_RESTARTING "Restarting"
#define D_JSON_RESTARTREASON "RestartReason" #define D_JSON_RESTARTREASON "RestartReason"
#define D_JSON_RSSI "RSSI" #define D_JSON_RSSI "RSSI"
#define D_JSON_RUNTIME "Runtime"
#define D_JSON_SAVEADDRESS "SaveAddress" #define D_JSON_SAVEADDRESS "SaveAddress"
#define D_JSON_SAVECOUNT "SaveCount" #define D_JSON_SAVECOUNT "SaveCount"
#define D_JSON_SAVED "Saved" #define D_JSON_SAVED "Saved"
@ -134,6 +135,7 @@
#define D_JSON_STARTDST "StartDST" // Start Daylight Savings Time #define D_JSON_STARTDST "StartDST" // Start Daylight Savings Time
#define D_JSON_STARTED "Started" #define D_JSON_STARTED "Started"
#define D_JSON_STARTUPUTC "StartupUTC" #define D_JSON_STARTUPUTC "StartupUTC"
#define D_JSON_STATUS "Status"
#define D_JSON_SUBNETMASK "Subnetmask" #define D_JSON_SUBNETMASK "Subnetmask"
#define D_JSON_SUCCESSFUL "Successful" #define D_JSON_SUCCESSFUL "Successful"
#define D_JSON_SUNRISE "Sunrise" #define D_JSON_SUNRISE "Sunrise"
@ -165,8 +167,6 @@
#define D_JSON_WRONG_PARAMETERS "Wrong parameters" #define D_JSON_WRONG_PARAMETERS "Wrong parameters"
#define D_JSON_YESTERDAY "Yesterday" #define D_JSON_YESTERDAY "Yesterday"
#define D_JSON_ZERO_POINT_CALIBRATION "Zero Point Calibration" #define D_JSON_ZERO_POINT_CALIBRATION "Zero Point Calibration"
#ifdef USE_SOLAX_X1
#define D_JSON_RUNTIME "Runtime"
#define D_JSON_PV1_VOLTAGE "Pv1Voltage" #define D_JSON_PV1_VOLTAGE "Pv1Voltage"
#define D_JSON_PV1_CURRENT "Pv1Current" #define D_JSON_PV1_CURRENT "Pv1Current"
#define D_JSON_PV1_POWER "Pv1Power" #define D_JSON_PV1_POWER "Pv1Power"
@ -174,8 +174,6 @@
#define D_JSON_PV2_CURRENT "Pv2Current" #define D_JSON_PV2_CURRENT "Pv2Current"
#define D_JSON_PV2_POWER "Pv2Power" #define D_JSON_PV2_POWER "Pv2Power"
#define D_JSON_SOLAR_POWER "SolarPower" #define D_JSON_SOLAR_POWER "SolarPower"
#define D_JSON_STATUS "Status"
#endif
#define D_RSLT_ENERGY "ENERGY" #define D_RSLT_ENERGY "ENERGY"
#define D_RSLT_HASS_STATE "HASS_STATE" #define D_RSLT_HASS_STATE "HASS_STATE"

View File

@ -404,11 +404,6 @@
#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code) #define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code)
#define WORKING_PERIOD 5 // Working period of the SDS Sensor, Takes a reading every X Minutes #define WORKING_PERIOD 5 // Working period of the SDS Sensor, Takes a reading every X Minutes
#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code) #define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code)
//#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k7 code)
#define SDM120_SPEED 2400 // SDM120-Modbus RS485 serial speed (default: 2400 baud)
#define USE_SDM220 // Add extra parameters for SDM220 (+0k1 code)
//#define USE_SDM630 // Add support for Eastron SDM630-Modbus energy meter (+2k code)
#define SDM630_SPEED 9600 // SDM630-Modbus RS485 serial speed (default: 9600 baud)
//#define USE_MP3_PLAYER // Use of the DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop //#define USE_MP3_PLAYER // Use of the DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop
#define MP3_VOLUME 10 // Set the startup volume on init, the range can be 0..30(max) #define MP3_VOLUME 10 // Set the startup volume on init, the range can be 0..30(max)
//#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code) //#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code)
@ -425,6 +420,15 @@
#define USE_PZEM_DC // Add support for PZEM003,017 Energy monitor (+1k1 code) #define USE_PZEM_DC // Add support for PZEM003,017 Energy monitor (+1k1 code)
#define USE_MCP39F501 // Add support for MCP39F501 Energy monitor as used in Shelly 2 (+3k1 code) #define USE_MCP39F501 // Add support for MCP39F501 Energy monitor as used in Shelly 2 (+3k1 code)
//#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k7 code)
#define SDM120_SPEED 2400 // SDM120-Modbus RS485 serial speed (default: 2400 baud)
#define USE_SDM220 // Add extra parameters for SDM220 (+0k1 code)
//#define USE_SDM630 // Add support for Eastron SDM630-Modbus energy meter (+2k code)
#define SDM630_SPEED 9600 // SDM630-Modbus RS485 serial speed (default: 9600 baud)
//#define USE_SOLAX_X1 // Add support for Solax X1 series Modbus log info (+4k1 code)
#define SOLAXX1_SPEED 9600 // Solax X1 Modbus RS485 serial speed (default: 9600 baud)
#define SOLAXX1_PV2 // Solax X1 using second PV
// -- Low level interface devices ----------------- // -- Low level interface devices -----------------
#define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor (1k6 code) #define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor (1k6 code)

View File

@ -177,7 +177,7 @@ void KNX_CB_Action(message_t const &msg, void *arg);
#define USE_ALECTO_V2 // Add support for decoding Alecto V2 sensors like ACH2010, WS3000 and DKW2012 using 868MHz RF sensor receiver (+1k7 code) #define USE_ALECTO_V2 // Add support for decoding Alecto V2 sensors like ACH2010, WS3000 and DKW2012 using 868MHz RF sensor receiver (+1k7 code)
#define USE_SM16716 // Add support for SM16716 RGB LED controller (+0k7 code) #define USE_SM16716 // Add support for SM16716 RGB LED controller (+0k7 code)
#define USE_HRE // Add support for Badger HR-E Water Meter (+1k4 code) #define USE_HRE // Add support for Badger HR-E Water Meter (+1k4 code)
//#define USE_SOLAX_X1 // Enable Solax X1 series log info support (+4k1 code) //#define USE_SOLAX_X1 // Add support for Solax X1 series Modbus log info (+4k1 code)
#endif // FIRMWARE_SENSORS #endif // FIRMWARE_SENSORS
/*********************************************************************************************\ /*********************************************************************************************\

View File

@ -18,12 +18,19 @@
*/ */
#ifdef USE_SOLAX_X1 #ifdef USE_SOLAX_X1
/*********************************************************************************************\
* Solax X1 Inverter
\*********************************************************************************************/
#define XSNS_49 49 #define XSNS_49 49
#define solaxX1_SPEED 9600 // default solax rs485 speed #ifndef SOLAXX1_SPEED
#define SOLAXX1_SPEED 9600 // default solax rs485 speed
#endif
#define PV2 // comment this line if you use only one PV input #define INVERTER_ADDRESS 0x0A
#define D_SOLAX_X1 "SolaxX1"
#include <TasmotaSerial.h> #include <TasmotaSerial.h>
@ -75,24 +82,11 @@ union {
}; };
} ErrCode; } ErrCode;
const char solax_mode_0[] PROGMEM = D_WAITING; const char kSolaxMode[] PROGMEM = D_WAITING "|" D_CHECKING "|" D_WORKING "|" D_FAILURE;
const char solax_mode_1[] PROGMEM = D_CHECKING;
const char solax_mode_2[] PROGMEM = D_WORKING;
const char solax_mode_3[] PROGMEM = D_FAILURE;
const char *const solaxX1_Mode[] PROGMEM = {solax_mode_0, solax_mode_1, solax_mode_2, solax_mode_3}; 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 "|"
const char solax_error_0[] PROGMEM = D_SOLAX_ERROR_0; D_SOLAX_ERROR_6 "|" D_SOLAX_ERROR_7 "|" D_SOLAX_ERROR_8;
const char solax_error_1[] PROGMEM = D_SOLAX_ERROR_1;
const char solax_error_2[] PROGMEM = D_SOLAX_ERROR_2;
const char solax_error_3[] PROGMEM = D_SOLAX_ERROR_3;
const char solax_error_4[] PROGMEM = D_SOLAX_ERROR_4;
const char solax_error_5[] PROGMEM = D_SOLAX_ERROR_5;
const char solax_error_6[] PROGMEM = D_SOLAX_ERROR_6;
const char solax_error_7[] PROGMEM = D_SOLAX_ERROR_7;
const char solax_error_8[] PROGMEM = D_SOLAX_ERROR_8;
const char *const solaxX1_ErrCode[] PROGMEM = {solax_error_0, solax_error_1, solax_error_2, solax_error_3, solax_error_4, solax_error_5, solax_error_6, solax_error_7, solax_error_8};
/*********************************************************************************************/ /*********************************************************************************************/
@ -135,8 +129,6 @@ uint8_t data[16] = {0};
uint8_t message[30]; uint8_t message[30];
#define INVERTER_ADDRESS 0x0A
/*********************************************************************************************/ /*********************************************************************************************/
bool solaxX1_RS485ReceiveReady(void) bool solaxX1_RS485ReceiveReady(void)
@ -236,7 +228,7 @@ void solaxX1_QueryLiveData()
uint8_t solaxX1_ParseErrorCode(uint32_t code){ uint8_t solaxX1_ParseErrorCode(uint32_t code){
ErrCode.ErrMessage = code; ErrCode.ErrMessage = code;
if (code == 0) return 0; if (code == 0) return 0;
if (ErrCode.MainsLostFault) return 1; if (ErrCode.MainsLostFault) return 1;
if (ErrCode.GridVoltFault) return 2; if (ErrCode.GridVoltFault) return 2;
@ -259,7 +251,8 @@ void solaxX1_Update(void) // Every Second
bool data_ready = solaxX1_RS485ReceiveReady(); bool data_ready = solaxX1_RS485ReceiveReady();
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "queryOffline: %d , queryOfflineSend: %d, hasAddress: %d, inverterAddressSend: %d, solaxX1_send_retry: %d"), queryOffline, queryOfflineSend, hasAddress, inverterAddressSend, solaxX1_send_retry); DEBUG_DRIVER_LOG(PSTR("SX1: queryOffline: %d , queryOfflineSend: %d, hasAddress: %d, inverterAddressSend: %d, solaxX1_send_retry: %d"),
queryOffline, queryOfflineSend, hasAddress, inverterAddressSend, solaxX1_send_retry);
if (!hasAddress && (data_ready || solaxX1_send_retry == 0)) if (!hasAddress && (data_ready || solaxX1_send_retry == 0))
{ {
@ -272,7 +265,7 @@ void solaxX1_Update(void) // Every Second
uint8_t error = solaxX1_RS485Receive(value); uint8_t error = solaxX1_RS485Receive(value);
if (error) if (error)
{ {
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "Address confirmation response CRC error")); DEBUG_DRIVER_LOG(PSTR("SX1: Address confirmation response CRC error"));
} }
else else
{ {
@ -291,7 +284,7 @@ void solaxX1_Update(void) // Every Second
uint8_t error = solaxX1_RS485Receive(value); uint8_t error = solaxX1_RS485Receive(value);
if (error) if (error)
{ {
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "Query Offline response CRC error")); DEBUG_DRIVER_LOG(PSTR("SX1: Query Offline response CRC error"));
} }
else else
{ {
@ -356,7 +349,7 @@ void solaxX1_Update(void) // Every Second
uint8_t error = solaxX1_RS485Receive(value); uint8_t error = solaxX1_RS485Receive(value);
if (error) if (error)
{ {
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "Data response CRC error")); DEBUG_DRIVER_LOG(PSTR("SX1: Data response CRC error"));
} }
else else
{ {
@ -365,7 +358,7 @@ void solaxX1_Update(void) // Every Second
sprintf(hexCar, "%02X", value[i]); sprintf(hexCar, "%02X", value[i]);
AddLog_P(LOG_LEVEL_DEBUG, hexCar); AddLog_P(LOG_LEVEL_DEBUG, hexCar);
}*/ }*/
solaxX1_nodata_count = 0; solaxX1_nodata_count = 0;
solaxX1_send_retry = 2; solaxX1_send_retry = 2;
uint32_t temporal = 0; uint32_t temporal = 0;
@ -421,7 +414,7 @@ void solaxX1_Update(void) // Every Second
//temporal = (value[53] << 8) | value[54]; // GFC fault value //temporal = (value[53] << 8) | value[54]; // GFC fault value
temporal = (value[58] << 8) | (value[57] << 8) | (value[56] << 8) | value[55]; // Error Code temporal = (value[58] << 8) | (value[57] << 8) | (value[56] << 8) | value[55]; // Error Code
solaxX1_errorCode = (uint32_t)temporal; solaxX1_errorCode = (uint32_t)temporal;
solaxX1_dc1_power = solaxX1_dc1_voltage * solaxX1_dc1_current; solaxX1_dc1_power = solaxX1_dc1_voltage * solaxX1_dc1_current;
solaxX1_dc2_power = solaxX1_dc2_voltage * solaxX1_dc2_current; solaxX1_dc2_power = solaxX1_dc2_voltage * solaxX1_dc2_current;
@ -440,7 +433,7 @@ void solaxX1_Update(void) // Every Second
{ // end hasAddress && (data_ready || solaxX1_send_retry == 0) { // end hasAddress && (data_ready || solaxX1_send_retry == 0)
if (solaxX1_nodata_count <= 10) // max. 10 sec without data if (solaxX1_nodata_count <= 10) // max. 10 sec without data
{ {
solaxX1_nodata_count++; solaxX1_nodata_count++;
} }
else if (solaxX1_nodata_count != 255) else if (solaxX1_nodata_count != 255)
@ -467,12 +460,12 @@ void solaxX1_Update(void) // Every Second
void solaxX1Init(void) void solaxX1Init(void)
{ {
AddLog_P(LOG_LEVEL_DEBUG, PSTR("Solax X1 Inverter Init")); AddLog_P(LOG_LEVEL_DEBUG, PSTR("Solax X1 Inverter Init"));
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "RX pin: %d, TX pin: %d"), pin[GPIO_SOLAXX1_RX], pin[GPIO_SOLAXX1_TX]); DEBUG_DRIVER_LOG(PSTR("SX1: RX pin: %d, TX pin: %d"), pin[GPIO_SOLAXX1_RX], pin[GPIO_SOLAXX1_TX]);
solaxX1_Init = 0; solaxX1_Init = 0;
if ((pin[GPIO_SOLAXX1_RX] < 99) && (pin[GPIO_SOLAXX1_TX] < 99)) if ((pin[GPIO_SOLAXX1_RX] < 99) && (pin[GPIO_SOLAXX1_TX] < 99))
{ {
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()) if (solaxX1Serial->hardwareSerial())
{ {
@ -484,103 +477,108 @@ void solaxX1Init(void)
} }
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
const char HTTP_SNS_solaxX1_DATA[] PROGMEM = const char HTTP_SNS_solaxX1_DATA1[] PROGMEM =
"{s}solaxX1 " D_VOLTAGE "{m}%s " D_UNIT_VOLT "{e}" "{s}" D_SOLAX_X1 " " D_VOLTAGE "{m}%s " D_UNIT_VOLT "{e}"
"{s}solaxX1 " D_CURRENT "{m}%s " D_UNIT_AMPERE "{e}" "{s}" D_SOLAX_X1 " " D_CURRENT "{m}%s " D_UNIT_AMPERE "{e}"
"{s}solaxX1 " D_FREQUENCY "{m}%s " D_UNIT_HERTZ "{e}" "{s}" D_SOLAX_X1 " " D_FREQUENCY "{m}%s " D_UNIT_HERTZ "{e}"
"{s}solaxX1 " D_INVERTER_POWER "{m}%s " D_UNIT_WATT "{e}" "{s}" D_SOLAX_X1 " " D_INVERTER_POWER "{m}%s " D_UNIT_WATT "{e}"
"{s}solaxX1 " D_SOLAR_POWER "{m}%s " D_UNIT_WATT "{e}" "{s}" D_SOLAX_X1 " " D_SOLAR_POWER "{m}%s " D_UNIT_WATT "{e}"
"{s}solaxX1 " D_ENERGY_TOTAL "{m}%s " D_UNIT_KILOWATTHOUR "{e}" "{s}" D_SOLAX_X1 " " D_ENERGY_TOTAL "{m}%s " D_UNIT_KILOWATTHOUR "{e}"
"{s}solaxX1 " D_ENERGY_TODAY "{m}%s " D_UNIT_KILOWATTHOUR "{e}" "{s}" D_SOLAX_X1 " " D_ENERGY_TODAY "{m}%s " D_UNIT_KILOWATTHOUR "{e}"
"{s}solaxX1 " D_PV1_VOLTAGE "{m}%s " D_UNIT_VOLT "{e}" "{s}" D_SOLAX_X1 " " D_PV1_VOLTAGE "{m}%s " D_UNIT_VOLT "{e}"
"{s}solaxX1 " D_PV1_CURRENT "{m}%s " D_UNIT_AMPERE "{e}" "{s}" D_SOLAX_X1 " " D_PV1_CURRENT "{m}%s " D_UNIT_AMPERE "{e}"
"{s}solaxX1 " D_PV1_POWER "{m}%s " D_UNIT_WATT "{e}" "{s}" D_SOLAX_X1 " " D_PV1_POWER "{m}%s " D_UNIT_WATT "{e}";
#ifdef PV2 #ifdef SOLAXX1_PV2
"{s}solaxX1 " D_PV2_VOLTAGE "{m}%s " D_UNIT_VOLT "{e}" const char HTTP_SNS_solaxX1_DATA2[] PROGMEM =
"{s}solaxX1 " D_PV2_CURRENT "{m}%s " D_UNIT_AMPERE "{e}" "{s}" D_SOLAX_X1 " " D_PV2_VOLTAGE "{m}%s " D_UNIT_VOLT "{e}"
"{s}solaxX1 " D_PV2_POWER "{m}%s " D_UNIT_WATT "{e}" "{s}" D_SOLAX_X1 " " D_PV2_CURRENT "{m}%s " D_UNIT_AMPERE "{e}"
"{s}" D_SOLAX_X1 " " D_PV2_POWER "{m}%s " D_UNIT_WATT "{e}";
#endif #endif
"{s}solaxX1 " D_TEMPERATURE "{m}%s " D_UNIT_TEMPERATURE "{e}" const char HTTP_SNS_solaxX1_DATA3[] PROGMEM =
"{s}solaxX1 " D_WORKTIME "{m}%s " D_UNIT_HOUR "{e}" "{s}" D_SOLAX_X1 " " D_UPTIME "{m}%s " D_UNIT_HOUR "{e}"
"{s}solaxX1 " D_STATUS "{m}%s" "{s}" D_SOLAX_X1 " " D_STATUS "{m}%s"
"{s}solaxX1 " D_ERROR "{m}%s"; "{s}" D_SOLAX_X1 " " D_ERROR "{m}%s";
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
void solaxX1Show(bool json) void solaxX1Show(bool json)
{ {
char voltage[33]; char voltage[33];
dtostrfd(solaxX1_ac_voltage, 2, voltage); dtostrfd(solaxX1_ac_voltage, Settings.flag2.voltage_resolution, voltage);
char current[33]; char current[33];
dtostrfd(solaxX1_ac_current, 3, current); dtostrfd(solaxX1_ac_current, Settings.flag2.current_resolution, current);
char inverter_power[33]; char inverter_power[33];
dtostrfd(solaxX1_power, 2, inverter_power); dtostrfd(solaxX1_power, Settings.flag2.wattage_resolution, inverter_power);
char solar_power[33]; char solar_power[33];
dtostrfd(solaxX1_dc1_power + dtostrfd(solaxX1_dc1_power + solaxX1_dc2_power, Settings.flag2.wattage_resolution, solar_power);
solaxX1_dc2_power, 2, solar_power);
char frequency[33]; char frequency[33];
dtostrfd(solaxX1_frequency, 2, frequency); dtostrfd(solaxX1_frequency, Settings.flag2.frequency_resolution, frequency);
char energy_total[33]; char energy_total[33];
dtostrfd(solaxX1_energy_total, 1, energy_total); dtostrfd(solaxX1_energy_total, Settings.flag2.energy_resolution, energy_total);
char energy_today[33]; char energy_today[33];
dtostrfd(solaxX1_energy_today, 1, energy_today); dtostrfd(solaxX1_energy_today, Settings.flag2.energy_resolution, energy_today);
char pv1_voltage[33]; char pv1_voltage[33];
dtostrfd(solaxX1_dc1_voltage, 2, pv1_voltage); dtostrfd(solaxX1_dc1_voltage, Settings.flag2.voltage_resolution, pv1_voltage);
char pv1_current[33]; char pv1_current[33];
dtostrfd(solaxX1_dc1_current, 3, pv1_current); dtostrfd(solaxX1_dc1_current, Settings.flag2.current_resolution, pv1_current);
char pv1_power[33]; char pv1_power[33];
dtostrfd(solaxX1_dc1_power, 2, pv1_power); dtostrfd(solaxX1_dc1_power, Settings.flag2.wattage_resolution, pv1_power);
#ifdef PV2 #ifdef SOLAXX1_PV2
char pv2_voltage[33]; char pv2_voltage[33];
dtostrfd(solaxX1_dc2_voltage, 2, pv2_voltage); dtostrfd(solaxX1_dc2_voltage, Settings.flag2.voltage_resolution, pv2_voltage);
char pv2_current[33]; char pv2_current[33];
dtostrfd(solaxX1_dc2_current, 3, pv2_current); dtostrfd(solaxX1_dc2_current, Settings.flag2.current_resolution, pv2_current);
char pv2_power[33]; char pv2_power[33];
dtostrfd(solaxX1_dc2_power, 2, pv2_power); dtostrfd(solaxX1_dc2_power, Settings.flag2.wattage_resolution, pv2_power);
#endif #endif
char temperature[33]; char temperature[33];
dtostrfd(solaxX1_temperature, 1, temperature); dtostrfd(solaxX1_temperature, Settings.flag2.temperature_resolution, temperature);
char runtime[33]; char runtime[33];
dtostrfd(solaxX1_runtime_total, 0, runtime); dtostrfd(solaxX1_runtime_total, 0, runtime);
char status[33]; char status[33];
strcpy_P(status, (PGM_P)solaxX1_Mode[solaxX1_status]); GetTextIndexed(status, sizeof(status), solaxX1_status, kSolaxMode);
char errorCode[33];
char errorCodeString[33];
dtostrfd(solaxX1_errorCode, 0, errorCode);
strcpy_P(errorCodeString, (PGM_P)solaxX1_ErrCode[solaxX1_ParseErrorCode(solaxX1_errorCode)]);
if (json) if (json)
{ {
#ifdef PV2 ResponseAppend_P(PSTR(",\"" D_RSLT_ENERGY "\":{\"" D_JSON_VOLTAGE "\":%s,\"" D_JSON_CURRENT "\":%s,\"" D_JSON_ACTIVE_POWERUSAGE "\":%s,\""
ResponseAppend_P(PSTR(",\"" D_RSLT_ENERGY "\":{\"" D_JSON_VOLTAGE "\":%s,\"" D_JSON_CURRENT "\":%s,\"" D_JSON_ACTIVE_POWERUSAGE "\":%s,\"" D_JSON_SOLAR_POWER "\":%s,\"" D_JSON_FREQUENCY "\":%s,\"" D_JSON_TOTAL "\":%s,\"" D_JSON_TODAY "\":%s,\"" D_JSON_PV1_VOLTAGE "\":%s,\"" D_JSON_PV1_CURRENT "\":%s,\"" D_JSON_PV1_POWER "\":%s,\"" D_JSON_PV2_VOLTAGE "\":%s,\"" D_JSON_PV2_CURRENT "\":%s,\"" D_JSON_PV2_POWER "\":%s,\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_RUNTIME "\":%s,\"" D_JSON_STATUS "\":\"%s\",\"" D_JSON_ERROR "\":%s}"), D_JSON_SOLAR_POWER "\":%s,\"" D_JSON_FREQUENCY "\":%s,\"" D_JSON_TOTAL "\":%s,\"" D_JSON_TODAY "\":%s,\""
voltage, current, inverter_power, solar_power, frequency, energy_total, energy_today, pv1_voltage, pv1_current, pv1_power, pv2_voltage, pv2_current, pv2_power, temperature, runtime, status, errorCode); D_JSON_PV1_VOLTAGE "\":%s,\"" D_JSON_PV1_CURRENT "\":%s,\"" D_JSON_PV1_POWER "\":%s"),
#else voltage, current, inverter_power,
ResponseAppend_P(PSTR(",\"" D_RSLT_ENERGY "\":{\"" D_JSON_VOLTAGE "\":%s,\"" D_JSON_CURRENT "\":%s,\"" D_JSON_ACTIVE_POWERUSAGE "\":%s,\"" D_JSON_SOLAR_POWER "\":%s,\"" D_JSON_FREQUENCY "\":%s,\"" D_JSON_TOTAL "\":%s,\"" D_JSON_TODAY "\":%s,\"" D_JSON_PV1_VOLTAGE "\":%s,\"" D_JSON_PV1_CURRENT "\":%s,\"" D_JSON_PV1_POWER "\":%s,\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_RUNTIME "\":%s,\"" D_JSON_STATUS "\":\"%s\"}"), solar_power, frequency, energy_total, energy_today,
voltage, current, inverter_power, solar_power, frequency, energy_total, energy_today, pv1_voltage, pv1_current, pv1_power, temperature, runtime, status, errorCode); pv1_voltage, pv1_current, pv1_power);
#ifdef SOLAXX1_PV2
ResponseAppend_P(PSTR(",\"" D_JSON_PV2_VOLTAGE "\":%s,\"" D_JSON_PV2_CURRENT "\":%s,\"" D_JSON_PV2_POWER "\":%s"),
pv2_voltage, pv2_current, pv2_power);
#endif #endif
ResponseAppend_P(PSTR(",\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_RUNTIME "\":%s,\"" D_JSON_STATUS "\":\"%s\",\"" D_JSON_ERROR "\":%d}"),
temperature, runtime, status, solaxX1_errorCode);
#ifdef USE_DOMOTICZ #ifdef USE_DOMOTICZ
if (0 == tele_period) if (0 == tele_period)
{ {
char energy_total_chr[33]; char energy_total_chr[33];
dtostrfd(solaxX1_energy_total * 1000, 1, energy_total_chr); dtostrfd(solaxX1_energy_total * 1000, 1, energy_total_chr);
DomoticzSensor(DZ_VOLTAGE, voltage); DomoticzSensor(DZ_VOLTAGE, voltage);
DomoticzSensor(DZ_CURRENT, current); DomoticzSensor(DZ_CURRENT, current);
// Only do the updates if the values are greater than 0, to avoid wrong data representation in domoticz // Only do the updates if the values are greater than 0, to avoid wrong data representation in domoticz
if (solaxX1_temperature > 0) DomoticzSensor(DZ_TEMP, temperature); if (solaxX1_temperature > 0) DomoticzSensor(DZ_TEMP, temperature);
if (solaxX1_energy_total > 0) DomoticzSensorPowerEnergy((int)solaxX1_power, energy_total_chr); if (solaxX1_energy_total > 0) DomoticzSensorPowerEnergy((int)solaxX1_power, energy_total_chr);
} }
#endif // USE_DOMOTICZ #endif // USE_DOMOTICZ
#ifdef USE_WEBSERVER #ifdef USE_WEBSERVER
} }
else else
{ {
#ifdef PV2 WSContentSend_PD(HTTP_SNS_solaxX1_DATA1, voltage, current, frequency, inverter_power, solar_power, energy_total, energy_today, pv1_voltage, pv1_current, pv1_power);
WSContentSend_PD(HTTP_SNS_solaxX1_DATA, voltage, current, frequency, inverter_power, solar_power, energy_total, energy_today, pv1_voltage, pv1_current, pv1_power, pv2_voltage, pv2_current, pv2_power, temperature, runtime, status, errorCodeString); #ifdef SOLAXX1_PV2
#else WSContentSend_PD(HTTP_SNS_solaxX1_DATA2, pv2_voltage, pv2_current, pv2_power);
WSContentSend_PD(HTTP_SNS_solaxX1_DATA, voltage, current, frequency, inverter_power, solar_power, energy_total, energy_today, pv1_voltage, pv1_current, pv1_power, temperature, runtime, status, errorCodeString);
#endif #endif
#endif // USE_WEBSERVER WSContentSend_PD(HTTP_SNS_TEMP, D_SOLAX_X1, temperature, TempUnit());
char errorCodeString[33];
WSContentSend_PD(HTTP_SNS_solaxX1_DATA3, runtime, status,
GetTextIndexed(errorCodeString, sizeof(errorCodeString), solaxX1_ParseErrorCode(solaxX1_errorCode), kSolaxError));
#endif // USE_WEBSERVER
} }
} }
@ -609,10 +607,10 @@ bool Xsns49(uint8_t function)
case FUNC_WEB_SENSOR: case FUNC_WEB_SENSOR:
solaxX1Show(0); solaxX1Show(0);
break; break;
#endif // USE_WEBSERVER #endif // USE_WEBSERVER
} }
} }
return result; return result;
} }
#endif // USE_solaxX1 #endif // USE_SOLAX_X1