ESP8266 gateway + WebServer = Awesome!
-
Hi,
I used the indications feature of MySensors 2.0 and a webserver to have the gateway provide status information through a web page:

This is how I did it:
In the global section I added this:
#include <ESP8266WiFi.h> #include <ESP8266WebServer.h> #include <WiFiClient.h> ESP8266WebServer WebServer(80); unsigned long startTime=millis(); unsigned long gwMsgSent = 0; unsigned long gwMsgRec = 0; String WebPage = "<h1>ESP8266 MQTT client for Mysensors</h1>"; void setupWebServer(); void showRootPage(); String readableTimestamp(unsigned long milliseconds);In the setup() Added this:
Serial.begin(9600); setupWebServer();Defined the following functions:
void setupWebServer() { WebServer.on("/", HTTP_GET, showRootPage); WebServer.begin(); Serial.println("WebServer started..."); } void indication( const indication_t ind ) { switch (ind) { case INDICATION_GW_TX: gwMsgSent++; break; case INDICATION_GW_RX: gwMsgRec++; break; default: break; }; } void showRootPage() { unsigned long runningTime = millis() - startTime; String page = WebPage; page+="<br>General information</br>"; page+= "<style> table, th, td { border: 1px solid black;}</style>"; page+="<table style=\"width:400\">"; page+="<tr>"; page+= "<th>Item</th>"; page+= "<th>Value</th>"; page+="</tr>"; page+="<tr>"; page+= "<td>Running for</td>"; page+= "<td>"; page += readableTimestamp(runningTime) ; page+= "</td>"; page+="</tr>"; page+="<tr>"; page+= "<td>Gateway messages sent</td>"; page+= "<td>"; page += gwMsgSent; page+= "</td>"; page+="</tr>"; page+="</table>"; page+="<br>MySensors gateway information</br>"; page+= "<style> table, th, td { border: 1px solid black;}</style>"; page+="<table style=\"width:400\">"; page+="<tr>"; page+= "<th>Item</th>"; page+= "<th>Value</th>"; page+="</tr>"; page+="<tr>"; page+= "<td>Gateway messages received</td>"; page+= "<td>"; page += gwMsgRec; page+= "</td>"; page+="</tr>"; page+="<tr>"; page+= "<td>Gateway messages sent</td>"; page+= "<td>"; page += gwMsgSent; page+= "</td>"; page+="</tr>"; page+="</table>"; Serial.println("WS: Send root webpage"); WebServer.send(200, "text/html", page); } String readableTimestamp(unsigned long milliseconds) { int days = milliseconds / 86400000; milliseconds=milliseconds % 86400000; int hours = milliseconds / 3600000; milliseconds = milliseconds %3600000; int minutes = milliseconds / 60000; milliseconds = milliseconds % 60000; int seconds = milliseconds / 1000; milliseconds = milliseconds % 1000; String timeStamp; timeStamp = days; timeStamp += " days, "; timeStamp += hours; timeStamp += ":"; timeStamp += minutes ; timeStamp += ":"; timeStamp +=seconds; timeStamp += "."; timeStamp +=milliseconds; Serial.println(timeStamp); return timeStamp; }And in loop() added the following:
WebServer.handleClient();If you have any more idaes on what to add to this page (I am thinking about maintaining a list of registered nodes and sensors) just post a reply!
-
Hi,
I used the indications feature of MySensors 2.0 and a webserver to have the gateway provide status information through a web page:

