Skip to content

Commit 9adde50

Browse files
committed
2 parents aa0a590 + ee6f902 commit 9adde50

File tree

8 files changed

+71
-69
lines changed

8 files changed

+71
-69
lines changed

src/app.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ void app::tickSend(void) {
381381
DPRINTLN(DBG_WARN, F("NRF24 not connected!"));
382382
return;
383383
}
384-
if (mIVCommunicationOn) {
384+
if (mIVCommunicationOn && mTimestamp) {
385385
if (!mSys.Radio.mBufCtrl.empty()) {
386386
if (mConfig->serial.debug) {
387387
DPRINT(DBG_DEBUG, F("recbuf not empty! #"));

src/hm/hmInverter.h

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,13 @@ class Inverter {
127127
record_t<REC_TYP> recordInfo; // structure for info values
128128
record_t<REC_TYP> recordConfig; // structure for system config values
129129
record_t<REC_TYP> recordAlarm; // structure for alarm values
130-
//String lastAlarmMsg;
131130
bool initialized; // needed to check if the inverter was correctly added (ESP32 specific - union types are never null)
132131
bool isConnected; // shows if inverter was successfully identified (fw version and hardware info)
133132
uint32_t pac_sum; // average calc for chart: sum of ac power values for cur interval
134133
uint16_t pac_cnt; // average calc for chart: number of ac power values for cur interval
134+
uint16_t alarmCode; // last Alarm
135+
uint32_t alarmStart;
136+
uint32_t alarmEnd;
135137

136138
Inverter() {
137139
ivGen = IV_HM;
@@ -141,9 +143,9 @@ class Inverter {
141143
mDevControlRequest = false;
142144
devControlCmd = InitDataState;
143145
initialized = false;
144-
//lastAlarmMsg = "nothing";
145146
alarmMesIndex = 0;
146147
isConnected = false;
148+
alarmCode = 0;
147149
}
148150

149151
~Inverter() {
@@ -178,9 +180,11 @@ class Inverter {
178180
uint8_t getQueuedCmd() {
179181
if (_commandQueue.empty()) {
180182
if (ivGen != IV_MI) {
181-
if (getFwVersion() == 0)
183+
if (getFwVersion()) {
184+
enqueCommand<InfoCommand>(RealTimeRunData_Debug); // live data
185+
} else {
182186
enqueCommand<InfoCommand>(InverterDevInform_All); // firmware version
183-
enqueCommand<InfoCommand>(RealTimeRunData_Debug); // live data
187+
}
184188
} else if (ivGen == IV_MI){
185189
if (getFwVersion() == 0)
186190
enqueCommand<InfoCommand>(InverterDevInform_All); // firmware version; might not work, esp. for 1/2 ch hardware
@@ -321,9 +325,6 @@ class Inverter {
321325
}
322326
else if (rec->assign == AlarmDataAssignment) {
323327
DPRINTLN(DBG_DEBUG, "add alarm");
324-
//if (getPosByChFld(0, FLD_LAST_ALARM_CODE, rec) == pos){
325-
// lastAlarmMsg = getAlarmStr(rec->record[pos]);
326-
//}
327328
}
328329
else
329330
DPRINTLN(DBG_WARN, F("add with unknown assginment"));
@@ -489,18 +490,22 @@ class Inverter {
489490
return 0;
490491

491492
uint16_t wCode = ((uint16_t)pyld[startOff]) << 8 | pyld[startOff+1];
492-
uint32_t startTimeOffset = 0, endTimeOffset = 0;
493493

494+
alarmStart = 0;
495+
alarmEnd = 0;
494496
if (((wCode >> 13) & 0x01) == 1) // check if is AM or PM
495-
startTimeOffset = 12 * 60 * 60;
497+
alarmStart = 12 * 60 * 60;
496498
if (((wCode >> 12) & 0x01) == 1) // check if is AM or PM
497-
endTimeOffset = 12 * 60 * 60;
499+
alarmEnd = 12 * 60 * 60;
498500

499-
*start = (((uint16_t)pyld[startOff + 4] << 8) | ((uint16_t)pyld[startOff + 5])) + startTimeOffset;
500-
*endTime = (((uint16_t)pyld[startOff + 6] << 8) | ((uint16_t)pyld[startOff + 7])) + endTimeOffset;
501+
alarmCode = pyld[startOff+1];
502+
alarmStart += (((uint16_t)pyld[startOff + 4] << 8) | ((uint16_t)pyld[startOff + 5]));
503+
alarmEnd += (((uint16_t)pyld[startOff + 6] << 8) | ((uint16_t)pyld[startOff + 7]));
504+
*start = alarmStart;
505+
*endTime = alarmEnd;
501506

502-
DPRINTLN(DBG_INFO, "Alarm #" + String(pyld[startOff+1]) + " '" + String(getAlarmStr(pyld[startOff+1])) + "' start: " + ah::getTimeStr(*start) + ", end: " + ah::getTimeStr(*endTime));
503-
return pyld[startOff+1];
507+
DPRINTLN(DBG_INFO, "Alarm " + String(pyld[startOff+3]) + ", #" + String(alarmCode) + " '" + String(getAlarmStr(alarmCode)) + "' start: " + ah::getTimeStr(alarmStart) + ", end: " + ah::getTimeStr(alarmEnd));
508+
return alarmCode;
504509
}
505510

506511
String getAlarmStr(uint16_t alarmCode) {

src/hm/hmPayload.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ class HmPayload {
100100
iv->setValue(pos, rec, 0.0f);
101101
}
102102
}
103-
103+
iv->alarmCode = 0; // design: every day a new start
104+
rec->ts = 0; // design: every day a new start
104105
notify(RealTimeRunData_Debug);
105106
}
106107

src/hm/hmRadio.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#define ALL_FRAMES 0x80
2222
#define SINGLE_FRAME 0x81
2323

24-
#define SEND_CHANNEL_QUALITY_INTEGRATOR_SIZE 4
2524
#define SEND_CHANNEL_MAX_QUALITY 4
2625
#define SEND_CHANNEL_MIN_QUALITY -6
2726
#define SEND_CHANNEL_QUALITY_GOOD 2
@@ -247,7 +246,12 @@ class HmRadio {
247246
mTxBuf[10] = cmd; // cid
248247
mTxBuf[11] = 0x00;
249248
CP_U32_LittleEndian(&mTxBuf[12], ts);
250-
if (cmd == RealTimeRunData_Debug || cmd == AlarmData ) {
249+
250+
if (cmd == AlarmData) {
251+
// ask for last signalled alarm id only (index is one less)
252+
if (alarmMesId) {
253+
alarmMesId--;
254+
}
251255
mTxBuf[18] = (alarmMesId >> 8) & 0xff;
252256
mTxBuf[19] = (alarmMesId ) & 0xff;
253257
}
@@ -301,7 +305,6 @@ class HmRadio {
301305

302306
void addSendChannelQuality (int8_t quality)
303307
{
304-
// continous averaging
305308
// assume: mTxChIdx is still the last send channel index used
306309
quality = mChQuality[mTxChIdx] + quality;
307310
if (quality < SEND_CHANNEL_MIN_QUALITY) {

src/hm/hmSystem.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ class HmSystem {
181181
day(time_today), month(time_today), year(time_today));
182182
file = LittleFS.open (file_name, "r");
183183
if (!file) {
184-
DPRINT (DBG_WARN, "open_hist, failed to open ");
184+
DPRINT (DBG_VERBOSE, "open_hist, failed to open "); // typical: during night time after midnight
185185
DBGPRINTLN (file_name);
186186
}
187187
} else {
@@ -236,7 +236,7 @@ class HmSystem {
236236
*pac = get_pac_average (false);
237237
return true;
238238
}
239-
DPRINTLN (DBG_INFO, "get_cur_value: none");
239+
DPRINTLN (DBG_VERBOSE, "get_cur_value: none");
240240
return false;
241241
}
242242

src/plugins/SML_OBIS_Parser.cpp

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -629,15 +629,6 @@ bool sml_get_list_entries (uint16_t layer)
629629
// Also: an info_len > 2 could be due to corrupt data. So better break.
630630
uint16 len_info = (*cur_serial_buf & SML_EXT_LENGTH) ? 2 : 1;
631631

632-
#ifdef undef
633-
DPRINT (DBG_INFO, "get_list_entries");
634-
DBGPRINT (", layer " + String (layer));
635-
DBGPRINT (", entries " + String (sml_list_layer_entries[layer]));
636-
DBGPRINT (", type 0x" + String (type, HEX));
637-
DBGPRINT (", len_info " + String (len_info));
638-
DBGPRINTLN (", sml_len " + String (sml_serial_len));
639-
#endif
640-
641632
if (sml_serial_len < len_info) {
642633
if (cur_serial_buf > sml_serial_buf) {
643634
memmove (sml_serial_buf, cur_serial_buf, sml_serial_len);
@@ -745,9 +736,7 @@ bool sml_get_list_entries (uint16_t layer)
745736
layer++;
746737
cur_sml_list_layer = layer;
747738
sml_list_layer_entries[layer] = entry_len;
748-
#ifdef undef
749-
DPRINTLN(DBG_INFO, "Open layer " + String(layer) + ", entries " + String(entry_len));
750-
#endif
739+
DPRINTLN(DBG_VERBOSE, "Open layer " + String(layer) + ", entries " + String(entry_len));
751740
if (!sml_serial_len) {
752741
error = true;
753742
}
@@ -779,9 +768,7 @@ bool sml_get_list_entries (uint16_t layer)
779768
}
780769
}
781770
while (!sml_list_layer_entries[layer]) {
782-
#ifdef undef
783-
DPRINTLN(DBG_INFO, "COMPLETE, layer " + String (layer));
784-
#endif
771+
DPRINTLN(DBG_VERBOSE, "COMPLETE, layer " + String (layer));
785772
if (layer) {
786773
layer--;
787774
cur_sml_list_layer = layer;
@@ -834,9 +821,7 @@ uint16_t sml_parse_stream (uint16 len)
834821
cur_serial_buf = sml_serial_buf;
835822
}
836823
sml_state = SML_ST_FIND_VERSION;
837-
#ifdef undef
838-
DPRINTLN(DBG_INFO, "START_TAG, rest " + String(sml_serial_len));
839-
#endif
824+
DPRINTLN(DBG_VERBOSE, "START_TAG, rest " + String(sml_serial_len));
840825
} else {
841826
cur_serial_buf = last_serial_buf + sml_serial_len;
842827
last_serial_buf = cur_serial_buf;
@@ -861,13 +846,8 @@ uint16_t sml_parse_stream (uint16 len)
861846
sml_telegram_crc = sml_calc_crc (sml_telegram_crc, sizeof (version_seq), cur_serial_buf);
862847
sml_msg_failure = 0;
863848
sml_state = SML_ST_FIND_MSG;
864-
#ifdef undef
865-
DPRINTLN(DBG_INFO, "VERSION, rest " + String (sml_serial_len - sizeof (version_seq)));
866-
#endif
849+
DPRINTLN(DBG_VERBOSE, "VERSION, rest " + String (sml_serial_len - sizeof (version_seq)));
867850
} else {
868-
#ifdef undef
869-
DPRINTLN(DBG_INFO, "no VERSION, rest " + String (sml_serial_len - sizeof (version_seq)));
870-
#endif
871851
sml_state = SML_ST_FIND_START_TAG;
872852
}
873853
sml_serial_len -= sizeof (version_seq);
@@ -892,10 +872,8 @@ uint16_t sml_parse_stream (uint16 len)
892872
parse_continue = true;
893873
} else if ((*cur_serial_buf & 0x70) == 0x70) {
894874
/* todo: extended list on 1st level (does this happen in real life?) */
875+
DPRINTLN (DBG_VERBOSE, "TOPLIST 0x" + String(*cur_serial_buf, HEX) + ", rest " + String (sml_serial_len - 1));
895876
sml_telegram_crc = sml_calc_crc (sml_telegram_crc, 1, cur_serial_buf);
896-
#ifdef undef
897-
DPRINTLN (DBG_INFO, "TOPLIST 0x" + String(*cur_serial_buf, HEX) + ", rest " + String (sml_serial_len - 1));
898-
#endif
899877
sml_state = SML_ST_FIND_LIST_ENTRIES;
900878
cur_sml_list_layer = 0;
901879
sml_message = SML_MSG_NONE;
@@ -951,9 +929,7 @@ uint16_t sml_parse_stream (uint16 len)
951929
sml_state = SML_ST_FIND_LIST_ENTRIES;
952930
sml_list_layer_entries[cur_sml_list_layer]--;
953931
while (!sml_list_layer_entries[cur_sml_list_layer]) {
954-
#ifdef undef
955-
DPRINTLN(DBG_INFO, "COMPLETE, layer " + String (cur_sml_list_layer));
956-
#endif
932+
DPRINTLN(DBG_VERBOSE, "COMPLETE, layer " + String (cur_sml_list_layer));
957933
if (cur_sml_list_layer) {
958934
cur_sml_list_layer--;
959935
} else {
@@ -1006,7 +982,7 @@ uint16_t sml_parse_stream (uint16 len)
1006982
", Yield in " + String (obis_yield_in_all_value) +
1007983
", Yield out " + String (obis_yield_out_all_value));
1008984
#else
1009-
DPRINTLN(DBG_INFO, "Power " + String (obis_power_all_value));
985+
DPRINTLN(DBG_VERBOSE, "Power " + String (obis_power_all_value));
1010986
#endif
1011987
sml_handle_obis_pac (obis_power_all_value);
1012988
} else {

src/web/RestApi.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -511,10 +511,19 @@ class RestApi {
511511
#ifdef AHOY_SML_OBIS_SUPPORT
512512
if (mConfig->sml_obis.ir_connected) {
513513
// design: no value of inverter but I want this value to be displayed prominently
514-
obj[F("grid_power")] = sml_get_obis_pac ();
514+
obj[F("grid_power")] = sml_get_obis_pac ();
515515
}
516516
#endif
517-
517+
if (iv->alarmCode) {
518+
time_t midnight = mApp->getTimestamp();
519+
520+
midnight -= midnight % 86400;
521+
obj[F("alarm_str")] = iv->getAlarmStr(iv->alarmCode);
522+
obj[F("alarm_start")] = String(midnight + iv->alarmStart);
523+
if (iv->alarmEnd && (iv->alarmEnd > iv->alarmStart)) {
524+
obj[F("alarm_end")] = String(midnight + iv->alarmEnd);
525+
}
526+
}
518527
JsonArray ch = obj.createNestedArray("ch");
519528

520529
// AC

src/web/html/visualization.html

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -186,23 +186,31 @@
186186
]);
187187
}
188188

189-
function tsInfo(ts) {
190-
var ageInfo = "Last received data requested at: ";
189+
function tsInfo(ts, alarm_str, alarm_start, alarm_end) {
190+
var ageInfo = "Last received data at ";
191+
var alarmInfo = "";
191192
if(ts > 0) {
192193
var date = new Date(ts * 1000);
193-
ageInfo += date.toLocaleString('de-DE');
194+
ageInfo += date.toLocaleTimeString('de-DE');
194195
}
195-
else
196-
ageInfo += "nothing received";
197-
198-
return ml("div", {class: "mb-5"}, [
199-
ml("div", {class: "row p-1 ts-h mx-2"},
200-
ml("div", {class: "col"}, "")
201-
),
202-
ml("div", {class: "row p-2 ts-bg mx-2"},
203-
ml("div", {class: "col mx-2"}, ageInfo)
204-
)
205-
]);
196+
else {
197+
ageInfo += "---";
198+
}
199+
if (alarm_str !== undefined) {
200+
var start = new Date(alarm_start * 1000);
201+
alarmInfo += alarm_str + " at ";
202+
alarmInfo += start.toLocaleTimeString('de-DE');
203+
if (alarm_end !== undefined) {
204+
var end = new Date(alarm_end * 1000);
205+
alarmInfo += " until ";
206+
alarmInfo += end.toLocaleTimeString('de-DE');
207+
}
208+
}
209+
return ml("div", {class: "mb-5"},
210+
ml("div", {class: "row p-2 ts-bg mx-2"}, [
211+
ml("span", {class: "col mx-2"}, ageInfo),
212+
ml("span", {class: "col mx-2"}, alarmInfo)
213+
]));
206214
}
207215

208216
function parseIv(obj) {
@@ -220,7 +228,7 @@
220228
ml("div", {}, [
221229
ivHead(obj),
222230
ml("div", {class: "row mb-2"}, chn),
223-
tsInfo(obj.ts_last_success)
231+
tsInfo(obj.ts_last_success, obj.alarm_str, obj.alarm_start, obj.alarm_end)
224232
])
225233
);
226234

0 commit comments

Comments
 (0)