mirror of https://github.com/lumapu/ahoy.git
Browse Source
* converted struct inverter_t to class Inverter * started with calculation functions (idea from Hubi/mikrocontroller.net)pull/21/head
lumapu
3 years ago
15 changed files with 214 additions and 290 deletions
@ -1,112 +0,0 @@ |
|||
#ifndef __HM_INVERTERS_H__ |
|||
#define __HM_INVERTERS_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"}; |
|||
|
|||
|
|||
|
|||
// CH0 is default channel (freq, ac, temp)
|
|||
enum {CH0 = 0, CH1, CH2, CH3, CH4}; |
|||
enum {CMD01 = 0x01, CMD02, CMD03, CMD83 = 0x83, CMD84}; |
|||
|
|||
enum {INV_TYPE_HM600 = 0, INV_TYPE_HM1200}; |
|||
const char* const invTypes[] = {"HM600", "HM1200"}; |
|||
#define NUM_INVERTER_TYPES 2 |
|||
|
|||
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; |
|||
|
|||
|
|||
union serial_u { |
|||
uint64_t u64; |
|||
uint8_t b[8]; |
|||
}; |
|||
|
|||
typedef struct { |
|||
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
|
|||
} inverter_t; |
|||
|
|||
|
|||
/**
|
|||
* indices are built for the buffer starting with cmd-id in first byte |
|||
* (complete payload in buffer) |
|||
* */ |
|||
|
|||
//-------------------------------------
|
|||
// HM600, HM700
|
|||
//-------------------------------------
|
|||
const byteAssign_t hm600assignment[] = { |
|||
{ FLD_UDC, UNIT_V, CH1, CMD01, 14, 2, 10 }, |
|||
{ FLD_IDC, UNIT_A, CH1, CMD01, 16, 2, 100 }, |
|||
{ FLD_PDC, UNIT_W, CH1, CMD01, 18, 2, 10 }, |
|||
{ FLD_UDC, UNIT_V, CH2, CMD01, 20, 2, 10 }, |
|||
{ FLD_IDC, UNIT_A, CH2, CMD01, 22, 2, 100 }, |
|||
{ FLD_PDC, UNIT_W, CH2, CMD01, 24, 2, 10 }, |
|||
{ FLD_YW, UNIT_WH, CH0, CMD02, 12, 2, 1 }, |
|||
{ FLD_YT, UNIT_WH, CH0, CMD02, 14, 4, 1 }, |
|||
{ FLD_YD, UNIT_WH, CH1, CMD02, 18, 2, 1 }, |
|||
{ FLD_YD, UNIT_WH, CH2, CMD02, 20, 2, 1 }, |
|||
{ FLD_UAC, UNIT_V, CH0, CMD02, 22, 2, 10 }, |
|||
{ FLD_F, UNIT_HZ, CH0, CMD02, 24, 2, 100 }, |
|||
{ FLD_IAC, UNIT_A, CH0, CMD02, 26, 2, 10 }, |
|||
{ FLD_T, UNIT_C, CH0, CMD83, 18, 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_INVERTERS_H__*/ |
@ -1,4 +1,4 @@ |
|||
#ifndef __SETUP_H__ |
|||
#define __SETUP_H__ |
|||
const char setup_html[] PROGMEM = "<!doctype html><html><head><title>Setup - {DEVICE}</title><link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"/><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"></head><body><h1>Setup</h1><div id=\"setup\" class=\"content\"><div id=\"content\"><p>Enter the credentials to your prefered WiFi station. After rebooting the device tries to connect with this information. </p><form method=\"post\" action=\"/save\"><p class=\"des\">WiFi</p><label for=\"ssid\">SSID</label><input type=\"text\" class=\"text\" name=\"ssid\" value=\"{SSID}\"/><label for=\"pwd\">Password</label><input type=\"password\" class=\"text\" name=\"pwd\" value=\"{PWD}\"/><p class=\"des\">Device Host Name</p><label for=\"device\">Device Name</label><input type=\"text\" class=\"text\" name=\"device\" value=\"{DEVICE}\"/><p class=\"des\">Inverter</p>{INVERTERS}<br/><p class=\"subdes\">General</p><label for=\"invInterval\">Interval (ms)</label><input type=\"text\" class=\"text\" name=\"invInterval\" value=\"{INV_INTERVAL}\"/><p class=\"des\">Pinout (Wemos)</p>{PINOUT}<p class=\"des\">MQTT</p><label for=\"mqttAddr\">Broker / Server IP</label><input type=\"text\" class=\"text\" name=\"mqttAddr\" value=\"{MQTT_ADDR}\"/><label for=\"mqttUser\">Username (optional)</label><input type=\"text\" class=\"text\" name=\"mqttUser\" value=\"{MQTT_USER}\"/><label for=\"mqttPwd\">Password (optional)</label><input type=\"text\" class=\"text\" name=\"mqttPwd\" value=\"{MQTT_PWD}\"/><label for=\"mqttTopic\">Topic</label><input type=\"text\" class=\"text\" name=\"mqttTopic\" value=\"{MQTT_TOPIC}\"/><label for=\"mqttInterval\">Interval (seconds)</label><input type=\"text\" class=\"text\" name=\"mqttInterval\" value=\"{MQTT_INTERVAL}\"/><p class=\"des\"> </p><input type=\"checkbox\" class=\"cb\" name=\"reboot\"/><label for=\"reboot\">Reboot device after successful save</label><input type=\"submit\" value=\"save\" class=\"btn\" /></form></div></div><div id=\"footer\"><p class=\"left\"><a href=\"/\">Home</a></p><p class=\"left\"><a href=\"/update\">Update Firmware</a></p><p class=\"right\">AHOY - {VERSION}</p></div></body></html>"; |
|||
const char setup_html[] PROGMEM = "<!doctype html><html><head><title>Setup - {DEVICE}</title><link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"/><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"></head><body><h1>Setup</h1><div id=\"setup\" class=\"content\"><div id=\"content\"><p>Enter the credentials to your prefered WiFi station. After rebooting the device tries to connect with this information. </p><form method=\"post\" action=\"/save\"><p class=\"des\">WiFi</p><label for=\"ssid\">SSID</label><input type=\"text\" class=\"text\" name=\"ssid\" value=\"{SSID}\"/><label for=\"pwd\">Password</label><input type=\"password\" class=\"text\" name=\"pwd\" value=\"{PWD}\"/><p class=\"des\">Device Host Name</p><label for=\"device\">Device Name</label><input type=\"text\" class=\"text\" name=\"device\" value=\"{DEVICE}\"/><a class=\"erase\" href=\"/erase\">ERASE SETTINGS (not WiFi)</a><p class=\"des\">Inverter</p>{INVERTERS}<br/><p class=\"subdes\">General</p><label for=\"invInterval\">Interval (ms)</label><input type=\"text\" class=\"text\" name=\"invInterval\" value=\"{INV_INTERVAL}\"/><p class=\"des\">Pinout (Wemos)</p>{PINOUT}<p class=\"des\">Radio (NRF24L01+)</p><label for=\"rf24Power\">Amplifier Power Level</label><select name=\"rf24Power\">{RF24}</select><p class=\"des\">MQTT</p><label for=\"mqttAddr\">Broker / Server IP</label><input type=\"text\" class=\"text\" name=\"mqttAddr\" value=\"{MQTT_ADDR}\"/><label for=\"mqttPort\">Port</label><input type=\"text\" class=\"text\" name=\"mqttPort\" value=\"{MQTT_PORT}\"/><label for=\"mqttUser\">Username (optional)</label><input type=\"text\" class=\"text\" name=\"mqttUser\" value=\"{MQTT_USER}\"/><label for=\"mqttPwd\">Password (optional)</label><input type=\"text\" class=\"text\" name=\"mqttPwd\" value=\"{MQTT_PWD}\"/><label for=\"mqttTopic\">Topic</label><input type=\"text\" class=\"text\" name=\"mqttTopic\" value=\"{MQTT_TOPIC}\"/><label for=\"mqttInterval\">Interval (ms)</label><input type=\"text\" class=\"text\" name=\"mqttInterval\" value=\"{MQTT_INTERVAL}\"/><p class=\"des\"> </p><input type=\"checkbox\" class=\"cb\" name=\"reboot\"/><label for=\"reboot\">Reboot device after successful save</label><input type=\"submit\" value=\"save\" class=\"btn\" /></form></div></div><div id=\"footer\"><p class=\"left\"><a href=\"/\">Home</a></p><p class=\"left\"><a href=\"/update\">Update Firmware</a></p><p class=\"right\">AHOY - {VERSION}</p></div></body></html>"; |
|||
#endif /*__SETUP_H__*/ |
|||
|
@ -1,4 +1,4 @@ |
|||
#ifndef __STYLE_H__ |
|||
#define __STYLE_H__ |
|||
const char style_css[] PROGMEM = "h1 {margin:0;padding:20pt;font-size:22pt;color:#fff;background-color:#006ec0;display:block;text-transform:uppercase;}html, body {font-family:Arial;margin:0;padding:0;}p {text-align:justify;font-size:13pt;}.des {margin-top:35px;font-size:14pt;color:#006ec0;}.subdes {font-size:13pt;color:#006ec0;margin-left:7px;}.fw {width:60px;display:block;float:left;}.color {width:50px;height:50px;border:1px solid #ccc;}.range {width:300px;}a:link, a:visited {text-decoration:none;font-size:13pt;color:#006ec0;}a:hover, a:focus {color:#f00;}#content {padding:15px 15px 60px 15px;}#footer {position:fixed;bottom:0px;height:45px;background-color:#006ec0;width:100%;}#footer p {color:#fff;padding-left:20px;padding-right:20px;font-size:10pt !important;}#footer a {color:#fff;}div.content {background-color:#fff;padding-bottom:65px;overflow:hidden;}input, select {padding:7px;font-size:13pt;}input.text, select {width:70%;box-sizing:border-box;margin-bottom:10px;border:1px solid #ccc;}input.btn {background-color:#006ec0;color:#fff;border:0px;float:right;text-transform:uppercase;}input.cb {margin-bottom:20px;}label {width:20%;display:inline-block;font-size:12pt;padding-right:10px;margin-left:10px;}.left {float:left;}.right {float:right;}div.ch {width:250px;height:410px;background-color:#006ec0;display:inline-block;margin-right:20px;margin-bottom:20px;}div.ch .value, div.ch .info, div.ch .head {color:#fff;display:block;width:100%;text-align:center;}div.ch .unit {font-size:19px;margin-left:10px;}div.ch .value {margin-top:20px;font-size:30px;}div.ch .info {margin-top:3px;font-size:10px;}div.ch .head {background-color:#003c80;padding:10px 0 10px 0;}"; |
|||
const char style_css[] PROGMEM = "h1 {margin:0;padding:20pt;font-size:22pt;color:#fff;background-color:#006ec0;display:block;text-transform:uppercase;}html, body {font-family:Arial;margin:0;padding:0;}p {text-align:justify;font-size:13pt;}.des {margin-top:35px;font-size:14pt;color:#006ec0;}.subdes {font-size:13pt;color:#006ec0;margin-left:7px;}.fw {width:60px;display:block;float:left;}.color {width:50px;height:50px;border:1px solid #ccc;}.range {width:300px;}a:link, a:visited {text-decoration:none;font-size:13pt;color:#006ec0;}a:hover, a:focus {color:#f00;}a.erase {background-color:#006ec0;color:#fff;padding:7px;display:inline-block;margin-top:30px;float:right;}#content {padding:15px 15px 60px 15px;}#footer {position:fixed;bottom:0px;height:45px;background-color:#006ec0;width:100%;}#footer p {color:#fff;padding-left:20px;padding-right:20px;font-size:10pt !important;}#footer a {color:#fff;}div.content {background-color:#fff;padding-bottom:65px;overflow:hidden;}input, select {padding:7px;font-size:13pt;}input.text, select {width:70%;box-sizing:border-box;margin-bottom:10px;border:1px solid #ccc;}input.btn {background-color:#006ec0;color:#fff;border:0px;float:right;margin:10px 0 30px;text-transform:uppercase;}input.cb {margin-bottom:20px;}label {width:20%;display:inline-block;font-size:12pt;padding-right:10px;margin-left:10px;}.left {float:left;}.right {float:right;}div.ch {width:250px;height:410px;background-color:#006ec0;display:inline-block;margin-right:20px;margin-bottom:20px;}div.ch .value, div.ch .info, div.ch .head {color:#fff;display:block;width:100%;text-align:center;}div.ch .unit {font-size:19px;margin-left:10px;}div.ch .value {margin-top:20px;font-size:30px;}div.ch .info {margin-top:3px;font-size:10px;}div.ch .head {background-color:#003c80;padding:10px 0 10px 0;}"; |
|||
#endif /*__STYLE_H__*/ |
|||
|
Loading…
Reference in new issue