Skip to content

Commit a50219a

Browse files
Merge pull request #448 from KipK:events
Add some events through websocket & mqtt
2 parents 3a6c28e + e0c86ba commit a50219a

File tree

4 files changed

+154
-102
lines changed

4 files changed

+154
-102
lines changed

src/evse_monitor.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,13 @@ void EvseMonitor::getChargeCurrentAndVoltageFromEvse()
710710
if(VOLTAGE_MINIMUM <= volts && volts <= VOLTAGE_MAXIMUM) {
711711
_voltage = volts;
712712
}
713+
714+
StaticJsonDocument<64> event;
715+
event["amp"] = _amp * AMPS_SCALE_FACTOR;;
716+
event["voltage"] = _voltage * VOLTS_SCALE_FACTOR;
717+
event_send(event);
718+
719+
713720
_data_ready.ready(EVSE_MONITOR_AMP_AND_VOLT_DATA_READY);
714721
}
715722
});
@@ -769,6 +776,11 @@ void EvseMonitor::getEnergyFromEvse()
769776
_total_kwh = total_kwh;
770777

771778
_data_ready.ready(EVSE_MONITOR_ENERGY_DATA_READY);
779+
StaticJsonDocument<512> event;
780+
event["session_energy"] = _session_wh;
781+
event["total_energy"] = _total_kwh;
782+
event["wh"] = _total_kwh * TOTAL_ENERGY_SCALE_FACTOR;
783+
event_send(event);
772784
}
773785
});
774786
} else {

src/input.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,18 @@ class InputTask : public MicroTasks::Task
6363
if(_evseState.IsTriggered())
6464
{
6565
// Send to all clients
66-
StaticJsonDocument<64> event;
66+
StaticJsonDocument<512> event;
6767
event["state"] = evse.getEvseState();
6868
event["flags"] = evse.getFlags();
6969
event["vehicle"] = evse.isVehicleConnected() ? 1 : 0;
7070
event["colour"] = evse.getStateColour();
7171
event["pilot"] = evse.getChargeCurrent();
7272
event["manual_override"] = manual.isActive() ? 1 : 0; //TODO: remove this
73-
event["session_energy"] = evse.getSessionEnergy();
73+
event["status"] = evse.getState().toString();
74+
event["elapsed"] = evse.getSessionElapsed();
75+
event["amp"] = evse.getAmps() * AMPS_SCALE_FACTOR;
76+
event["voltage"] = evse.getVoltage() * VOLTS_SCALE_FACTOR;
77+
7478
event_send(event);
7579
}
7680

@@ -130,13 +134,25 @@ void create_rapi_json(JsonDocument &doc)
130134
}
131135
#endif
132136
doc["state"] = evse.getEvseState();
137+
doc["status"] = evse.getState().toString();
133138
doc["flags"] = evse.getFlags();
134139
doc["vehicle"] = evse.isVehicleConnected() ? 1 : 0;
135140
doc["colour"] = evse.getStateColour();
136141
doc["manual_override"] = manual.isActive() ? 1 : 0;
137142
doc["freeram"] = ESPAL.getFreeHeap();
138143
doc["divertmode"] = (uint8_t)divert.getMode();
139144
doc["srssi"] = WiFi.RSSI();
145+
// get the current time
146+
char time[64];
147+
char offset[8];
148+
struct timeval local_time;
149+
gettimeofday(&local_time, NULL);
150+
struct tm * timeinfo = gmtime(&local_time.tv_sec);
151+
strftime(time, sizeof(time), "%FT%TZ", timeinfo);
152+
strftime(offset, sizeof(offset), "%z", timeinfo);
153+
doc["time"] = time;
154+
doc["offset"] = offset;
155+
doc["elapsed"] = evse.getSessionElapsed();
140156
}
141157

142158
void

src/main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,9 @@ void event_send(JsonDocument &event)
270270
DBUGLN("");
271271
#endif
272272
web_server_event(event);
273+
yield();
273274
mqtt_publish(event);
275+
yield();
274276
}
275277

