mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-15 18:06:39 +02:00
Merge branch 'main' into dev
# Conflicts: # tools/esp8266/app.cpp # tools/esp8266/hmInverters.h # tools/esp8266/hmSystem.h * added missing files
This commit is contained in:
commit
5844795447
11 changed files with 913 additions and 565 deletions
|
@ -5,7 +5,8 @@ Various tools, examples, and documentation for communicating with Hoymiles micro
|
||||||
|
|
||||||
In particular:
|
In particular:
|
||||||
|
|
||||||
* `doc\hoymiles-format-description.txt` is a detailed description of the communications format and the history of this project
|
* `doc/hoymiles-format-description.txt` is a detailed description of the communications format and the history of this project
|
||||||
* The `tools` folder contains various software tools for RaspberryPi and Arduino
|
* `doc/getting-started-ESP8266.md` shows the hardware setup for an ESP8266-based system
|
||||||
|
* The `tools` folder contains various software tools for RaspberryPi, Arduino and ESP8266/ESP32
|
||||||
|
|
||||||
Contributors are always welcome!
|
Contributors are always welcome!
|
||||||
|
|
BIN
doc/AhoyMiles.fzz
Normal file
BIN
doc/AhoyMiles.fzz
Normal file
Binary file not shown.
BIN
doc/AhoyMiles_bb.png
Normal file
BIN
doc/AhoyMiles_bb.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 62 KiB |
BIN
doc/AhoyMiles_schem.png
Normal file
BIN
doc/AhoyMiles_schem.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
BIN
doc/HM-400 data.xlsx
Executable file
BIN
doc/HM-400 data.xlsx
Executable file
Binary file not shown.
45
doc/getting-started-ESP8266.md
Normal file
45
doc/getting-started-ESP8266.md
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
# Getting Started with an ESP8266
|
||||||
|
|
||||||
|
Wire Connections
|
||||||
|
|
||||||
|
```ditaa
|
||||||
|
+-----------+ +-----------+
|
||||||
|
| ESP8266 |--colour--| nRF24L01+ |
|
||||||
|
| | | |
|
||||||
|
| GND |---black--|[GND] |
|
||||||
|
| +3.3V |----red---| VCC |
|
||||||
|
| D4 |---grey---| CE |
|
||||||
|
| D8 |--purple--| CSN |
|
||||||
|
| D5 |---blue---| SCK |
|
||||||
|
| D7 |---green--| MOSI |
|
||||||
|
| D6 |---brown--| MISO |
|
||||||
|
| D3 |--yellow--| IRQ |
|
||||||
|
+-----------+ +-----------+
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Fritzing diagrams & schematics
|
||||||
|
* [AhoyMiles_bb.png](./AhoyMiles_bb.png)
|
||||||
|
* [AhoyMiles_schem.png](./AhoyMiles_schem.png)
|
||||||
|
* [AhoyMiles.fzz](./AhoyMiles.fzz)
|
||||||
|
|
||||||
|
Libraries to be installed in Arduino IDE:
|
||||||
|
* RF24
|
||||||
|
* TimeLib
|
||||||
|
|
||||||
|
Verify & Compile
|
||||||
|
* Connect to WiFi Network `ESP AHOY`
|
||||||
|
* Use password `esp_8266`
|
||||||
|
* Connect to Network settings
|
||||||
|
|
||||||
|
Setup
|
||||||
|
* WiFi
|
||||||
|
* Enter SSID `mynetwork`
|
||||||
|
* Enter Password `mypassword`
|
||||||
|
* Device Host Name
|
||||||
|
* Enter Device Name `esp-ahoy`
|
||||||
|
* General
|
||||||
|
* Hoymiles Address (e.g. 114173123456) `11:41:73:12:34:56`
|
||||||
|
* [x] Reboot device after successful save
|
||||||
|
Save
|
|
@ -418,14 +418,33 @@ Example 72220200 72220200 ? 2022-02-13
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
CMD 0x01: WR --> DTU: "Current DC data" (?) (shown for an HM-700)
|
CMD 0x01: WR --> DTU: "Current DC data" (?) (shown for an HM-700 and HM-400)
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
HM-700 (2-channel):
|
||||||
95 72 22 02 00 72 22 02 00 01 00 01 01 4c 03 bd 0c 46 00 b5 00 03 00 05 00 00 BD 7F
|
95 72 22 02 00 72 22 02 00 01 00 01 01 4c 03 bd 0c 46 00 b5 00 03 00 05 00 00 BD 7F
|
||||||
^^ ^^^^^^^^^^^ ^^^^^^^^^^^ ^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^ ^^
|
^^ ^^^^^^^^^^^ ^^^^^^^^^^^ ^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^ ^^
|
||||||
NameMID WR ser# WR ser# CMD ? PV1.u PV1.i PV1.p PV2.u PV2.i PV2.p ? CRC8 EOF
|
NameMID WR ser# WR ser# CMD ? PV1.u PV1.i PV1.p PV2.u PV2.i PV2.p ? CRC8 EOF
|
||||||
Units BCD (letzte 8) BCD (letzte 8) ? [0.1V] [0.01A] [.1W] [0.1V] [0.01A] [.1W] ?
|
Units BCD (letzte 8) BCD (letzte 8) ? [0.1V] [0.01A] [.1W] [0.1V] [0.01A] [.1W] ?
|
||||||
Example 72220200 72220200 ? 33.2V 9.57A 317.2W 18.1V 0.03A 0.5W ?
|
Example 72220200 72220200 ? 33.2V 9.57A 317.2W 18.1V 0.03A 0.5W ?
|
||||||
|
|
||||||
|
|
||||||
|
HM-400 (1-channel):
|
||||||
|
byte 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
||||||
|
95 73 10 xx yy 73 10 xx yy 01 00 01 01 9A 00 46 01 21 00 00 FA E6 00 84 09 0C F5 DD BD 7F
|
||||||
|
^^ ^^^^^^^^^^^ ^^^^^^^^^^^ ^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^^^^^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^ ^^
|
||||||
|
NameMID WR ser# WR ser# CMD ? PV1.u PV1.i PV1.p DC? P total? DC? P day V AC CRC8 EOF
|
||||||
|
Units BCD (letzte 8) BCD (letzte 8) ? [0.1V] [0.01A] [.1W] [0.001kWh] [1Wh] [0.1V] ?
|
||||||
|
Example 7310xxyy 7310xxyy ? 41.0V 0.70A 28.9W 64.23kWh 132Wh 231.6V ?
|
||||||
|
|
||||||
|
legend
|
||||||
|
PVx.u: DC voltage of panel x
|
||||||
|
PVx.i: DC current of panel x
|
||||||
|
PVx.p: DC power of panel x
|
||||||
|
WR ser#: inverter serial, e.g. 11217310xxyy (HM-400) => 7310xxyy
|
||||||
|
P tot: DC (or AC)? power total (monthly/yearly?)
|
||||||
|
P day: DC (or AC)? power daily
|
||||||
|
V AC: AC voltage
|
||||||
|
|
||||||
```
|
```
|
||||||
- The exact meaning of the contents of this message varies depending on inverter type. So far, the following variants have been observed:
|
- The exact meaning of the contents of this message varies depending on inverter type. So far, the following variants have been observed:
|
||||||
- HM-400 (single channel):
|
- HM-400 (single channel):
|
||||||
|
@ -456,7 +475,25 @@ Einheit BCD (letzte 8) BCD (letzte 8) ?
|
||||||
Beispiel 72220200 72220200 ? 9284 60 231.9V 50.00Hz 302.9W
|
Beispiel 72220200 72220200 ? 9284 60 231.9V 50.00Hz 302.9W
|
||||||
```
|
```
|
||||||
- The exact meaning of the contents of this message varies depending on inverter type. So far, the following variants have been observed:
|
- The exact meaning of the contents of this message varies depending on inverter type. So far, the following variants have been observed:
|
||||||
- ...
|
- until now, message never observed using a HM-400
|
||||||
|
|
||||||
|
```
|
||||||
|
CMD 0x82: WR --> DTU: "???" (?) (shown for an HM-400)
|
||||||
|
----------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
HM-400 (1-channel):
|
||||||
|
byte 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
||||||
|
95 73 10 xx yy 73 10 xx yy 82 13 8A 01 1C 00 00 00 0C 03 E8 00 65 00 06 3C 1D 36 9E 8D 1
|
||||||
|
^^ ^^^^^^^^^^^ ^^^^^^^^^^^ ^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^ ^^
|
||||||
|
NameMID WR ser# WR ser# CMD Freq P AC ? I AC ? Temp ? ? ? CRC8? EOF?
|
||||||
|
Units BCD (letzte 8) BCD (letzte 8) [0.01Hz] [0.1W] ? [0.01A] ? [0.1°C] ? ? ?
|
||||||
|
Example 7310xxyy 7310xxyy 50,02Hz 28,40W ? 0,120A ? 10,10°C ? ? ?
|
||||||
|
|
||||||
|
legend
|
||||||
|
Freq: frequency of inverter
|
||||||
|
P AC: AC power of inverter
|
||||||
|
I AC: AC current of inverter
|
||||||
|
Temp: temperature of inverter
|
||||||
|
WR ser#: inverter serial, e.g. 11217310xxyy (HM-400) => 7310xxyy
|
||||||
|
|
||||||
```
|
```
|
||||||
Nachricht 0x83: WR an DTU (?): "???" (nach CMD wäre das eher auch eine Antwort vom WR?)
|
Nachricht 0x83: WR an DTU (?): "???" (nach CMD wäre das eher auch eine Antwort vom WR?)
|
||||||
|
|
|
@ -482,7 +482,7 @@ void app::saveValues(bool webSend = true) {
|
||||||
// type
|
// type
|
||||||
mWeb->arg("inv" + String(i) + "Type").toCharArray(buf, 20);
|
mWeb->arg("inv" + String(i) + "Type").toCharArray(buf, 20);
|
||||||
uint8_t type = atoi(buf);
|
uint8_t type = atoi(buf);
|
||||||
mEep->write(ADDR_INV_TYPE + (i * MAX_NAME_LENGTH), type);
|
mEep->write(ADDR_INV_TYPE + i, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
interval = mWeb->arg("invInterval").toInt();
|
interval = mWeb->arg("invInterval").toInt();
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 2
|
#define VERSION_MINOR 2
|
||||||
#define VERSION_PATCH 10
|
#define VERSION_PATCH 11
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
@ -39,7 +39,7 @@ typedef struct {
|
||||||
// EEPROM
|
// EEPROM
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
#define SSID_LEN 32
|
#define SSID_LEN 32
|
||||||
#define PWD_LEN 32
|
#define PWD_LEN 63
|
||||||
#define DEVNAME_LEN 16
|
#define DEVNAME_LEN 16
|
||||||
#define CRC_LEN 2 // uint16_t
|
#define CRC_LEN 2 // uint16_t
|
||||||
|
|
||||||
|
|
122
tools/esp8266/hmDefines.h
Normal file
122
tools/esp8266/hmDefines.h
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
#ifndef __HM_DEFINES_H__
|
||||||
|
#define __HM_DEFINES_H__
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
// units
|
||||||
|
enum {UNIT_V = 0, UNIT_A, UNIT_W, UNIT_WH, UNIT_KWH, UNIT_HZ, UNIT_C, UNIT_PCT};
|
||||||
|
const char* const units[] = {"V", "A", "W", "Wh", "kWh", "Hz", "°C", "%"};
|
||||||
|
|
||||||
|
// field types
|
||||||
|
enum {FLD_UDC = 0, FLD_IDC, FLD_PDC, FLD_YD, FLD_YW, FLD_YT,
|
||||||
|
FLD_UAC, FLD_IAC, FLD_PAC, FLD_F, FLD_T, FLD_PCT};
|
||||||
|
const char* const fields[] = {"U_DC", "I_DC", "P_DC", "YieldDay", "YieldWeek", "YieldTotal",
|
||||||
|
"U_AC", "I_AC", "P_AC", "Freq", "Temp", "Pct"};
|
||||||
|
|
||||||
|
|
||||||
|
union serial_u {
|
||||||
|
uint64_t u64;
|
||||||
|
uint8_t b[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// CH0 is default channel (freq, ac, temp)
|
||||||
|
enum {CH0 = 0, CH1, CH2, CH3, CH4};
|
||||||
|
// received command ids, special command CMDFF for calculations
|
||||||
|
enum {CMD01 = 0x01, CMD02, CMD03, CMD82 = 0x82, CMD83, CMD84, CMDFF=0xff};
|
||||||
|
|
||||||
|
enum {INV_TYPE_HM600 = 0, INV_TYPE_HM1200, INV_TYPE_HM400};
|
||||||
|
const char* const invTypes[] = {"HM600", "HM1200 / HM1500", "HM400"};
|
||||||
|
#define NUM_INVERTER_TYPES 3
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t fieldId; // field id
|
||||||
|
uint8_t unitId; // uint id
|
||||||
|
uint8_t ch; // channel 0 - 3
|
||||||
|
uint8_t cmdId; // received command id
|
||||||
|
uint8_t start; // pos of first byte in buffer
|
||||||
|
uint8_t num; // number of bytes in buffer
|
||||||
|
uint16_t div; // divisor
|
||||||
|
} byteAssign_t;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* indices are built for the buffer starting with cmd-id in first byte
|
||||||
|
* (complete payload in buffer)
|
||||||
|
* */
|
||||||
|
|
||||||
|
//-------------------------------------
|
||||||
|
// HM400 HM350?, HM300?
|
||||||
|
//-------------------------------------
|
||||||
|
const byteAssign_t hm400assignment[] = {
|
||||||
|
{ FLD_UDC, UNIT_V, CH1, CMD01, 3, 2, 10 },
|
||||||
|
{ FLD_IDC, UNIT_A, CH1, CMD01, 5, 2, 100 },
|
||||||
|
{ FLD_PDC, UNIT_W, CH1, CMD01, 7, 2, 10 },
|
||||||
|
{ FLD_YT, UNIT_KWH, CH1, CMD01, 9, 4, 1000 },
|
||||||
|
{ FLD_YD, UNIT_WH, CH1, CMD01, 13, 2, 1000 },
|
||||||
|
{ FLD_UAC, UNIT_V, CH0, CMD01, 15, 2, 10 },
|
||||||
|
{ FLD_F, UNIT_HZ, CH0, CMD82, 1, 2, 100 },
|
||||||
|
{ FLD_PAC, UNIT_W, CH0, CMD82, 3, 2, 10 },
|
||||||
|
{ FLD_IAC, UNIT_A, CH0, CMD82, 7, 2, 100 },
|
||||||
|
{ FLD_T, UNIT_C, CH0, CMD82, 11, 2, 10 }
|
||||||
|
};
|
||||||
|
#define HM400_LIST_LEN (sizeof(hm400assignment) / sizeof(byteAssign_t))
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------
|
||||||
|
// HM600, HM700
|
||||||
|
//-------------------------------------
|
||||||
|
const byteAssign_t hm600assignment[] = {
|
||||||
|
{ FLD_UDC, UNIT_V, CH1, CMD01, 3, 2, 10 },
|
||||||
|
{ FLD_IDC, UNIT_A, CH1, CMD01, 5, 2, 100 },
|
||||||
|
{ FLD_PDC, UNIT_W, CH1, CMD01, 7, 2, 10 },
|
||||||
|
{ FLD_UDC, UNIT_V, CH2, CMD01, 9, 2, 10 },
|
||||||
|
{ FLD_IDC, UNIT_A, CH2, CMD01, 11, 2, 100 },
|
||||||
|
{ FLD_PDC, UNIT_W, CH2, CMD01, 13, 2, 10 },
|
||||||
|
{ FLD_YW, UNIT_WH, CH0, CMD02, 1, 2, 1 },
|
||||||
|
{ FLD_YT, UNIT_KWH, CH0, CMD02, 3, 4, 1000 },
|
||||||
|
{ FLD_YD, UNIT_WH, CH1, CMD02, 7, 2, 1 },
|
||||||
|
{ FLD_YD, UNIT_WH, CH2, CMD02, 9, 2, 1 },
|
||||||
|
{ FLD_UAC, UNIT_V, CH0, CMD02, 11, 2, 10 },
|
||||||
|
{ FLD_F, UNIT_HZ, CH0, CMD02, 13, 2, 100 },
|
||||||
|
{ FLD_IAC, UNIT_A, CH0, CMD02, 15, 2, 10 },
|
||||||
|
{ FLD_T, UNIT_C, CH0, CMD83, 7, 2, 10 }
|
||||||
|
};
|
||||||
|
#define HM600_LIST_LEN (sizeof(hm600assignment) / sizeof(byteAssign_t))
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------
|
||||||
|
// HM1200, HM1500
|
||||||
|
//-------------------------------------
|
||||||
|
const byteAssign_t hm1200assignment[] = {
|
||||||
|
{ FLD_UDC, UNIT_V, CH1, CMD01, 3, 2, 10 },
|
||||||
|
{ FLD_IDC, UNIT_A, CH1, CMD01, 5, 2, 100 },
|
||||||
|
{ FLD_PDC, UNIT_W, CH1, CMD01, 9, 2, 10 },
|
||||||
|
{ FLD_YD, UNIT_WH, CH1, CMD02, 5, 2, 1 },
|
||||||
|
{ FLD_YT, UNIT_KWH, CH1, CMD01, 13, 4, 1000 },
|
||||||
|
{ FLD_UDC, UNIT_V, CH2, CMD02, 9, 2, 10 },
|
||||||
|
{ FLD_IDC, UNIT_A, CH2, CMD01, 7, 2, 100 },
|
||||||
|
{ FLD_PDC, UNIT_W, CH2, CMD01, 11, 2, 10 },
|
||||||
|
{ FLD_YD, UNIT_WH, CH2, CMD02, 7, 2, 1 },
|
||||||
|
{ FLD_YT, UNIT_KWH, CH2, CMD02, 1, 4, 1000 },
|
||||||
|
{ FLD_IDC, UNIT_A, CH3, CMD02, 11, 2, 100 },
|
||||||
|
{ FLD_PDC, UNIT_W, CH3, CMD02, 15, 2, 10 },
|
||||||
|
{ FLD_YD, UNIT_WH, CH3, CMD03, 11, 2, 1 },
|
||||||
|
{ FLD_YT, UNIT_KWH, CH3, CMD03, 3, 4, 1000 },
|
||||||
|
{ FLD_IDC, UNIT_A, CH4, CMD02, 13, 2, 100 },
|
||||||
|
{ FLD_PDC, UNIT_W, CH4, CMD03, 1, 2, 10 },
|
||||||
|
{ FLD_YD, UNIT_WH, CH4, CMD03, 13, 2, 1 },
|
||||||
|
{ FLD_YT, UNIT_KWH, CH4, CMD03, 7, 4, 1000 },
|
||||||
|
{ FLD_UAC, UNIT_V, CH0, CMD03, 15, 2, 10 },
|
||||||
|
{ FLD_IAC, UNIT_A, CH0, CMD84, 7, 2, 100 },
|
||||||
|
{ FLD_PAC, UNIT_W, CH0, CMD84, 3, 2, 10 },
|
||||||
|
{ FLD_F, UNIT_HZ, CH0, CMD84, 1, 2, 100 },
|
||||||
|
{ FLD_PCT, UNIT_PCT, CH0, CMD84, 9, 2, 10 },
|
||||||
|
{ FLD_T, UNIT_C, CH0, CMD84, 11, 2, 10 }
|
||||||
|
};
|
||||||
|
#define HM1200_LIST_LEN (sizeof(hm1200assignment) / sizeof(byteAssign_t))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /*__HM_DEFINES_H__*/
|
143
tools/esp8266/hmInverter.h
Normal file
143
tools/esp8266/hmInverter.h
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
#ifndef __HM_INVERTER_H__
|
||||||
|
#define __HM_INVERTER_H__
|
||||||
|
|
||||||
|
#include "hmDefines.h"
|
||||||
|
|
||||||
|
template <class RECORDTYPE=float>
|
||||||
|
class Inverter {
|
||||||
|
public:
|
||||||
|
uint8_t id; // unique id
|
||||||
|
char name[MAX_NAME_LENGTH]; // human readable name, eg. "HM-600.1"
|
||||||
|
uint8_t type; // integer which refers to inverter type
|
||||||
|
byteAssign_t* assign; // type of inverter
|
||||||
|
uint8_t listLen; // length of assignments
|
||||||
|
serial_u serial; // serial number as on barcode
|
||||||
|
serial_u radioId; // id converted to modbus
|
||||||
|
uint8_t channels; // number of PV channels (1-4)
|
||||||
|
RECORDTYPE *record; // pointer for values
|
||||||
|
|
||||||
|
Inverter() {
|
||||||
|
getAssignment();
|
||||||
|
toRadioId();
|
||||||
|
record = new RECORDTYPE[listLen];
|
||||||
|
memset(record, 0, sizeof(RECORDTYPE) * listLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
~Inverter() {
|
||||||
|
// TODO: cleanup
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getPosByChFld(uint8_t channel, uint8_t fieldId) {
|
||||||
|
uint8_t pos = 0;
|
||||||
|
for(; pos < listLen; pos++) {
|
||||||
|
if((assign[pos].ch == channel) && (assign[pos].fieldId == fieldId))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return (pos >= listLen) ? 0xff : pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *getFieldName(uint8_t pos) {
|
||||||
|
return fields[assign[pos].fieldId];
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *getUnit(uint8_t pos) {
|
||||||
|
return units[assign[pos].unitId];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getChannel(uint8_t pos) {
|
||||||
|
return assign[pos].ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t getCmdId(uint8_t pos) {
|
||||||
|
return assign[pos].cmdId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addValue(uint8_t pos, uint8_t buf[]) {
|
||||||
|
uint8_t ptr = assign[pos].start;
|
||||||
|
uint8_t end = ptr + assign[pos].num;
|
||||||
|
uint16_t div = assign[pos].div;
|
||||||
|
|
||||||
|
uint32_t val = 0;
|
||||||
|
do {
|
||||||
|
val <<= 8;
|
||||||
|
val |= buf[ptr];
|
||||||
|
} while(++ptr != end);
|
||||||
|
|
||||||
|
record[pos] = (RECORDTYPE)(val) / (RECORDTYPE)(div);
|
||||||
|
}
|
||||||
|
|
||||||
|
RECORDTYPE getValue(uint8_t pos) {
|
||||||
|
return record[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void toRadioId(void) {
|
||||||
|
radioId.u64 = 0ULL;
|
||||||
|
radioId.b[4] = serial.b[0];
|
||||||
|
radioId.b[3] = serial.b[1];
|
||||||
|
radioId.b[2] = serial.b[2];
|
||||||
|
radioId.b[1] = serial.b[3];
|
||||||
|
radioId.b[0] = 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
void getAssignment(void) {
|
||||||
|
if(INV_TYPE_HM600 == type) {
|
||||||
|
listLen = (uint8_t)(HM600_LIST_LEN);
|
||||||
|
assign = (byteAssign_t*)hm600assignment;
|
||||||
|
channels = 2;
|
||||||
|
}
|
||||||
|
else if(INV_TYPE_HM1200 == type) {
|
||||||
|
listLen = (uint8_t)(HM1200_LIST_LEN);
|
||||||
|
assign = (byteAssign_t*)hm1200assignment;
|
||||||
|
channels = 4;
|
||||||
|
}
|
||||||
|
else if(INV_TYPE_HM400 == type) {
|
||||||
|
listLen = (uint8_t)(HM400_LIST_LEN);
|
||||||
|
assign = (byteAssign_t*)hm400assignment;
|
||||||
|
channels = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
listLen = 0;
|
||||||
|
channels = 0;
|
||||||
|
assign = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To calculate values which are not transmitted by the unit there is a generic
|
||||||
|
* list of functions which can be linked to the assignment.
|
||||||
|
* The special command 0xff (CMDFF) must be used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef float (*func_t)(Inverter<> *);
|
||||||
|
typedef struct {
|
||||||
|
uint8_t funcId; // unique id
|
||||||
|
func_t func; // function pointer
|
||||||
|
} calcFunc_t;
|
||||||
|
|
||||||
|
static float calcYieldTotalCh0(Inverter<> *iv) {
|
||||||
|
if(NULL != iv) {
|
||||||
|
float yield[iv->channels];
|
||||||
|
for(uint8_t i = 1; i <= iv->channels; i++) {
|
||||||
|
uint8_t pos = iv->getPosByChFld(i, FLD_YT);
|
||||||
|
//yield[i-1] = iv->getValue(iv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float calcYieldDayCh0(Inverter<> *iv) {
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum {CALC_YT_CH0 = 0, CALC_YD_CH0};
|
||||||
|
|
||||||
|
const calcFunc_t calcFunctions[] = {
|
||||||
|
{ CALC_YT_CH0, &calcYieldTotalCh0 },
|
||||||
|
{ CALC_YD_CH0, &calcYieldDayCh0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /*__HM_INVERTER_H__*/
|
Loading…
Add table
Add a link
Reference in a new issue