This is how I did it:
In the global section I added this:
#include <ESP8266WiFi.h> #include <ESP8266WebServer.h> #include <WiFiClient.h> ESP8266WebServer WebServer(80); unsigned long startTime=millis(); unsigned long gwMsgSent = 0; unsigned long gwMsgRec = 0; String WebPage = "<h1>ESP8266 MQTT client for Mysensors</h1>"; void setupWebServer(); void showRootPage(); String readableTimestamp(unsigned long milliseconds);In the setup() Added this:
Serial.begin(9600); setupWebServer();Defined the following functions:
void setupWebServer() { WebServer.on("/", HTTP_GET, showRootPage); WebServer.begin(); Serial.println("WebServer started..."); } void indication( const indication_t ind ) { switch (ind) { case INDICATION_GW_TX: gwMsgSent++; break; case INDICATION_GW_RX: gwMsgRec++; break; default: break; }; } void showRootPage() { unsigned long runningTime = millis() - startTime; String page = WebPage; page+="<br>General information</br>"; page+= "<style> table, th, td { border: 1px solid black;}</style>"; page+="<table style=\"width:400\">"; page+="<tr>"; page+= "<th>Item</th>"; page+= "<th>Value</th>"; page+="</tr>"; page+="<tr>"; page+= "<td>Running for</td>"; page+= "<td>"; page += readableTimestamp(runningTime) ; page+= "</td>"; page+="</tr>"; page+="<tr>"; page+= "<td>Gateway messages sent</td>"; page+= "<td>"; page += gwMsgSent; page+= "</td>"; page+="</tr>"; page+="</table>"; page+="<br>MySensors gateway information</br>"; page+= "<style> table, th, td { border: 1px solid black;}</style>"; page+="<table style=\"width:400\">"; page+="<tr>"; page+= "<th>Item</th>"; page+= "<th>Value</th>"; page+="</tr>"; page+="<tr>"; page+= "<td>Gateway messages received</td>"; page+= "<td>"; page += gwMsgRec; page+= "</td>"; page+="</tr>"; page+="<tr>"; page+= "<td>Gateway messages sent</td>"; page+= "<td>"; page += gwMsgSent; page+= "</td>"; page+="</tr>"; page+="</table>"; Serial.println("WS: Send root webpage"); WebServer.send(200, "text/html", page); } String readableTimestamp(unsigned long milliseconds) { int days = milliseconds / 86400000; milliseconds=milliseconds % 86400000; int hours = milliseconds / 3600000; milliseconds = milliseconds %3600000; int minutes = milliseconds / 60000; milliseconds = milliseconds % 60000; int seconds = milliseconds / 1000; milliseconds = milliseconds % 1000; String timeStamp; timeStamp = days; timeStamp += " days, "; timeStamp += hours; timeStamp += ":"; timeStamp += minutes ; timeStamp += ":"; timeStamp +=seconds; timeStamp += "."; timeStamp +=milliseconds; Serial.println(timeStamp); return timeStamp; }And in loop() added the following:
WebServer.handleClient();If you have any more idaes on what to add to this page (I am thinking about maintaining a list of registered nodes and sensors) just post a reply!
-
@Yveaux thanks for formatting the code.
Would it be possible to get the list of registered nodes and sensors for example?
-
The routing table only holds the next jump for a destination. Might be better to implement receive method and build a new data structure (as the ESP has plenty of memory). Then you would be able to pick up both from-field and even presentation messages to show which type of sensors the nodes has attached.
-
@hek Indeed, the ESP has both plenty of processing power and memory compared to the arduino.
This implementing a receive method, is that a method I can implement in my sketch, with a specific name and signature, and it will be called automatically (like the indication handler)? or does it require changes in de library code? Sounds promising, I can just take out the data I need and store it in a separate structure until the webpage is requested.
Another thing I found "somewhere on the Internet" is an ESP8266 program that, when the wifi connection is not established, or the stored network SSID and password are empty, places the ESP in Access point mode. You can connect to this wifi network and configure the wifi settings. That way you don't need your SSID and password in the sketch.
Too many things to do, and too little time I am afraid.:grinning:
-
@hek Indeed, the ESP has both plenty of processing power and memory compared to the arduino.
This implementing a receive method, is that a method I can implement in my sketch, with a specific name and signature, and it will be called automatically (like the indication handler)? or does it require changes in de library code? Sounds promising, I can just take out the data I need and store it in a separate structure until the webpage is requested.
Another thing I found "somewhere on the Internet" is an ESP8266 program that, when the wifi connection is not established, or the stored network SSID and password are empty, places the ESP in Access point mode. You can connect to this wifi network and configure the wifi settings. That way you don't need your SSID and password in the sketch.
Too many things to do, and too little time I am afraid.:grinning:
-
Hmm I implemented a receive function like this:
void receive(const MyMessage &message) { Serial.println("@@@@@@@#####@@@@@Message"); }And when I connect my smartmeter sensor I get the following output in the serial console of my MQTT gateway:
0;255;3;0;9;TSP:MSG:READ 20-20-0 s=6,c=1,t=17,pt=7,l=5,sg=0:350 0;255;3;0;9;Sending message on topic: mygateway1-out/20/6/1/0/17 0;255;3;0;9;TSP:MSG:READ 20-20-0 s=7,c=1,t=17,pt=7,l=5,sg=1: 0 0;255;3;0;9;Sending message on topic: mygateway1-out/20/7/1/0/17So I assume the receive function is not called?
Still, as with the indication function it is fuzzy to me how it i possible that a function is called when it is implemented, but the compiler does not complain when it is not :confused:
Is this some kind of inheritance relation?
-
Hmm I implemented a receive function like this:
void receive(const MyMessage &message) { Serial.println("@@@@@@@#####@@@@@Message"); }And when I connect my smartmeter sensor I get the following output in the serial console of my MQTT gateway:
0;255;3;0;9;TSP:MSG:READ 20-20-0 s=6,c=1,t=17,pt=7,l=5,sg=0:350 0;255;3;0;9;Sending message on topic: mygateway1-out/20/6/1/0/17 0;255;3;0;9;TSP:MSG:READ 20-20-0 s=7,c=1,t=17,pt=7,l=5,sg=1: 0 0;255;3;0;9;Sending message on topic: mygateway1-out/20/7/1/0/17So I assume the receive function is not called?
Still, as with the indication function it is fuzzy to me how it i possible that a function is called when it is implemented, but the compiler does not complain when it is not :confused:
Is this some kind of inheritance relation?
@Japio said:
Still, as with the indication function it is fuzzy to me how it i possible that a function is called when it is implemented, but the compiler does not complain when it is not
The function is defined as weak in the library.
This means the user can implement its own version and then the pointer to the function will be non-null, or you can leave it unimplemented and the pointer to the function becomes null. It's up to the caller (the MySensors library in this case) to test if the pointer is null before calling the function. -
@Yveaux ok, thanks, I just have learned something ;-)
So I can assume the receive function is not called from the library then? So which function is called, on reception of data from a node?
@Japio Looks like you hit a bug in 2.0.0 (receive() was not called for gateways), which has been fixed in development: https://github.com/mysensors/MySensors/commit/24e3dfa36c711b4174ed615408994e8624a2b1f3#diff-9ff5690366e84c42d1e97f40dfe3b8a1R580
Please try with development branch (2.0.1 beta) https://github.com/mysensors/MySensors/tree/development and see if that fixes your issue.
-
Yes, I see the difference. I'll try the bèta version tomorrow.
-
Hi,
I used the indications feature of MySensors 2.0 and a webserver to have the gateway provide status information through a web page:

