mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-25 19:56:30 +00:00
Merge pull request #10653 from pablozg/development
Solax X1 Bug fixes and code refactor
This commit is contained in:
commit
1785d93cc1
@ -93,8 +93,6 @@ const char kSolaxError[] PROGMEM =
|
|||||||
|
|
||||||
TasmotaSerial *solaxX1Serial;
|
TasmotaSerial *solaxX1Serial;
|
||||||
|
|
||||||
uint8_t solaxX1_Init = 1;
|
|
||||||
|
|
||||||
struct SOLAXX1 {
|
struct SOLAXX1 {
|
||||||
float temperature = 0;
|
float temperature = 0;
|
||||||
float energy_today = 0;
|
float energy_today = 0;
|
||||||
@ -102,8 +100,8 @@ struct SOLAXX1 {
|
|||||||
float dc2_voltage = 0;
|
float dc2_voltage = 0;
|
||||||
float dc1_current = 0;
|
float dc1_current = 0;
|
||||||
float dc2_current = 0;
|
float dc2_current = 0;
|
||||||
float energy_total = 0;
|
uint32_t energy_total = 0;
|
||||||
float runtime_total = 0;
|
uint32_t runtime_total = 0;
|
||||||
float dc1_power = 0;
|
float dc1_power = 0;
|
||||||
float dc2_power = 0;
|
float dc2_power = 0;
|
||||||
|
|
||||||
@ -241,17 +239,17 @@ uint8_t solaxX1_ParseErrorCode(uint32_t code){
|
|||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
|
|
||||||
uint8_t solaxX1_send_retry = 0;
|
uint8_t solaxX1_send_retry = 20;
|
||||||
uint8_t solaxX1_nodata_count = 0;
|
uint8_t solaxX1_queryData_count = 0;
|
||||||
|
|
||||||
void solaxX1250MSecond(void) // Every Second
|
void solaxX1250MSecond(void) // Every 250 milliseconds
|
||||||
{
|
{
|
||||||
uint8_t value[61] = {0};
|
uint8_t value[61] = {0};
|
||||||
bool data_ready = solaxX1_RS485ReceiveReady();
|
bool data_ready = solaxX1_RS485ReceiveReady();
|
||||||
|
|
||||||
if (protocolStatus.hasAddress && (data_ready || solaxX1_send_retry == 0))
|
|
||||||
{
|
|
||||||
if (data_ready)
|
if (data_ready)
|
||||||
|
{
|
||||||
|
if (protocolStatus.hasAddress)
|
||||||
{
|
{
|
||||||
uint8_t error = solaxX1_RS485Receive(value);
|
uint8_t error = solaxX1_RS485Receive(value);
|
||||||
if (error)
|
if (error)
|
||||||
@ -260,8 +258,7 @@ void solaxX1250MSecond(void) // Every Second
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
solaxX1_nodata_count = 0;
|
solaxX1_send_retry = 20;
|
||||||
solaxX1_send_retry = 12;
|
|
||||||
Energy.data_valid[0] = 0;
|
Energy.data_valid[0] = 0;
|
||||||
|
|
||||||
solaxX1.temperature = (float)((value[9] << 8) | value[10]); // Temperature
|
solaxX1.temperature = (float)((value[9] << 8) | value[10]); // Temperature
|
||||||
@ -275,8 +272,8 @@ void solaxX1250MSecond(void) // Every Second
|
|||||||
Energy.frequency[0] = (float)((value[25] << 8) | value[26]) * 0.01f; // AC Frequency
|
Energy.frequency[0] = (float)((value[25] << 8) | value[26]) * 0.01f; // AC Frequency
|
||||||
Energy.active_power[0] = (float)((value[27] << 8) | value[28]); // AC Power
|
Energy.active_power[0] = (float)((value[27] << 8) | value[28]); // AC Power
|
||||||
//temporal = (float)((value[29] << 8) | value[30]) * 0.1f; // Not Used
|
//temporal = (float)((value[29] << 8) | value[30]) * 0.1f; // Not Used
|
||||||
solaxX1.energy_total = (float)((value[31] << 8) | (value[32] << 8) | (value[33] << 8) | value[34]) * 0.1f; // Energy Total
|
solaxX1.energy_total = ((value[31] << 24) | (value[32] << 16) | (value[33] << 8) | value[34]); // Energy Total
|
||||||
solaxX1.runtime_total = (float)((value[35] << 8) | (value[36] << 8) | (value[37] << 8) | value[38]); // Work Time Total
|
solaxX1.runtime_total = ((value[35] << 24) | (value[36] << 16) | (value[37] << 8) | value[38]); // Work Time Total
|
||||||
solaxX1.status = (uint8_t)((value[39] << 8) | value[40]); // Work mode
|
solaxX1.status = (uint8_t)((value[39] << 8) | value[40]); // Work mode
|
||||||
//temporal = (float)((value[41] << 8) | value[42]); // Grid voltage fault value 0.1V
|
//temporal = (float)((value[41] << 8) | value[42]); // Grid voltage fault value 0.1V
|
||||||
//temporal = (float)((value[43] << 8) | value[44]); // Gird frequency fault value 0.01Hz
|
//temporal = (float)((value[43] << 8) | value[44]); // Gird frequency fault value 0.01Hz
|
||||||
@ -285,53 +282,14 @@ void solaxX1250MSecond(void) // Every Second
|
|||||||
//temporal = (float)((value[49] << 8) | value[50]); // Pv1 voltage fault value 0.1V
|
//temporal = (float)((value[49] << 8) | value[50]); // Pv1 voltage fault value 0.1V
|
||||||
//temporal = (float)((value[51] << 8) | value[52]); // Pv2 voltage fault value 0.1V
|
//temporal = (float)((value[51] << 8) | value[52]); // Pv2 voltage fault value 0.1V
|
||||||
//temporal = (float)((value[53] << 8) | value[54]); // GFC fault value
|
//temporal = (float)((value[53] << 8) | value[54]); // GFC fault value
|
||||||
solaxX1.errorCode = (uint32_t)((value[58] << 8) | (value[57] << 8) | (value[56] << 8) | value[55]); // Error Code
|
solaxX1.errorCode = ((value[58] << 24) | (value[57] << 16) | (value[56] << 8) | value[55]); // Error Code
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
solaxX1_QueryLiveData();
|
EnergyUpdateTotal((float)solaxX1.energy_total * 0.1f, true); // 484.708 kWh
|
||||||
EnergyUpdateTotal(solaxX1.energy_total, true); // 484.708 kWh
|
|
||||||
}
|
}
|
||||||
} // End data Ready
|
} else { // end hasAddress
|
||||||
|
|
||||||
if (0 == solaxX1_send_retry && 255 != solaxX1_nodata_count) {
|
|
||||||
solaxX1_send_retry = 12;
|
|
||||||
solaxX1_QueryLiveData();
|
|
||||||
}
|
|
||||||
|
|
||||||
// While the inverter has not stable ambient light, will send an address adquired but go offline again,
|
|
||||||
// so no data will be received when the query is send, then we start the countdown to set the inverter as offline again.
|
|
||||||
if (255 == solaxX1_nodata_count) {
|
|
||||||
solaxX1_nodata_count = 0;
|
|
||||||
solaxX1_send_retry = 12;
|
|
||||||
}
|
|
||||||
} // end hasAddress && (data_ready || solaxX1_send_retry == 0)
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((solaxX1_nodata_count % 4) == 0) { DEBUG_SENSOR_LOG(PSTR("SX1: No Data count: %d"), solaxX1_nodata_count); }
|
|
||||||
if (solaxX1_nodata_count < 10 * 4) // max. seconds without data
|
|
||||||
{
|
|
||||||
solaxX1_nodata_count++;
|
|
||||||
}
|
|
||||||
else if (255 != solaxX1_nodata_count)
|
|
||||||
{
|
|
||||||
// no data from RS485, reset values to 0 and set inverter as offline
|
|
||||||
solaxX1_nodata_count = 255;
|
|
||||||
solaxX1_send_retry = 12;
|
|
||||||
protocolStatus.status = 0b00001000; // queryOffline
|
|
||||||
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.dc2_power = solaxX1.status = Energy.current[0] = Energy.voltage[0] = Energy.frequency[0] = Energy.active_power[0] = 0;
|
|
||||||
//solaxX1.energy_today = solaxX1.energy_total = solaxX1.runtime_total = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!protocolStatus.hasAddress && (data_ready || solaxX1_send_retry == 0))
|
|
||||||
{
|
|
||||||
if (data_ready)
|
|
||||||
{
|
|
||||||
// check address confirmation from inverter
|
// check address confirmation from inverter
|
||||||
if (protocolStatus.inverterAddressSend)
|
if (protocolStatus.inverterAddressSend)
|
||||||
{
|
{
|
||||||
@ -373,16 +331,16 @@ void solaxX1250MSecond(void) // Every Second
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // End data ready
|
|
||||||
|
|
||||||
if (solaxX1_send_retry == 0)
|
|
||||||
{
|
|
||||||
if (protocolStatus.queryOfflineSend)
|
|
||||||
{
|
|
||||||
protocolStatus.status = 0b00001000; // queryOffline
|
|
||||||
DEBUG_SENSOR_LOG(PSTR("SX1: Set Query Offline"));
|
|
||||||
}
|
}
|
||||||
solaxX1_send_retry = 12;
|
}
|
||||||
|
|
||||||
|
if (protocolStatus.hasAddress) {
|
||||||
|
if (solaxX1_queryData_count <= 0) {
|
||||||
|
solaxX1_queryData_count = 5;
|
||||||
|
DEBUG_SENSOR_LOG(PSTR("SX1: Send Retry count: %d"), solaxX1_send_retry);
|
||||||
|
solaxX1_QueryLiveData();
|
||||||
|
}
|
||||||
|
solaxX1_queryData_count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// request to the inverter the serial number if offline
|
// request to the inverter the serial number if offline
|
||||||
@ -396,12 +354,28 @@ void solaxX1250MSecond(void) // Every Second
|
|||||||
dataLength[0] = 0x00;
|
dataLength[0] = 0x00;
|
||||||
solaxX1_RS485Send(9);
|
solaxX1_RS485Send(9);
|
||||||
protocolStatus.status = 0b00010000; // queryOfflineSend
|
protocolStatus.status = 0b00010000; // queryOfflineSend
|
||||||
|
solaxX1_send_retry = 20;
|
||||||
DEBUG_SENSOR_LOG(PSTR("SX1: Query Offline Send"));
|
DEBUG_SENSOR_LOG(PSTR("SX1: Query Offline Send"));
|
||||||
}
|
}
|
||||||
} // end !hasAddress && (data_ready || solaxX1_send_retry == 0)
|
|
||||||
|
|
||||||
if (!data_ready)
|
if (solaxX1_send_retry == 0) {
|
||||||
solaxX1_send_retry--;
|
if (protocolStatus.hasAddress) {
|
||||||
|
protocolStatus.status = 0b00001000; // queryOffline
|
||||||
|
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.dc2_power = solaxX1.status = Energy.current[0] = Energy.voltage[0] = Energy.frequency[0] = Energy.active_power[0] = 0;
|
||||||
|
//solaxX1.energy_today = solaxX1.energy_total = solaxX1.runtime_total = 0;
|
||||||
|
} else {
|
||||||
|
if (protocolStatus.queryOfflineSend) {
|
||||||
|
protocolStatus.status = 0b00001000; // queryOffline
|
||||||
|
DEBUG_SENSOR_LOG(PSTR("SX1: Set Query Offline"));
|
||||||
|
}
|
||||||
|
solaxX1_send_retry = 20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data_ready && solaxX1_send_retry > 0) { solaxX1_send_retry--; }
|
||||||
}
|
}
|
||||||
|
|
||||||
void solaxX1SnsInit(void)
|
void solaxX1SnsInit(void)
|
||||||
@ -479,10 +453,13 @@ void solaxX1Show(bool json)
|
|||||||
ResponseAppend_P(PSTR(",\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_RUNTIME "\":%s,\"" D_JSON_STATUS "\":\"%s\",\"" D_JSON_ERROR "\":%d"),
|
ResponseAppend_P(PSTR(",\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_RUNTIME "\":%s,\"" D_JSON_STATUS "\":\"%s\",\"" D_JSON_ERROR "\":%d"),
|
||||||
temperature, runtime, status, solaxX1.errorCode);
|
temperature, runtime, status, solaxX1.errorCode);
|
||||||
|
|
||||||
|
#ifdef USE_DOMOTICZ
|
||||||
|
// Avoid bad temperature report at beginning of the day (spikes of 1200 celsius degrees)
|
||||||
|
if (0 == TasmotaGlobal.tele_period && solaxX1.temperature < 100) { DomoticzSensor(DZ_TEMP, temperature); }
|
||||||
|
#endif // USE_DOMOTICZ
|
||||||
|
|
||||||
#ifdef USE_WEBSERVER
|
#ifdef USE_WEBSERVER
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
WSContentSend_PD(HTTP_SNS_solaxX1_DATA1, solar_power, pv1_voltage, pv1_current, pv1_power);
|
WSContentSend_PD(HTTP_SNS_solaxX1_DATA1, solar_power, pv1_voltage, pv1_current, pv1_power);
|
||||||
#ifdef SOLAXX1_PV2
|
#ifdef SOLAXX1_PV2
|
||||||
WSContentSend_PD(HTTP_SNS_solaxX1_DATA2, pv2_voltage, pv2_current, pv2_power);
|
WSContentSend_PD(HTTP_SNS_solaxX1_DATA2, pv2_voltage, pv2_current, pv2_power);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user