mirror of
https://github.com/lumapu/ahoy.git
synced 2025-04-29 18:26:21 +02:00
Merge branch 'lumapu:development03' into development03
This commit is contained in:
commit
92e5f2693f
6 changed files with 97 additions and 7 deletions
|
@ -1,10 +1,15 @@
|
||||||
# Development Changes
|
# Development Changes
|
||||||
|
|
||||||
|
## 0.8.124 - 2024-06-06
|
||||||
|
* improved MqTT `OnMessage` (threadsafe)
|
||||||
|
* support of HERF inverters, serial number is converted in Javascript #1425
|
||||||
|
* revert buffer size in `RestAPI` for ESP8266 #1650
|
||||||
|
|
||||||
## 0.8.123 - 2024-05-30
|
## 0.8.123 - 2024-05-30
|
||||||
* fix ESP8266, ESP32 static IP #1643 #1608
|
* fix ESP8266, ESP32 static IP #1643 #1608
|
||||||
* update MqTT library which enhances stability #1646
|
* update MqTT library which enhances stability #1646
|
||||||
* merge PR: MQTT JSON Payload pro Kanal und total, auswählbar #1541
|
* merge PR: MqTT JSON Payload pro Kanal und total, auswählbar #1541
|
||||||
* add option to publish mqtt as json
|
* add option to publish MqTT as json
|
||||||
* publish rssi not on ch0 any more, published on `topic/rssi`
|
* publish rssi not on ch0 any more, published on `topic/rssi`
|
||||||
* add total power to index page (if multiple inverters are configured)
|
* add total power to index page (if multiple inverters are configured)
|
||||||
* show device name in html title #1639
|
* show device name in html title #1639
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 8
|
#define VERSION_MINOR 8
|
||||||
#define VERSION_PATCH 123
|
#define VERSION_PATCH 124
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t ch;
|
uint8_t ch;
|
||||||
|
|
|
@ -50,7 +50,7 @@ class MaxPower {
|
||||||
if((mValues[i].first + mMaxDiff) >= *mTs)
|
if((mValues[i].first + mMaxDiff) >= *mTs)
|
||||||
val += mValues[i].second;
|
val += mValues[i].second;
|
||||||
else if(mValues[i].first > 0)
|
else if(mValues[i].first > 0)
|
||||||
return mLast; // old data
|
break; // old data
|
||||||
}
|
}
|
||||||
if(val > mLast)
|
if(val > mLast)
|
||||||
mLast = val;
|
mLast = val;
|
||||||
|
|
|
@ -39,6 +39,9 @@ template<class HMSYSTEM>
|
||||||
class PubMqtt {
|
class PubMqtt {
|
||||||
public:
|
public:
|
||||||
PubMqtt() : SendIvData() {
|
PubMqtt() : SendIvData() {
|
||||||
|
mutex = xSemaphoreCreateBinaryStatic(&mutexBuffer);
|
||||||
|
xSemaphoreGive(mutex);
|
||||||
|
|
||||||
mLastIvState.fill(InverterStatus::OFF);
|
mLastIvState.fill(InverterStatus::OFF);
|
||||||
mIvLastRTRpub.fill(0);
|
mIvLastRTRpub.fill(0);
|
||||||
|
|
||||||
|
@ -50,7 +53,9 @@ class PubMqtt {
|
||||||
mSendAlarm.fill(false);
|
mSendAlarm.fill(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
~PubMqtt() { }
|
~PubMqtt() {
|
||||||
|
vSemaphoreDelete(mutex);
|
||||||
|
}
|
||||||
|
|
||||||
void setup(IApp *app, cfgMqtt_t *cfg_mqtt, const char *devName, const char *version, HMSYSTEM *sys, uint32_t *utcTs, uint32_t *uptime) {
|
void setup(IApp *app, cfgMqtt_t *cfg_mqtt, const char *devName, const char *version, HMSYSTEM *sys, uint32_t *utcTs, uint32_t *uptime) {
|
||||||
mApp = app;
|
mApp = app;
|
||||||
|
@ -96,6 +101,17 @@ class PubMqtt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
std::queue<message_s> queue;
|
||||||
|
xSemaphoreTake(mutex, portMAX_DELAY);
|
||||||
|
std::swap(queue, mReceiveQueue);
|
||||||
|
xSemaphoreGive(mutex);
|
||||||
|
|
||||||
|
while (!queue.empty()) {
|
||||||
|
message_s *entry = &queue.front();
|
||||||
|
handleMessage(entry->topic, entry->payload, entry->len, entry->index, entry->total);
|
||||||
|
queue.pop();
|
||||||
|
}
|
||||||
|
|
||||||
SendIvData.loop();
|
SendIvData.loop();
|
||||||
|
|
||||||
#if defined(ESP8266)
|
#if defined(ESP8266)
|
||||||
|
@ -301,6 +317,14 @@ class PubMqtt {
|
||||||
void onMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total) {
|
void onMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total) {
|
||||||
if(len == 0)
|
if(len == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
xSemaphoreTake(mutex, portMAX_DELAY);
|
||||||
|
mReceiveQueue.push(message_s(topic, payload, len, index, total));
|
||||||
|
xSemaphoreGive(mutex);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void handleMessage(const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total) {
|
||||||
DPRINT(DBG_INFO, mqttStr[MQTT_STR_GOT_TOPIC]);
|
DPRINT(DBG_INFO, mqttStr[MQTT_STR_GOT_TOPIC]);
|
||||||
DBGPRINTLN(String(topic));
|
DBGPRINTLN(String(topic));
|
||||||
if(NULL == mSubscriptionCb)
|
if(NULL == mSubscriptionCb)
|
||||||
|
@ -613,6 +637,30 @@ class PubMqtt {
|
||||||
private:
|
private:
|
||||||
enum {MQTT_STATUS_OFFLINE = 0, MQTT_STATUS_PARTIAL, MQTT_STATUS_ONLINE};
|
enum {MQTT_STATUS_OFFLINE = 0, MQTT_STATUS_PARTIAL, MQTT_STATUS_ONLINE};
|
||||||
|
|
||||||
|
struct message_s {
|
||||||
|
char* topic;
|
||||||
|
uint8_t* payload;
|
||||||
|
size_t len;
|
||||||
|
size_t index;
|
||||||
|
size_t total;
|
||||||
|
|
||||||
|
message_s(const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total) {
|
||||||
|
this->topic = new char[strlen(topic) + 1];
|
||||||
|
this->payload = new uint8_t[len];
|
||||||
|
|
||||||
|
memcpy(this->topic, topic, strlen(topic));
|
||||||
|
memcpy(this->payload, payload, len);
|
||||||
|
this->len = len;
|
||||||
|
this->index = index;
|
||||||
|
this->total = total;
|
||||||
|
}
|
||||||
|
|
||||||
|
~message_s() {
|
||||||
|
delete[] this->topic;
|
||||||
|
delete[] this->payload;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
espMqttClient mClient;
|
espMqttClient mClient;
|
||||||
cfgMqtt_t *mCfgMqtt = nullptr;
|
cfgMqtt_t *mCfgMqtt = nullptr;
|
||||||
|
@ -620,6 +668,8 @@ class PubMqtt {
|
||||||
#if defined(ESP8266)
|
#if defined(ESP8266)
|
||||||
WiFiEventHandler mHWifiCon, mHWifiDiscon;
|
WiFiEventHandler mHWifiCon, mHWifiDiscon;
|
||||||
#endif
|
#endif
|
||||||
|
SemaphoreHandle_t mutex;
|
||||||
|
StaticSemaphore_t mutexBuffer;
|
||||||
|
|
||||||
HMSYSTEM *mSys = nullptr;
|
HMSYSTEM *mSys = nullptr;
|
||||||
PubMqttIvData<HMSYSTEM> SendIvData;
|
PubMqttIvData<HMSYSTEM> SendIvData;
|
||||||
|
@ -634,6 +684,8 @@ class PubMqtt {
|
||||||
std::array<uint32_t, MAX_NUM_INVERTERS> mIvLastRTRpub;
|
std::array<uint32_t, MAX_NUM_INVERTERS> mIvLastRTRpub;
|
||||||
uint16_t mIntervalTimeout = 0;
|
uint16_t mIntervalTimeout = 0;
|
||||||
|
|
||||||
|
std::queue<message_s> mReceiveQueue;
|
||||||
|
|
||||||
// last will topic and payload must be available through lifetime of 'espMqttClient'
|
// last will topic and payload must be available through lifetime of 'espMqttClient'
|
||||||
std::array<char, (MQTT_TOPIC_LEN + 5)> mLwtTopic;
|
std::array<char, (MQTT_TOPIC_LEN + 5)> mLwtTopic;
|
||||||
const char *mDevName = nullptr, *mVersion = nullptr;
|
const char *mDevName = nullptr, *mVersion = nullptr;
|
||||||
|
|
|
@ -83,7 +83,11 @@ class RestApi {
|
||||||
mHeapFrag = ESP.getHeapFragmentation();
|
mHeapFrag = ESP.getHeapFragmentation();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(ESP32)
|
||||||
AsyncJsonResponse* response = new AsyncJsonResponse(false, 8000);
|
AsyncJsonResponse* response = new AsyncJsonResponse(false, 8000);
|
||||||
|
#else
|
||||||
|
AsyncJsonResponse* response = new AsyncJsonResponse(false, 6000);
|
||||||
|
#endif
|
||||||
JsonObject root = response->getRoot();
|
JsonObject root = response->getRoot();
|
||||||
|
|
||||||
String path = request->url().substring(5);
|
String path = request->url().substring(5);
|
||||||
|
|
|
@ -880,11 +880,16 @@
|
||||||
ser.dispatchEvent(new Event('change'));
|
ser.dispatchEvent(new Event('change'));
|
||||||
|
|
||||||
function ivSave() {
|
function ivSave() {
|
||||||
var o = new Object();
|
var o = {}
|
||||||
o.cmd = "save_iv"
|
o.cmd = "save_iv"
|
||||||
o.token = "*"
|
o.token = "*"
|
||||||
o.id = obj.id
|
o.id = obj.id
|
||||||
o.ser = parseInt(document.getElementsByName("ser")[0].value, 16);
|
|
||||||
|
let sn = document.getElementsByName("ser")[0].value
|
||||||
|
if(sn[0] == 'A')
|
||||||
|
sn = convHerf(sn)
|
||||||
|
o.ser = parseInt(sn, 16)
|
||||||
|
|
||||||
o.name = document.getElementsByName("name")[0].value;
|
o.name = document.getElementsByName("name")[0].value;
|
||||||
o.en = document.getElementsByName("enable")[0].checked;
|
o.en = document.getElementsByName("enable")[0].checked;
|
||||||
o.ch = [];
|
o.ch = [];
|
||||||
|
@ -904,6 +909,30 @@
|
||||||
getAjax("/api/setup", cb, "POST", JSON.stringify(o));
|
getAjax("/api/setup", cb, "POST", JSON.stringify(o));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function convHerf(sn) {
|
||||||
|
let sn_int = 0n;
|
||||||
|
const CHARS = "0123456789ABCDEFGHJKLMNPRSTUVWXY";
|
||||||
|
|
||||||
|
for (let i = 0; i < 9; ++i) {
|
||||||
|
const pos = CHARS.indexOf(sn[i])
|
||||||
|
const shift = 42 - 5 * i - (i <= 2 ? 0 : 2)
|
||||||
|
sn_int |= BigInt(pos) << BigInt(shift)
|
||||||
|
}
|
||||||
|
|
||||||
|
let first4Hex = (sn_int >> 32n) & 0xFFFFn
|
||||||
|
|
||||||
|
if (first4Hex === 0x2841n)
|
||||||
|
first4Hex = 0x1121n
|
||||||
|
else if (first4Hex === 0x2821n)
|
||||||
|
first4Hex = 0x1141n
|
||||||
|
else if (first4Hex === 0x2801n)
|
||||||
|
first4Hex = 0x1161n
|
||||||
|
|
||||||
|
sn_int = (sn_int & ~(0xFFFFn << 32n)) | (first4Hex << 32n);
|
||||||
|
|
||||||
|
return sn_int.toString(16)
|
||||||
|
}
|
||||||
|
|
||||||
function cb(obj2) {
|
function cb(obj2) {
|
||||||
var e = document.getElementById("res");
|
var e = document.getElementById("res");
|
||||||
if(!obj2.success)
|
if(!obj2.success)
|
||||||
|
|
Loading…
Add table
Reference in a new issue