@@ -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+
11031122void
11041123web_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