Skip to content

Commit

Permalink
Feature: Publish Huawei AC charger mode via MQTT (#876)
Browse files Browse the repository at this point in the history
  • Loading branch information
eu-gh authored May 2, 2024
1 parent 744df41 commit 686b5df
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 34 deletions.
11 changes: 6 additions & 5 deletions include/Huawei_can.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,14 @@ class HuaweiCanCommClass {
SPIClass *SPI;
MCP_CAN *_CAN;
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;

uint32_t _recValues[12];
uint16_t _txValues[5];
bool _hasNewTxValue[5];

uint8_t _errorCode;
bool _completeUpdateReceived;
};
Expand All @@ -125,8 +125,9 @@ class HuaweiCanClass {
void setMode(uint8_t mode);

RectifierParameters_t * get();
uint32_t getLastUpdate();
bool getAutoPowerStatus();
uint32_t getLastUpdate() const { return _lastUpdateReceivedMillis; };
bool getAutoPowerStatus() const { return _autoPowerEnabled; };
uint8_t getMode() const { return _mode; };

private:
void loop();
Expand Down Expand Up @@ -154,4 +155,4 @@ class HuaweiCanClass {
};

extern HuaweiCanClass HuaweiCan;
extern HuaweiCanCommClass HuaweiCanComm;
extern HuaweiCanCommClass HuaweiCanComm;
50 changes: 22 additions & 28 deletions src/Huawei_can.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ bool HuaweiCanCommClass::init(uint8_t huawei_miso, uint8_t huawei_mosi, uint8_t

// Public methods need to obtain semaphore

void HuaweiCanCommClass::loop()
{
void HuaweiCanCommClass::loop()
{
std::lock_guard<std::mutex> lock(_mutex);

INT32U rxId;
unsigned char len = 0;
unsigned char rxBuf[8];
Expand Down Expand Up @@ -122,7 +122,7 @@ void HuaweiCanCommClass::loop()
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)};

// Send extended message
// Send extended message
byte sndStat = _CAN->sendMsgBuf(0x108180FE, 1, 8, data);
if (sndStat == CAN_OK) {
_hasNewTxValue[i] = false;
Expand All @@ -137,10 +137,10 @@ void HuaweiCanCommClass::loop()
_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);
uint32_t v = 0;
if (parameter < HUAWEI_OUTPUT_CURRENT1_IDX) {
Expand All @@ -149,8 +149,8 @@ uint32_t HuaweiCanCommClass::getParameterValue(uint8_t parameter)
return v;
}

bool HuaweiCanCommClass::gotNewRxDataFrame(bool clear)
{
bool HuaweiCanCommClass::gotNewRxDataFrame(bool clear)
{
std::lock_guard<std::mutex> lock(_mutex);
bool b = false;
b = _completeUpdateReceived;
Expand All @@ -160,8 +160,8 @@ bool HuaweiCanCommClass::gotNewRxDataFrame(bool clear)
return b;
}

uint8_t HuaweiCanCommClass::getErrorCode(bool clear)
{
uint8_t HuaweiCanCommClass::getErrorCode(bool clear)
{
std::lock_guard<std::mutex> lock(_mutex);
uint8_t e = 0;
e = _errorCode;
Expand All @@ -171,7 +171,7 @@ uint8_t HuaweiCanCommClass::getErrorCode(bool clear)
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);
if (parameterType < HUAWEI_OFFLINE_CURRENT) {
Expand All @@ -185,7 +185,7 @@ void HuaweiCanCommClass::setParameterValue(uint16_t in, uint8_t parameterType)
void HuaweiCanCommClass::sendRequest()
{
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);
if(sndStat != CAN_OK) {
_errorCode |= HUAWEI_ERROR_CODE_RX;
Expand Down Expand Up @@ -242,10 +242,6 @@ RectifierParameters_t * HuaweiCanClass::get()
return &_rp;
}

uint32_t HuaweiCanClass::getLastUpdate()
{
return _lastUpdateReceivedMillis;
}

void HuaweiCanClass::processReceivedParameters()
{
Expand Down Expand Up @@ -284,7 +280,7 @@ void HuaweiCanClass::loop()
MessageOutput.println("[HuaweiCanClass::loop] Data request error");
}
if (com_error & HUAWEI_ERROR_CODE_TX) {
MessageOutput.println("[HuaweiCanClass::loop] Data set error");
MessageOutput.println("[HuaweiCanClass::loop] Data set error");
}

// Print updated data
Expand All @@ -298,7 +294,7 @@ void HuaweiCanClass::loop()
if (_rp.output_current > HUAWEI_AUTO_MODE_SHUTDOWN_CURRENT) {
_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)) {
digitalWrite(_huaweiPower, 1);
}
Expand All @@ -321,7 +317,7 @@ void HuaweiCanClass::loop()
_batteryEmergencyCharging = true;

// 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);
MessageOutput.printf("[HuaweiCanClass::loop] Emergency Charge Output current %f \r\n", outputCurrent);
_setValue(outputCurrent, HUAWEI_ONLINE_CURRENT);
Expand All @@ -343,7 +339,7 @@ void HuaweiCanClass::loop()

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
if (_autoModeBlockedTillMillis > millis()) {
return;
Expand All @@ -368,7 +364,7 @@ void HuaweiCanClass::loop()
if (inverter != nullptr) {
if(inverter->isProducing()) {
_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;
MessageOutput.printf("[HuaweiCanClass::loop] Inverter is active, disable\r\n");
return;
Expand All @@ -384,7 +380,7 @@ void HuaweiCanClass::loop()

// Calculate new power limit
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
newPowerLimit += _rp.output_power + config.Huawei.Auto_Power_Target_Power_Consumption / efficiency;
Expand Down Expand Up @@ -449,7 +445,7 @@ void HuaweiCanClass::loop()
_setValue(0.0, HUAWEI_ONLINE_CURRENT);
}
}
}
}
}

void HuaweiCanClass::setValue(float in, uint8_t parameterType)
Expand All @@ -476,7 +472,7 @@ void HuaweiCanClass::_setValue(float in, uint8_t parameterType)
}

// 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)) {
digitalWrite(_huaweiPower, 0);
_outputCurrentOnSinceMillis = millis();
Expand Down Expand Up @@ -524,7 +520,5 @@ void HuaweiCanClass::setMode(uint8_t mode) {
}
}

bool HuaweiCanClass::getAutoPowerStatus() {
return _autoPowerEnabled;
}


3 changes: 2 additions & 1 deletion src/MqttHandleHuawei.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ void MqttHandleHuaweiClass::loop()
MqttSettings.publish("huawei/input_temp", String(rp->input_temp));
MqttSettings.publish("huawei/output_temp", String(rp->output_temp));
MqttSettings.publish("huawei/efficiency", String(rp->efficiency));
MqttSettings.publish("huawei/mode", String(HuaweiCan.getMode()));


yield();
Expand Down Expand Up @@ -158,4 +159,4 @@ void MqttHandleHuaweiClass::onMqttMessage(Topic t,
}
break;
}
}
}

0 comments on commit 686b5df

Please sign in to comment.