Skip to content

Commit

Permalink
Merge branch 'pr/MalteSchm/144' into development
Browse files Browse the repository at this point in the history
  • Loading branch information
helgeerbe committed Mar 27, 2023
2 parents e0a8073 + 2aad13d commit b3c17c8
Show file tree
Hide file tree
Showing 33 changed files with 1,555 additions and 6 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ This project is still under development and adds following features:
* Can read the current solar panel power from the Victron MPPT and adjust the limiter accordingly to not save energy in the battery (for increased system efficiency). Increases the battery lifespan and reduces energy loses.
* Settings can be configured in the UI
* Pylontech Battery support (via CAN bus interface). Use the SOC for starting/stopping the power output and provide the battery data via MQTT (autodiscovery for home assistant is currently not supported). Pin Mapping is supported (default RX PIN 27, TX PIN 26). Actual no live view support for Pylontech Battery.
* Huawei R4850G2 power supply unit that can act as AC charger. Supports status shown on the web interface and options to set voltage and current limits on the web interface and via MQTT. Connection is done using CAN bus (needs to be separate from Pylontech CAN bus) via SN65HVD230 interface.

[![OpenDTU Build](https://github.com/tbnobody/OpenDTU/actions/workflows/build.yml/badge.svg)](https://github.com/tbnobody/OpenDTU/actions/workflows/build.yml)
[![cpplint](https://github.com/tbnobody/OpenDTU/actions/workflows/cpplint.yml/badge.svg)](https://github.com/tbnobody/OpenDTU/actions/workflows/cpplint.yml)
Expand Down Expand Up @@ -166,6 +167,23 @@ Topics for 3 phases of a power meter is configurable. Given is an example for th
| battery/charging/dischargeEnabled | R | | |
| battery/charging/chargeImmediately | R | | |

## Huawei AC charger topics
| Topic | R / W | Description | Value / Unit |
| --------------------------------------- | ----- | ---------------------------------------------------- | -------------------------- |
| huawei/cmd/limit_online_voltage | W | Online voltage (i.e. CAN bus connected) | Volt (V) |
| huawei/cmd/limit_online_current | W | Online current (i.e. CAN bus connected) | Ampere (A) |
| huawei/cmd/power | W | Controls output pin GPIO to drive solid state relais | 0 / 1 |
| huawei/data_age | R | How old the data is | Seconds |
| huawei/input_voltage | R | Input voltage | Volt (V) |
| huawei/input_current | R | Input current | Ampere (A) |
| huawei/input_power | R | Input power | Watt (W) |
| huawei/output_voltage | R | Output voltage | Volt (V) |
| huawei/output_current | R | Output current | Ampere (A) |
| huawei/max_output_current | R | Maximum output current (set using the online limit) | Ampere (A) |
| huawei/output_power | R | Output power | Watt (W) |
| huawei/input_temp | R | Input air temperature | °C |
| huawei/output_temp | R | Output air temperature | °C |
| huawei/efficiency | R | Efficiency | Percentage |

## Currently supported Inverters
* Hoymiles HM-300
Expand Down
1 change: 1 addition & 0 deletions include/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ struct CONFIG_T {
float PowerLimiter_VoltageLoadCorrectionFactor;

bool Battery_Enabled;
bool Huawei_Enabled;

char Security_Password[WIFI_MAX_PASSWORD_STRLEN + 1];
bool Security_AllowReadonly;
Expand Down
95 changes: 95 additions & 0 deletions include/Huawei_can.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once

#include <cstdint>
#include "SPI.h"
#include <mcp_can.h>

#ifndef HUAWEI_PIN_MISO
#define HUAWEI_PIN_MISO 12
#endif

#ifndef HUAWEI_PIN_MOSI
#define HUAWEI_PIN_MOSI 13
#endif

#ifndef HUAWEI_PIN_SCLK
#define HUAWEI_PIN_SCLK 26
#endif

#ifndef HUAWEI_PIN_IRQ
#define HUAWEI_PIN_IRQ 25
#endif

#ifndef HUAWEI_PIN_CS
#define HUAWEI_PIN_CS 15
#endif

#ifndef HUAWEI_PIN_POWER
#define HUAWEI_PIN_POWER 33
#endif

#define HUAWEI_MINIMAL_OFFLINE_VOLTAGE 48
#define HUAWEI_MINIMAL_ONLINE_VOLTAGE 42

#define MAX_CURRENT_MULTIPLIER 20

#define HUAWEI_OFFLINE_VOLTAGE 0x01
#define HUAWEI_ONLINE_VOLTAGE 0x00
#define HUAWEI_OFFLINE_CURRENT 0x04
#define HUAWEI_ONLINE_CURRENT 0x03

#define R48xx_DATA_INPUT_POWER 0x70
#define R48xx_DATA_INPUT_FREQ 0x71
#define R48xx_DATA_INPUT_CURRENT 0x72
#define R48xx_DATA_OUTPUT_POWER 0x73
#define R48xx_DATA_EFFICIENCY 0x74
#define R48xx_DATA_OUTPUT_VOLTAGE 0x75
#define R48xx_DATA_OUTPUT_CURRENT_MAX 0x76
#define R48xx_DATA_INPUT_VOLTAGE 0x78
#define R48xx_DATA_OUTPUT_TEMPERATURE 0x7F
#define R48xx_DATA_INPUT_TEMPERATURE 0x80
#define R48xx_DATA_OUTPUT_CURRENT 0x81
#define R48xx_DATA_OUTPUT_CURRENT1 0x82

struct RectifierParameters_t {
float input_voltage;
float input_frequency;
float input_current;
float input_power;
float input_temp;
float efficiency;
float output_voltage;
float output_current;
float max_output_current;
float output_power;
float output_temp;
float amp_hour;
};

class HuaweiCanClass {
public:
void init(uint8_t huawei_miso, uint8_t huawei_mosi, uint8_t huawei_clk, uint8_t huawei_irq, uint8_t huawei_cs, uint8_t huawei_power);
void loop();
void setValue(float in, uint8_t parameterType);
void setPower(bool power);

RectifierParameters_t * get();
unsigned long getLastUpdate();

private:
void sendRequest();
void onReceive(uint8_t* frame, uint8_t len);

unsigned long previousMillis;
unsigned long lastUpdate;
RectifierParameters_t _rp;

SPIClass *spi;
MCP_CAN *CAN;
uint8_t _huawei_irq;
uint8_t _huawei_power;

};

extern HuaweiCanClass HuaweiCan;
21 changes: 21 additions & 0 deletions include/MqttHandleHuawei.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once

#include "Configuration.h"
#include <Huawei_can.h>
#include <espMqttClient.h>

class MqttHandleHuaweiClass {
public:
void init();
void loop();

private:
void onMqttMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total);

uint32_t _lastPublishStats;
uint32_t _lastPublish;

};

extern MqttHandleHuaweiClass MqttHandleHuawei;
9 changes: 8 additions & 1 deletion include/PinMapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ struct PinMapping_t {
uint8_t victron_rx;
uint8_t battery_rx;
uint8_t battery_tx;
uint8_t huawei_miso;
uint8_t huawei_mosi;
uint8_t huawei_clk;
uint8_t huawei_irq;
uint8_t huawei_cs;
uint8_t huawei_power;
};

class PinMappingClass {
Expand All @@ -45,7 +51,8 @@ class PinMappingClass {
bool isValidEthConfig();
bool isValidVictronConfig();
bool isValidBatteryConfig();

bool isValidHuaweiConfig();

private:
PinMapping_t _pinMapping;
};
Expand Down
5 changes: 5 additions & 0 deletions include/WebApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include "WebApi_ws_live.h"
#include "WebApi_ws_vedirect_live.h"
#include "WebApi_vedirect.h"
#include "WebApi_ws_Huawei.h"
#include "WebApi_Huawei.h"
#include <ESPAsyncWebServer.h>

class WebApiClass {
Expand Down Expand Up @@ -66,6 +68,9 @@ class WebApiClass {
WebApiWsLiveClass _webApiWsLive;
WebApiWsVedirectLiveClass _webApiWsVedirectLive;
WebApiVedirectClass _webApiVedirect;
WebApiHuaweiClass _webApiHuaweiClass;
WebApiWsHuaweiLiveClass _webApiWsHuaweiLive;

};

extern WebApiClass WebApi;
19 changes: 19 additions & 0 deletions include/WebApi_Huawei.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once

#include <ESPAsyncWebServer.h>
#include <AsyncJson.h>

class WebApiHuaweiClass {
public:
void init(AsyncWebServer* server);
void loop();
void getJsonData(JsonObject& root);
private:
void onStatus(AsyncWebServerRequest* request);
void onAdminGet(AsyncWebServerRequest* request);
void onAdminPost(AsyncWebServerRequest* request);
void onPost(AsyncWebServerRequest* request);

AsyncWebServer* _server;
};
24 changes: 24 additions & 0 deletions include/WebApi_ws_Huawei.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once

#include "ArduinoJson.h"
#include <ESPAsyncWebServer.h>
//#include <HuaweiFrameHandler.h>

class WebApiWsHuaweiLiveClass {
public:
WebApiWsHuaweiLiveClass();
void init(AsyncWebServer* server);
void loop();

private:
void generateJsonResponse(JsonVariant& root);
void onLivedataStatus(AsyncWebServerRequest* request);
void onWebsocketEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len);

AsyncWebServer* _server;
AsyncWebSocket _ws;

uint32_t _lastWsCleanup = 0;
uint32_t _lastUpdateCheck = 0;
};
2 changes: 2 additions & 0 deletions include/defaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,5 @@
#define POWERLIMITER_VOLTAGE_LOAD_CORRECTION_FACTOR 0.001

#define BATTERY_ENABLED false

#define HUAWEI_ENABLED false
13 changes: 13 additions & 0 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ lib_deps =
nrf24/RF24 @ ^1.4.5
olikraus/U8g2 @ ^2.34.16
buelowp/sunset @ ^1.1.7
https://github.com/coryjfowler/MCP_CAN_lib

extra_scripts =
pre:auto_firmware_version.py
Expand Down Expand Up @@ -60,6 +61,12 @@ build_flags = ${env.build_flags}
-DVICTRON_PIN_RX=22
-DPYLONTECH_PIN_RX=27
-DPYLONTECH_PIN_TX=14
-DHUAWEI_PIN_MISO=12
-DHUAWEI_PIN_MOSI=13
-DHUAWEI_PIN_SCLK=26
-DHUAWEI_PIN_IRQ=25
-DHUAWEI_PIN_CS=15
-DHUAWEI_PIN_POWER=33


[env:olimex_esp32_poe]
Expand Down Expand Up @@ -102,6 +109,12 @@ build_flags =
-DVICTRON_PIN_RX=22
-DPYLONTECH_PIN_RX=27
-DPYLONTECH_PIN_TX=14
-DHUAWEI_PIN_MISO=12
-DHUAWEI_PIN_MOSI=13
-DHUAWEI_PIN_SCLK=26
-DHUAWEI_PIN_IRQ=25
-DHUAWEI_PIN_CS=15
-DHUAWEI_PIN_POWER=33

[env:wt32_eth01]
; http://www.wireless-tag.com/portfolio/wt32-eth01/
Expand Down
5 changes: 5 additions & 0 deletions platformio_override.ini
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,10 @@
; -DHOYMILES_PIN_CS=6
; -DVICTRON_PIN_TX=21
; -DVICTRON_PIN_RX=22
; -DHUAWEI_PIN_MISO=12
; -DHUAWEI_PIN_MOSI=13
; -DHUAWEI_PIN_SCLK=26
; -DHUAWEI_PIN_IRQ=25
; -DHUAWEI_PIN_CS=15
;monitor_port = /dev/ttyACM0
;upload_port = /dev/ttyACM0
6 changes: 6 additions & 0 deletions src/Configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ bool ConfigurationClass::write()
JsonObject battery = doc.createNestedObject("battery");
battery["enabled"] = config.Battery_Enabled;

JsonObject huawei = doc.createNestedObject("huawei");
huawei["enabled"] = config.Huawei_Enabled;

// Serialize JSON to file
if (serializeJson(doc, f) == 0) {
MessageOutput.println("Failed to write file");
Expand Down Expand Up @@ -320,6 +323,9 @@ bool ConfigurationClass::read()
JsonObject battery = doc["battery"];
config.Battery_Enabled = battery["enabled"] | BATTERY_ENABLED;

JsonObject huawei = doc["huawei"];
config.Huawei_Enabled = huawei["enabled"] | HUAWEI_ENABLED;

f.close();
return true;
}
Expand Down
Loading

0 comments on commit b3c17c8

Please sign in to comment.