Feature: Publish Huawei AC charger mode via MQTT (#876)

This commit is contained in:
eu-gh 2024-05-02 21:19:25 +02:00 committed by GitHub
parent 744df41b01
commit 686b5df64e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 30 additions and 34 deletions

View File

@ -105,14 +105,14 @@ private:
SPIClass *SPI; SPIClass *SPI;
MCP_CAN *_CAN; MCP_CAN *_CAN;
uint8_t _huaweiIrq; // IRQ pin uint8_t _huaweiIrq; // IRQ pin
uint32_t _nextRequestMillis = 0; // When to send next data request to PSU uint32_t _nextRequestMillis = 0; // When to send next data request to PSU
std::mutex _mutex; std::mutex _mutex;
uint32_t _recValues[12]; uint32_t _recValues[12];
uint16_t _txValues[5]; uint16_t _txValues[5];
bool _hasNewTxValue[5]; bool _hasNewTxValue[5];
uint8_t _errorCode; uint8_t _errorCode;
bool _completeUpdateReceived; bool _completeUpdateReceived;
}; };
@ -125,8 +125,9 @@ public:
void setMode(uint8_t mode); void setMode(uint8_t mode);
RectifierParameters_t * get(); RectifierParameters_t * get();
uint32_t getLastUpdate(); uint32_t getLastUpdate() const { return _lastUpdateReceivedMillis; };
bool getAutoPowerStatus(); bool getAutoPowerStatus() const { return _autoPowerEnabled; };
uint8_t getMode() const { return _mode; };
private: private:
void loop(); void loop();
@ -154,4 +155,4 @@ private:
}; };
extern HuaweiCanClass HuaweiCan; extern HuaweiCanClass HuaweiCan;
extern HuaweiCanCommClass HuaweiCanComm; extern HuaweiCanCommClass HuaweiCanComm;

View File