This is how I did it:
In the global section I added this:
#include <ESP8266WiFi.h> #include <ESP8266WebServer.h> #include <WiFiClient.h> ESP8266WebServer WebServer(80); unsigned long startTime=millis(); unsigned long gwMsgSent = 0; unsigned long gwMsgRec = 0; String WebPage = "<h1>ESP8266 MQTT client for Mysensors</h1>"; void setupWebServer(); void showRootPage(); String readableTimestamp(unsigned long milliseconds);In the setup() Added this:
Serial.begin(9600); setupWebServer();Defined the following functions:
void setupWebServer() { WebServer.on("/", HTTP_GET, showRootPage); WebServer.begin(); Serial.println("WebServer started..."); } void indication( const indication_t ind ) { switch (ind) { case INDICATION_GW_TX: gwMsgSent++; break; case INDICATION_GW_RX: gwMsgRec++; break; default: break; }; } void showRootPage() { unsigned long runningTime = millis() - startTime; String page = WebPage; page+="<br>General information</br>"; page+= "<style> table, th, td { border: 1px solid black;}</style>"; page+="<table style=\"width:400\">"; page+="<tr>"; page+= "<th>Item</th>"; page+= "<th>Value</th>"; page+="</tr>"; page+="<tr>"; page+= "<td>Running for</td>"; page+= "<td>"; page += readableTimestamp(runningTime) ; page+= "</td>"; page+="</tr>"; page+="<tr>"; page+= "<td>Gateway messages sent</td>"; page+= "<td>"; page += gwMsgSent; page+= "</td>"; page+="</tr>"; page+="</table>"; page+="<br>MySensors gateway information</br>"; page+= "<style> table, th, td { border: 1px solid black;}</style>"; page+="<table style=\"width:400\">"; page+="<tr>"; page+= "<th>Item</th>"; page+= "<th>Value</th>"; page+="</tr>"; page+="<tr>"; page+= "<td>Gateway messages received</td>"; page+= "<td>"; page += gwMsgRec; page+= "</td>"; page+="</tr>"; page+="<tr>"; page+= "<td>Gateway messages sent</td>"; page+= "<td>"; page += gwMsgSent; page+= "</td>"; page+="</tr>"; page+="</table>"; Serial.println("WS: Send root webpage"); WebServer.send(200, "text/html", page); } String readableTimestamp(unsigned long milliseconds) { int days = milliseconds / 86400000; milliseconds=milliseconds % 86400000; int hours = milliseconds / 3600000; milliseconds = milliseconds %3600000; int minutes = milliseconds / 60000; milliseconds = milliseconds % 60000; int seconds = milliseconds / 1000; milliseconds = milliseconds % 1000; String timeStamp; timeStamp = days; timeStamp += " days, "; timeStamp += hours; timeStamp += ":"; timeStamp += minutes ; timeStamp += ":"; timeStamp +=seconds; timeStamp += "."; timeStamp +=milliseconds; Serial.println(timeStamp); return timeStamp; }And in loop() added the following:
WebServer.handleClient();If you have any more idaes on what to add to this page (I am thinking about maintaining a list of registered nodes and sensors) just post a reply!
-
No, it worked right out of the box, something that surprised me as well.
You do need Mysensors 2.0 for this.
You can check if you have a myindication.h file in the source tree of the Mysensors library. That file also contains the indications sent.
-
No, it worked right out of the box, something that surprised me as well.
You do need Mysensors 2.0 for this.
You can check if you have a myindication.h file in the source tree of the Mysensors library. That file also contains the indications sent.
-
No, it worked right out of the box, something that surprised me as well.
You do need Mysensors 2.0 for this.
You can check if you have a myindication.h file in the source tree of the Mysensors library. That file also contains the indications sent.
@Japio It's very easy to get information about available memory and wifi signal - just add
page+="<tr>"; page+= "<td>Free memory:</td>"; page+= "<td>"; page += ESP.getFreeHeap() ; page+= " bytes</td>"; page+="</tr>"; page+="<tr>"; page+= "<td>WIFI signal:</td>"; page+= "<td>"; page += WiFi.RSSI(); ; page+= " dBm</td>"; page+="</tr>"; -
Great! This will be added.
I am going to continue with the node and sensor status tomorrow.