276278
void hardware_setup()

src/web_server.cpp

Lines changed: 122 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,113 @@ bool isPositive(MongooseHttpServerRequest *request, const char *param) {
170170
return paramFound >= 0 && (0 == paramFound || isPositive(String(paramValue)));
171171
}
172172

173+
//---------------------------------------------------------------------
174+
// Build status data
175+
// --------------------------------------------------------------------
176+
177+
void buildStatus(DynamicJsonDocument &doc) {
178+
179+
// Get the current time
180+
struct timeval local_time;
181+
gettimeofday(&local_time, NULL);
182+
183+
struct tm * timeinfo = gmtime(&local_time.tv_sec);
184+
185+
char time[64];
186+
char offset[8];
187+
strftime(time, sizeof(time), "%FT%TZ", timeinfo);
188+
strftime(offset, sizeof(offset), "%z", timeinfo);
189+
190+
if (net_eth_connected()) {
191+
doc["mode"] = "Wired";
192+
} else if (net_wifi_mode_is_sta_only()) {
193+
doc["mode"] = "STA";
194+
} else if (net_wifi_mode_is_ap_only()) {
195+
doc["mode"] = "AP";
196+
} else if (net_wifi_mode_is_ap() && net_wifi_mode_is_sta()) {
197+
doc["mode"] = "STA+AP";
198+
}
199+
200+
doc["wifi_client_connected"] = (int)net_wifi_client_connected();
201+
doc["eth_connected"] = (int)net_eth_connected();
202+
doc["net_connected"] = (int)net_is_connected();
203+
doc["ipaddress"] = ipaddress;
204+
205+
doc["emoncms_connected"] = (int)emoncms_connected;
206+
doc["packets_sent"] = packets_sent;
207+
doc["packets_success"] = packets_success;
208+
209+
doc["mqtt_connected"] = (int)mqtt_connected();
210+
211+
doc["ocpp_connected"] = (int)MongooseOcppSocketClient::ocppConnected();
212+
213+
#if defined(ENABLE_PN532) || defined(ENABLE_RFID)
214+
doc["rfid_failure"] = (int) rfid.communicationFails();
215+
#endif
216+
217+
doc["ohm_hour"] = ohm_hour;
218+
219+
doc["free_heap"] = ESPAL.getFreeHeap();
220+
221+
doc["comm_sent"] = rapiSender.getSent();
222+
doc["comm_success"] = rapiSender.getSuccess();
223+
doc["rapi_connected"] = (int)rapiSender.isConnected();
224+
doc["evse_connected"] = (int)evse.isConnected();
225+
226+
create_rapi_json(doc);
227+
228+
doc["status"] = evse.getState().toString();
229+
230+
doc["elapsed"] = evse.getSessionElapsed();
231+
doc["wattsec"] = evse.getSessionEnergy() * SESSION_ENERGY_SCALE_FACTOR;
232+
doc["watthour"] = evse.getTotalEnergy() * TOTAL_ENERGY_SCALE_FACTOR;
233+
234+
doc["gfcicount"] = evse.getFaultCountGFCI();
235+
doc["nogndcount"] = evse.getFaultCountNoGround();
236+
doc["stuckcount"] = evse.getFaultCountStuckRelay();
237+
238+
doc["solar"] = solar;
239+
doc["grid_ie"] = grid_ie;
240+
doc["charge_rate"] = divert.getChargeRate();
241+
doc["divert_update"] = (millis() - divert.getLastUpdate()) / 1000;
242+
doc["divert_active"] = divert.isActive();
243+
244+
doc["shaper"] = shaper.isActive();
245+
doc["shaper_live_pwr"] = shaper.getLivePwr();
246+
doc["shaper_chg_cur"] = shaper.getChgCur();
247+
248+
doc["service_level"] = static_cast<uint8_t>(evse.getActualServiceLevel());
249+
250+
doc["ota_update"] = (int)Update.isRunning();
251+
doc["time"] = String(time);
252+
doc["offset"] = String(offset);
253+
254+
doc["config_version"] = config_version;
255+
doc["schedule_version"] = scheduler.getVersion();
256+
doc["schedule_plan_version"] = scheduler.getPlanVersion();
257+
258+
doc["vehicle_state_update"] = (millis() - evse.getVehicleLastUpdated()) / 1000;
259+
if(teslaClient.getVehicleCnt() > 0) {
260+
doc["tesla_vehicle_count"] = teslaClient.getVehicleCnt();
261+
doc["tesla_vehicle_id"] = teslaClient.getVehicleId(teslaClient.getCurVehicleIdx());
262+
doc["tesla_vehicle_name"] = teslaClient.getVehicleDisplayName(teslaClient.getCurVehicleIdx());
263+
teslaClient.getChargeInfoJson(doc);
264+
} else {
265+
doc["tesla_vehicle_count"] = false;
266+
doc["tesla_vehicle_id"] = false;
267+
doc["tesla_vehicle_name"] = false;
268+
if(evse.isVehicleStateOfChargeValid()) {
269+
doc["battery_level"] = evse.getVehicleStateOfCharge();
270+
}
271+
if(evse.isVehicleRangeValid()) {
272+
doc["battery_range"] = evse.getVehicleRange();
273+
}
274+
if(evse.isVehicleEtaValid()) {
275+
doc["time_to_full_charge"] = evse.getVehicleEta();
276+
}
277+
}
278+
}
279+
173280
// -------------------------------------------------------------------
174281
// Wifi scan /scan not currently used
175282
// url: /scan
@@ -574,108 +681,10 @@ handleStatus(MongooseHttpServerRequest *request) {
574681
return;
575682
}
576683