@ -68,10 +68,10 @@ bool HuaweiCanCommClass::init(uint8_t huawei_miso, uint8_t huawei_mosi, uint8_t
// Public methods need to obtain semaphore // Public methods need to obtain semaphore
void HuaweiCanCommClass::loop() void HuaweiCanCommClass::loop()
{ {
std::lock_guard<std::mutex> lock(_mutex); std::lock_guard<std::mutex> lock(_mutex);
INT32U rxId; INT32U rxId;
unsigned char len = 0; unsigned char len = 0;
unsigned char rxBuf[8]; unsigned char rxBuf[8];
@ -122,7 +122,7 @@ void HuaweiCanCommClass::loop()
if ( _hasNewTxValue[i] == true) { if ( _hasNewTxValue[i] == true) {
uint8_t data[8] = {0x01, i, 0x00, 0x00, 0x00, 0x00, (uint8_t)((_txValues[i] & 0xFF00) >> 8), (uint8_t)(_txValues[i] & 0xFF)}; uint8_t data[8] = {0x01, i, 0x00, 0x00, 0x00, 0x00, (uint8_t)((_txValues[i] & 0xFF00) >> 8), (uint8_t)(_txValues[i] & 0xFF)};
// Send extended message // Send extended message
byte sndStat = _CAN->sendMsgBuf(0x108180FE, 1, 8, data); byte sndStat = _CAN->sendMsgBuf(0x108180FE, 1, 8, data);
if (sndStat == CAN_OK) { if (sndStat == CAN_OK) {
_hasNewTxValue[i] = false; _hasNewTxValue[i] = false;
@ -137,10 +137,10 @@ void HuaweiCanCommClass::loop()
_nextRequestMillis = millis() + HUAWEI_DATA_REQUEST_INTERVAL_MS; _nextRequestMillis = millis() + HUAWEI_DATA_REQUEST_INTERVAL_MS;
} }
} }
uint32_t HuaweiCanCommClass::getParameterValue(uint8_t parameter) uint32_t HuaweiCanCommClass::getParameterValue(uint8_t parameter)
{ {
std::lock_guard<std::mutex> lock(_mutex); std::lock_guard<std::mutex> lock(_mutex);
uint32_t v = 0; uint32_t v = 0;
if (parameter < HUAWEI_OUTPUT_CURRENT1_IDX) { if (parameter < HUAWEI_OUTPUT_CURRENT1_IDX) {
@ -149,8 +149,8 @@ uint32_t HuaweiCanCommClass::getParameterValue(uint8_t parameter)
return v; return v;
} }
bool HuaweiCanCommClass::gotNewRxDataFrame(bool clear) bool HuaweiCanCommClass::gotNewRxDataFrame(bool clear)
{ {
std::lock_guard<std::mutex> lock(_mutex); std::lock_guard<std::mutex> lock(_mutex);
bool b = false; bool b = false;
b = _completeUpdateReceived; b = _completeUpdateReceived;
@ -160,8 +160,8 @@ bool HuaweiCanCommClass::gotNewRxDataFrame(bool clear)
return b; return b;
} }
uint8_t HuaweiCanCommClass::getErrorCode(bool clear) uint8_t HuaweiCanCommClass::getErrorCode(bool clear)
{ {
std::lock_guard<std::mutex> lock(_mutex); std::lock_guard<std::mutex> lock(_mutex);
uint8_t e = 0; uint8_t e = 0;
e = _errorCode; e = _errorCode;
@ -171,7 +171,7 @@ uint8_t HuaweiCanCommClass::getErrorCode(bool clear)
return e; return e;
} }
void HuaweiCanCommClass::setParameterValue(uint16_t in, uint8_t parameterType) void HuaweiCanCommClass::setParameterValue(uint16_t in, uint8_t parameterType)
{ {
std::lock_guard<std::mutex> lock(_mutex); std::lock_guard<std::mutex> lock(_mutex);
if (parameterType < HUAWEI_OFFLINE_CURRENT) { if (parameterType < HUAWEI_OFFLINE_CURRENT) {
@ -185,7 +185,7 @@ void HuaweiCanCommClass::setParameterValue(uint16_t in, uint8_t parameterType)
void HuaweiCanCommClass::sendRequest() void HuaweiCanCommClass::sendRequest()
{ {
uint8_t data[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t data[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
//Send extended message //Send extended message
byte sndStat = _CAN->sendMsgBuf(0x108040FE, 1, 8, data); byte sndStat = _CAN->sendMsgBuf(0x108040FE, 1, 8, data);
if(sndStat != CAN_OK) { if(sndStat != CAN_OK) {
_errorCode |= HUAWEI_ERROR_CODE_RX; _errorCode |= HUAWEI_ERROR_CODE_RX;
@ -242,10 +242,6 @@ RectifierParameters_t * HuaweiCanClass::get()
return &_rp; return &_rp;
} }
uint32_t HuaweiCanClass::getLastUpdate()
{
return _lastUpdateReceivedMillis;
}
void HuaweiCanClass::processReceivedParameters() void HuaweiCanClass::processReceivedParameters()
{ {
@ -284,7 +280,7 @@ void HuaweiCanClass::loop()
MessageOutput.println("[HuaweiCanClass::loop] Data request error"); MessageOutput.println("[HuaweiCanClass::loop] Data request error");
} }
if (com_error & HUAWEI_ERROR_CODE_TX) { if (com_error & HUAWEI_ERROR_CODE_TX) {
MessageOutput.println("[HuaweiCanClass::loop] Data set error"); MessageOutput.println("[HuaweiCanClass::loop] Data set error");
} }
// Print updated data // Print updated data
@ -298,7 +294,7 @@ void HuaweiCanClass::loop()
if (_rp.output_current > HUAWEI_AUTO_MODE_SHUTDOWN_CURRENT) { if (_rp.output_current > HUAWEI_AUTO_MODE_SHUTDOWN_CURRENT) {
_outputCurrentOnSinceMillis = millis(); _outputCurrentOnSinceMillis = millis();
} }
if (_outputCurrentOnSinceMillis + HUAWEI_AUTO_MODE_SHUTDOWN_DELAY < millis() && if (_outputCurrentOnSinceMillis + HUAWEI_AUTO_MODE_SHUTDOWN_DELAY < millis() &&
(_mode == HUAWEI_MODE_AUTO_EXT || _mode == HUAWEI_MODE_AUTO_INT)) { (_mode == HUAWEI_MODE_AUTO_EXT || _mode == HUAWEI_MODE_AUTO_INT)) {
digitalWrite(_huaweiPower, 1); digitalWrite(_huaweiPower, 1);
} }
@ -321,7 +317,7 @@ void HuaweiCanClass::loop()
_batteryEmergencyCharging = true; _batteryEmergencyCharging = true;
// Set output current // Set output current
float efficiency = (_rp.efficiency > 0.5 ? _rp.efficiency : 1.0); float efficiency = (_rp.efficiency > 0.5 ? _rp.efficiency : 1.0);
float outputCurrent = efficiency * (config.Huawei.Auto_Power_Upper_Power_Limit / _rp.output_voltage); float outputCurrent = efficiency * (config.Huawei.Auto_Power_Upper_Power_Limit / _rp.output_voltage);
MessageOutput.printf("[HuaweiCanClass::loop] Emergency Charge Output current %f \r\n", outputCurrent); MessageOutput.printf("[HuaweiCanClass::loop] Emergency Charge Output current %f \r\n", outputCurrent);
_setValue(outputCurrent, HUAWEI_ONLINE_CURRENT); _setValue(outputCurrent, HUAWEI_ONLINE_CURRENT);
@ -343,7 +339,7 @@ void HuaweiCanClass::loop()
if (_mode == HUAWEI_MODE_AUTO_INT ) { if (_mode == HUAWEI_MODE_AUTO_INT ) {
// Check if we should run automatic power calculation at all. // Check if we should run automatic power calculation at all.
// We may have set a value recently and still wait for output stabilization // We may have set a value recently and still wait for output stabilization
if (_autoModeBlockedTillMillis > millis()) { if (_autoModeBlockedTillMillis > millis()) {
return; return;
@ -368,7 +364,7 @@ void HuaweiCanClass::loop()
if (inverter != nullptr) { if (inverter != nullptr) {
if(inverter->isProducing()) { if(inverter->isProducing()) {
_setValue(0.0, HUAWEI_ONLINE_CURRENT); _setValue(0.0, HUAWEI_ONLINE_CURRENT);
// Don't run auto mode for a second now. Otherwise we may send too much over the CAN bus // Don't run auto mode for a second now. Otherwise we may send too much over the CAN bus
_autoModeBlockedTillMillis = millis() + 1000; _autoModeBlockedTillMillis = millis() + 1000;
MessageOutput.printf("[HuaweiCanClass::loop] Inverter is active, disable\r\n"); MessageOutput.printf("[HuaweiCanClass::loop] Inverter is active, disable\r\n");
return; return;
@ -384,7 +380,7 @@ void HuaweiCanClass::loop()
// Calculate new power limit // Calculate new power limit
float newPowerLimit = -1 * round(PowerMeter.getPowerTotal()); float newPowerLimit = -1 * round(PowerMeter.getPowerTotal());
float efficiency = (_rp.efficiency > 0.5 ? _rp.efficiency : 1.0); float efficiency = (_rp.efficiency > 0.5 ? _rp.efficiency : 1.0);
// Powerlimit is the requested output power + permissable Grid consumption factoring in the efficiency factor // Powerlimit is the requested output power + permissable Grid consumption factoring in the efficiency factor
newPowerLimit += _rp.output_power + config.Huawei.Auto_Power_Target_Power_Consumption / efficiency; newPowerLimit += _rp.output_power + config.Huawei.Auto_Power_Target_Power_Consumption / efficiency;
@ -449,7 +445,7 @@ void HuaweiCanClass::loop()
_setValue(0.0, HUAWEI_ONLINE_CURRENT); _setValue(0.0, HUAWEI_ONLINE_CURRENT);
} }
} }
} }
} }
void HuaweiCanClass::setValue(float in, uint8_t parameterType) void HuaweiCanClass::setValue(float in, uint8_t parameterType)
@ -476,7 +472,7 @@ void HuaweiCanClass::_setValue(float in, uint8_t parameterType)
} }
// Start PSU if needed // Start PSU if needed
if (in > HUAWEI_AUTO_MODE_SHUTDOWN_CURRENT && parameterType == HUAWEI_ONLINE_CURRENT && if (in > HUAWEI_AUTO_MODE_SHUTDOWN_CURRENT && parameterType == HUAWEI_ONLINE_CURRENT &&
(_mode == HUAWEI_MODE_AUTO_EXT || _mode == HUAWEI_MODE_AUTO_INT)) { (_mode == HUAWEI_MODE_AUTO_EXT || _mode == HUAWEI_MODE_AUTO_INT)) {
digitalWrite(_huaweiPower, 0); digitalWrite(_huaweiPower, 0);
_outputCurrentOnSinceMillis = millis(); _outputCurrentOnSinceMillis = millis();
@ -524,7 +520,5 @@ void HuaweiCanClass::setMode(uint8_t mode) {
} }
} }
bool HuaweiCanClass::getAutoPowerStatus() {
return _autoPowerEnabled;
}

View File

@ -75,6 +75,7 @@ void MqttHandleHuaweiClass::loop()
MqttSettings.publish("huawei/input_temp", String(rp->input_temp)); MqttSettings.publish("huawei/input_temp", String(rp->input_temp));
MqttSettings.publish("huawei/output_temp", String(rp->output_temp)); MqttSettings.publish("huawei/output_temp", String(rp->output_temp));
MqttSettings.publish("huawei/efficiency", String(rp->efficiency)); MqttSettings.publish("huawei/efficiency", String(rp->efficiency));
MqttSettings.publish("huawei/mode", String(HuaweiCan.getMode()));
yield(); yield();
@ -158,4 +159,4 @@ void MqttHandleHuaweiClass::onMqttMessage(Topic t,
} }
break; break;
} }
} }