enocean

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
enocean [13.03.2018 22:43] – [add the async printer] Pascal Suterenocean [16.03.2018 06:18] (current) – [MQTT] Pascal Suter
Line 24: Line 24:
 here are a few libraries i have found beforehand and intend on trying out:  here are a few libraries i have found beforehand and intend on trying out: 
   * [[https://github.com/marvinroger/async-mqtt-client|Async MQTT client]] for mqtt obviously   * [[https://github.com/marvinroger/async-mqtt-client|Async MQTT client]] for mqtt obviously
-  * [[https://github.com/me-no-dev/ESPAsyncTCP|ESPAsyncTCP]] to plot debug messages to a netcat server while working with the enOcean module on the serial port.. this is to avoid using SoftSerial+  * <del>[[https://github.com/me-no-dev/ESPAsyncTCP|ESPAsyncTCP]] to plot debug messages to a netcat server while working with the enOcean module on the serial port.. turns out i could still use Serial for debugging as well as to receive enOcean messages, so this was not needed.</del> As a matter of fact it prevented the MQTT Client class to operate correctly. However, I wrote a little gide on Using the [[ESP AsyncPrinter]] just to keep my example of how i got it to work for later reference
   * [[https://github.com/tzapu/WiFiManager|WiFiManager]] seems to do all we need to make the final device easy to get configured without a serial connection (has automatic fall back to AP mode with captive portal config page).    * [[https://github.com/tzapu/WiFiManager|WiFiManager]] seems to do all we need to make the final device easy to get configured without a serial connection (has automatic fall back to AP mode with captive portal config page). 
   * [[https://bitbucket.org/charly37/arduino_enocean_lib/downloads/|arduino enocean library]] with a [[http://djynet.net/?p=635|description from the developer]]   * [[https://bitbucket.org/charly37/arduino_enocean_lib/downloads/|arduino enocean library]] with a [[http://djynet.net/?p=635|description from the developer]]
 +  * [[https://github.com/KoljaWindeler/ESP8266_mqtt_pwm_pir_temp/tree/master/JKW_MQTT_PWM_PIR_TEMP/src|a similar project]] i found only after starting this. maybe i could just expand that one rather than writing my own? a shame i found it so late. 
  
 ===== setup and development ===== ===== setup and development =====
Line 62: Line 63:
 </code> </code>
  
-==== add the async printer ==== 
-we use [[https://github.com/me-no-dev/ESPAsyncTCP|ESPAsyncTCP]]'s AsyncPrinter to print debug messages to a tcp socket at our development machine as we will use the serial port to connect to our enOcean board.  
  
-first we need to install the library:  +==== add enOcean ==== 
-  cd <arduino directory>/portable/sketchbook/libraries/ +now we can finally add the enocean receiver to our setup. we therefore connect the +3.3V to the +3.3V of the Wemos D1, the GND to the GND and we cross connect the RX of the enocean Module to the TX of the Wemos D1 and the same for the TX fo the enOcean that goes to the RX of the Wemos 
-  git clone https://github.com/me-no-dev/ESPAsyncTCP.git+
  
-for my development machine to receive those messages i need to open a socket with ''netcat'' in listening mode. this is for linux but i am sure there are tools like that in windows too, i just don't know them. so on your develpment machine run:  +next we need the [[http://djynet.net/?p=635|enOceanMsg]] library.. howeveri have modified it slightly (removed all serial debugging and changed the enOcean communication part from ''Serial1'' to ''Serial'' as the ESP8266'''Serial1'' only supports transmitting data but not receiving. So either you do these modifications yourself or you get {{ :enocean:enoceanmsg.zip |my Version}} of it. 
-  nc -l 3333 +
-and leave the terminal open. +
- +
-now we could integrate it as is into our code as you can see in the example [[https://github.com/me-no-dev/ESPAsyncTCP/issues/30|I posted on Github]], but the problem with AsyncPrinter is, that it blocks forever waiting for a connectionThis meansthat our sketch won't make it past the setup process if our debug host is not online. that's not what we want. I therefore modified the AsyncPrinter source slightly by removing these two lines from both ''AsnycPrinter::connect()'' functions:  +
-<code cpp> +
-    while(_client->state() < 4) +
-      delay(1); +
-</code> +
- +
-let's add ''AsyncPrinter'' and a ''debug()'' function which handles sending debug messages if we have a connection to a debug host+
  
 +extract the contents of this ZIP to the ''sketchbook/libraries'' folder. I then also modified the Sketch to both include the enOcean stuff and to disable serial debugging of the WiFiManager when online-debugging is requested. 
 <code cpp> <code cpp>
 #include <ESP8266WiFi.h>          //ESP8266 Core WiFi Library (you most likely already have this in your sketch) #include <ESP8266WiFi.h>          //ESP8266 Core WiFi Library (you most likely already have this in your sketch)
Line 87: Line 76:
 #include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager WiFi Configuration Magic #include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager WiFi Configuration Magic
 #include <AsyncPrinter.h> #include <AsyncPrinter.h>
 +#include <EnOceanMsg.h>           //http://djynet.net/?p=635
  
 bool enableOnlineDebugging=true; bool enableOnlineDebugging=true;
 const char *debuggerHost="192.168.168.48"; const char *debuggerHost="192.168.168.48";
  
 +EnOceanMsg _Msg;
 AsyncPrinter ap; AsyncPrinter ap;
 WiFiManager wifiManager; WiFiManager wifiManager;
 bool debugOnline=false; bool debugOnline=false;
 bool firstround=true; bool firstround=true;
 +int lastPayload=0;
 void setup() { void setup() {
   // put your setup code here, to run once:   // put your setup code here, to run once:
-  Serial.begin(115200);+  Serial.begin(57600); 
 +  if(enableOnlineDebugging){ 
 +    wifiManager.setDebugOutput(false); 
 +  }
   wifiManager.autoConnect();   wifiManager.autoConnect();
   wifiManager.startWebPortal();   wifiManager.startWebPortal();
Line 107: Line 101:
       if(ap.connected()){       if(ap.connected()){
         debugOnline=true;         debugOnline=true;
-        ap.println("setup done");+        ap.println("connected");
         break;         break;
       } else {       } else {
Line 121: Line 115:
   } else {   } else {
     Serial.println("debugger is not online");     Serial.println("debugger is not online");
 +  }
 +  _Msg.decode();
 +  if (_Msg.dataAvailable() == true){
 +    
   }   }
 } }
 +
 +void debugHex(int payload){
 +  if(debugOnline){
 +    ap.println(payload,HEX);
 +  }  
 +}
 +
 +
 void loop() { void loop() {
   // put your main code here, to run repeatedly:   // put your main code here, to run repeatedly:
 +  int payload=0;
   wifiManager.process();   wifiManager.process();
   if(firstround){   if(firstround){
Line 130: Line 137:
     firstround=false;     firstround=false;
   }   }
 +  _Msg.decode();
 +  if(_Msg.dataAvailable() == true){
 +    payload=_Msg.getPayload();
 +    if(payload!=lastPayload){
 +      debug("new payload received:");
 +      debugHex(payload);
 +      lastPayload=payload;
 +      debugHex(_Msg.getSenderId());
 +    }
 +  }
 +  delay(50);
 } }
 </code> </code>
-you should now see "setup done" and "hello world" on your terminal with ''nc'' running+now you should see output like this on your netcat console after you started the sketch and then pressed a button:  
 +<code> 
 +connected 
 +hello world 
 +new payload received: 
 +70 
 +3102F7 
 +new payload received: 
 +
 +3102F7 
 +</code> 
 +''70'' is the hex code for one of the buttons and ''3102f7'' is actually ''0x00 0x31 0x02 0xf7'' which is the enOcean device's address which can also be found on the lable on the device itself
  
-==== add enOcean ==== +==== MQTT ==== 
-now we can finally add the enocean receiver to our setup. we therefore connect the +3.3V to the +3.3V of the Wemos D1, the GND to the GND and we cross connect the RX of the enocean Module to the TX of the Wemos D1 and the same for the TX fo the enOcean that goes to the RX of the Wemos +next up is MQTT support throught he [[https://github.com/marvinroger/async-mqtt-client|Async MQTT Library]].  
 +I should have done this right after implementing the WiFiManager as one could also use mqtt for debugging messages rather than trying to use AsyncPrinter which did not work in conjunction with mqtt and was painful to figure out in the first placeso now this contains a solution for debugging via mqtt.  
 + 
 +download the [[https://github.com/marvinroger/async-mqtt-client/releases|latest release]] as zip file and then add it via Sketch->Include Library->Add .ZIP library 
 + 
 +of course you will need an mqtt broker. you can subscribe to the enocean topic on your development machine using for example mosquitto client:  
 +  mosquitto_sub -h mqtt.psuter.ch -v -t enocean/#
  
-next we need the [[http://djynet.net/?p=635|enOceanMsg]] library.. however, i have modified it slightly (removed all serial debugging and changed the enOcean communication part from ''Serial1'' to ''Serial'' as the ESP8266's ''Serial1'' only supports transmitting data but not receiving. So either you do these modifications yourself or you get [[{{ :enocean:enoceanmsg.zip |my Version}} of it.  
  
-extract the contents of this ZIP to the ''sketchbook/libraries'' folder. I then also modified the Sketch to both include the enOcean stuff and to disable serial debugging of the WiFiManager when online-debugging is requested.  
 <code cpp> <code cpp>
 #include <ESP8266WiFi.h>          //ESP8266 Core WiFi Library (you most likely already have this in your sketch) #include <ESP8266WiFi.h>          //ESP8266 Core WiFi Library (you most likely already have this in your sketch)
Line 145: Line 178:
 #include <ESP8266WebServer.h>     //Local WebServer used to serve the configuration portal #include <ESP8266WebServer.h>     //Local WebServer used to serve the configuration portal
 #include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager WiFi Configuration Magic #include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager WiFi Configuration Magic
-#include <AsyncPrinter.h> 
 #include <EnOceanMsg.h>           //http://djynet.net/?p=635 #include <EnOceanMsg.h>           //http://djynet.net/?p=635
 +#include <AsyncMqttClient.h>       //https://github.com/marvinroger/async-mqtt-client
  
-bool enableOnlineDebugging=true+int enableDebugging=2// 0 = off, 1=Serial, 2=mqtt 
-const char *debuggerHost="192.168.168.48";+const char *mqttServer="192.168.168.1"
 +int mqttPort=1883;
  
 EnOceanMsg _Msg; EnOceanMsg _Msg;
-AsyncPrinter ap; 
 WiFiManager wifiManager; WiFiManager wifiManager;
-bool debugOnline=false; 
 bool firstround=true; bool firstround=true;
 int lastPayload=0; int lastPayload=0;
 +AsyncMqttClient mqtt;
 +bool mqttConnected=false;
 +String mqttBaseTopic="enocean";
 +
 +
 +String topic;
 +
 +void onMqttConnect(bool sessionPresent){
 +  debug("connected to mqtt server");
 +  mqttConnected=true;
 +  uint16_t packetIdPub1 = mqtt.publish(String(mqttBaseTopic+"/online").c_str(), 1, true, "now");
 +}
 +void onMqttPublish(uint16_t packetId) {
 +  if(enableDebugging==1){
 +    Serial.println("Publish acknowledged.");
 +  }
 +}
 +
 void setup() { void setup() {
   // put your setup code here, to run once:   // put your setup code here, to run once:
   Serial.begin(57600);   Serial.begin(57600);
-  if(enableOnlineDebugging){+  if(enableDebugging!=1){
     wifiManager.setDebugOutput(false);     wifiManager.setDebugOutput(false);
   }   }
   wifiManager.autoConnect();   wifiManager.autoConnect();
   wifiManager.startWebPortal();   wifiManager.startWebPortal();
-  ap.connect(debuggerHost,3333); +  mqtt.onConnect(onMqttConnect); 
-  if(enableOnlineDebugging)+  mqtt.onPublish(onMqttPublish); 
-    //block for maximum 5 seconds trying to reach the debugger +  mqtt.setServer(mqttServer, mqttPort); 
-    for ( int i = 0i < 10 ; i++){ +  mqtt.connect();
-      if(ap.connected()){ +
-        debugOnline=true+
-        ap.println("connected"); +
-        break; +
-      } else { +
-        delay(500); +
-      } +
-    } +
-  }+
 } }
  
 void debug(const char *message){ void debug(const char *message){
-  if(debugOnline){ +  switch (enableDebugging) { 
-    ap.println(message); +    case 1: 
-  } else { +      Serial.println(message); 
-    Serial.println("debugger is not online")+      break; 
-  } +    case 2: 
-  _Msg.decode()+      mqtt.publish(String(mqttBaseTopic+"/debug").c_str(), 1, true, message); 
-  if (_Msg.dataAvailable() == true){ +      break;
-    +
   }   }
 } }
  
 void debugHex(int payload){ void debugHex(int payload){
-  if(debugOnline){ +  switch (enableDebugging) { 
-    ap.println(payload,HEX);+    case 1: 
 +      Serial.println(payload,HEX)
 +      break; 
 +    case 2: 
 +      mqtt.publish(String(mqttBaseTopic+"/debug").c_str(), 1, true, String(payload,HEX).c_str()); 
 +      break;
   }     }  
 } }
Line 202: Line 247:
   // put your main code here, to run repeatedly:   // put your main code here, to run repeatedly:
   int payload=0;   int payload=0;
 +  uint32_t senderId=0;
 +  
   wifiManager.process();   wifiManager.process();
   if(firstround){   if(firstround){
-    debug("hello world");+    debug("loop started");
     firstround=false;     firstround=false;
   }   }
Line 214: Line 261:
       debugHex(payload);       debugHex(payload);
       lastPayload=payload;       lastPayload=payload;
-      debugHex(_Msg.getSenderId());+      senderId=_Msg.getSenderId()
 +      debugHex(senderId); 
 +      if(senderId > 0 && mqttConnected){ 
 +        if(payload > 0){ 
 +          topic = String(mqttBaseTopic+"/"+senderId+"/"+payload); 
 +          debug("publish ON message"); 
 +          uint16_t packetIdPub1 = mqtt.publish(topic.c_str(), 1, false, "ON"); 
 +        } else { 
 +          debug("publish OFF message"); 
 +          uint16_t packetIdPub1 = mqtt.publish(topic.c_str(), 1, false, "OFF"); 
 +        } 
 +      }
     }     }
   }   }
Line 220: Line 278:
 } }
 </code> </code>
-now you should see output like this on your netcat console after you started the sketch and then pressed a button:  
-<code> 
-connected 
-hello world 
-new payload received: 
-70 
-3102F7 
-new payload received: 
-0 
-3102F7 
-</code> 
-''70'' is the hex code for one of the buttons and ''3102f7'' is actually ''0x00 0x31 0x02 0xf7'' which is the enOcean device's address which can also be found on the lable on the device itself.  
  • enocean.1520977400.txt.gz
  • Last modified: 13.03.2018 22:43
  • by Pascal Suter