577-
// Get the current time
578-
struct timeval local_time;
579-
gettimeofday(&local_time, NULL);
580-
581-
struct tm * timeinfo = gmtime(&local_time.tv_sec);
582-
583-
char time[64];
584-
char offset[8];
585-
strftime(time, sizeof(time), "%FT%TZ", timeinfo);
586-
strftime(offset, sizeof(offset), "%z", timeinfo);
587-
588684
const size_t capacity = JSON_OBJECT_SIZE(40) + 1024;
589685
DynamicJsonDocument doc(capacity);
590686

591-
if (net_eth_connected()) {
592-
doc["mode"] = "Wired";
593-
} else if (net_wifi_mode_is_sta_only()) {
594-
doc["mode"] = "STA";
595-
} else if (net_wifi_mode_is_ap_only()) {
596-
doc["mode"] = "AP";
597-
} else if (net_wifi_mode_is_ap() && net_wifi_mode_is_sta()) {
598-
doc["mode"] = "STA+AP";
599-
}
600-
601-
doc["wifi_client_connected"] = (int)net_wifi_client_connected();
602-
doc["eth_connected"] = (int)net_eth_connected();
603-
doc["net_connected"] = (int)net_is_connected();
604-
doc["ipaddress"] = ipaddress;
605-
606-
doc["emoncms_connected"] = (int)emoncms_connected;
607-
doc["packets_sent"] = packets_sent;
608-
doc["packets_success"] = packets_success;
609-
610-
doc["mqtt_connected"] = (int)mqtt_connected();
611-
612-
doc["ocpp_connected"] = (int)MongooseOcppSocketClient::ocppConnected();
613-
614-
#if defined(ENABLE_PN532) || defined(ENABLE_RFID)
615-
doc["rfid_failure"] = (int) rfid.communicationFails();
616-
#endif
617-
618-
doc["ohm_hour"] = ohm_hour;
619-
620-
doc["free_heap"] = ESPAL.getFreeHeap();
621-
622-
doc["comm_sent"] = rapiSender.getSent();
623-
doc["comm_success"] = rapiSender.getSuccess();
624-
doc["rapi_connected"] = (int)rapiSender.isConnected();
625-
doc["evse_connected"] = (int)evse.isConnected();
626-
627-
create_rapi_json(doc);
628-
629-
doc["status"] = evse.getState().toString();
630-
631-
doc["elapsed"] = evse.getSessionElapsed();
632-
doc["wattsec"] = evse.getSessionEnergy() * SESSION_ENERGY_SCALE_FACTOR;
633-
doc["watthour"] = evse.getTotalEnergy() * TOTAL_ENERGY_SCALE_FACTOR;
634-
635-
doc["gfcicount"] = evse.getFaultCountGFCI();
636-
doc["nogndcount"] = evse.getFaultCountNoGround();
637-
doc["stuckcount"] = evse.getFaultCountStuckRelay();
638-
639-
doc["solar"] = solar;
640-
doc["grid_ie"] = grid_ie;
641-
doc["charge_rate"] = divert.getChargeRate();
642-
doc["divert_update"] = (millis() - divert.getLastUpdate()) / 1000;
643-
doc["divert_active"] = divert.isActive();
644-
645-
doc["shaper"] = shaper.isActive();
646-
doc["shaper_live_pwr"] = shaper.getLivePwr();
647-
doc["shaper_chg_cur"] = shaper.getChgCur();
648-
649-
doc["service_level"] = static_cast<uint8_t>(evse.getActualServiceLevel());
650-
651-
doc["ota_update"] = (int)Update.isRunning();
652-
doc["time"] = String(time);
653-
doc["offset"] = String(offset);
654-
655-
doc["config_version"] = config_version;
656-
doc["schedule_version"] = scheduler.getVersion();
657-
doc["schedule_plan_version"] = scheduler.getPlanVersion();
658-
659-
doc["vehicle_state_update"] = (millis() - evse.getVehicleLastUpdated()) / 1000;
660-
if(teslaClient.getVehicleCnt() > 0) {
661-
doc["tesla_vehicle_count"] = teslaClient.getVehicleCnt();
662-
doc["tesla_vehicle_id"] = teslaClient.getVehicleId(teslaClient.getCurVehicleIdx());
663-
doc["tesla_vehicle_name"] = teslaClient.getVehicleDisplayName(teslaClient.getCurVehicleIdx());
664-
teslaClient.getChargeInfoJson(doc);
665-
} else {
666-
doc["tesla_vehicle_count"] = false;
667-
doc["tesla_vehicle_id"] = false;
668-
doc["tesla_vehicle_name"] = false;
669-
if(evse.isVehicleStateOfChargeValid()) {
670-
doc["battery_level"] = evse.getVehicleStateOfCharge();
671-
}
672-
if(evse.isVehicleRangeValid()) {
673-
doc["battery_range"] = evse.getVehicleRange();
674-
}
675-
if(evse.isVehicleEtaValid()) {
676-
doc["time_to_full_charge"] = evse.getVehicleEta();
677-
}
678-
}
687+
buildStatus(doc);
679688

680689
response->setCode(200);
681690
serializeJson(doc, *response);
@@ -1100,6 +1109,16 @@ void onWsFrame(MongooseHttpWebSocketConnection *connection, int flags, uint8_t *
11001109
DBUGF("Got message %.*s", len, (const char *)data);
11011110
}
11021111

1112+
void onWsConnect(MongooseHttpWebSocketConnection *connection)
1113+
{
1114+
DBUGF("New client connected over ws");
1115+
// pushing states to client
1116+
const size_t capacity = JSON_OBJECT_SIZE(40) + 1024;
1117+
DynamicJsonDocument doc(capacity);
1118+
buildStatus(doc);
1119+
web_server_event(doc);
1120+
}
1121+
11031122
void
11041123
web_server_setup() {
11051124
// SPIFFS.begin(); // mount the fs
@@ -1191,7 +1210,10 @@ web_server_setup() {
11911210
server.sendAll("/evse/console", WEBSOCKET_OP_TEXT, buffer, size);
11921211
});
11931212

1194-
server.on("/ws$")->onFrame(onWsFrame);
1213+
server.on("/ws$")->
1214+
onFrame(onWsFrame)
1215+
->
1216+
onConnect(onWsConnect);
11951217

11961218
server.onNotFound(handleNotFound);
11971219

0 commit comments

Comments
 (0)