From b23a113133604b75a8351de47bcfdc210fb4092d Mon Sep 17 00:00:00 2001
From: user2684 <user2684@users.noreply.github.com>
Date: Tue, 30 May 2017 17:12:36 +0200
Subject: [PATCH] Allow a sensor to access NodeManager's or other sensors'
 functions #93 (#124)

---
 NodeManager.cpp | 131 ++++++++++++++++++++++++------------------------
 NodeManager.h   |  60 +++++++++++-----------
 README.md       |  97 ++++++++++++++++++++++-------------
 3 files changed, 160 insertions(+), 128 deletions(-)

diff --git a/NodeManager.cpp b/NodeManager.cpp
index a2af65d..721eb4d 100644
--- a/NodeManager.cpp
+++ b/NodeManager.cpp
@@ -96,7 +96,8 @@ void PowerManager::powerOff() {
    Sensor class
 */
 // constructor
-Sensor::Sensor(int child_id, int pin) {
+Sensor::Sensor(NodeManager* node_manager, int child_id, int pin) {
+  _node_manager = node_manager;
   _child_id = child_id;
   _pin = pin;
   _msg = MyMessage(_child_id, _type);
@@ -318,7 +319,7 @@ void Sensor::_send(MyMessage & message) {
 */
 
 // contructor
-SensorAnalogInput::SensorAnalogInput(int child_id, int pin): Sensor(child_id, pin) {
+SensorAnalogInput::SensorAnalogInput(NodeManager* node_manager, int child_id, int pin): Sensor(node_manager, child_id, pin) {
 }
 
 // setter/getter
@@ -405,7 +406,7 @@ int SensorAnalogInput::_getPercentage(int adc) {
 */
 
 // contructor
-SensorLDR::SensorLDR(int child_id, int pin): SensorAnalogInput(child_id, pin) {
+SensorLDR::SensorLDR(NodeManager* node_manager, int child_id, int pin): SensorAnalogInput(node_manager, child_id, pin) {
   // set presentation and type and reverse (0: no light, 100: max light)
   setPresentation(S_LIGHT_LEVEL);
   setType(V_LIGHT_LEVEL);
@@ -417,7 +418,7 @@ SensorLDR::SensorLDR(int child_id, int pin): SensorAnalogInput(child_id, pin) {
 */
 
 // contructor
-SensorThermistor::SensorThermistor(int child_id, int pin): Sensor(child_id, pin) {
+SensorThermistor::SensorThermistor(NodeManager* node_manager, int child_id, int pin): Sensor(node_manager, child_id, pin) {
   // set presentation, type and value type
   setPresentation(S_TEMP);
   setType(V_TEMP);
@@ -491,7 +492,7 @@ void SensorThermistor::onReceive(const MyMessage & message) {
 */
 
 // contructor
-SensorML8511::SensorML8511(int child_id, int pin): Sensor(child_id, pin) {
+SensorML8511::SensorML8511(NodeManager* node_manager, int child_id, int pin): Sensor(node_manager, child_id, pin) {
   // set presentation, type and value type
   setPresentation(S_UV);
   setType(V_UV);
@@ -544,7 +545,7 @@ float SensorML8511::_mapfloat(float x, float in_min, float in_max, float out_min
 */
 
 // contructor
-SensorACS712::SensorACS712(int child_id, int pin): Sensor(child_id, pin) {
+SensorACS712::SensorACS712(NodeManager* node_manager, int child_id, int pin): Sensor(node_manager, child_id, pin) {
   // set presentation, type and value type
   setPresentation(S_MULTIMETER);
   setType(V_CURRENT);
@@ -594,7 +595,7 @@ void SensorACS712::onReceive(const MyMessage & message) {
 */
 
 // contructor
-SensorRainGauge::SensorRainGauge(int child_id, int pin): Sensor(child_id, pin) {
+SensorRainGauge::SensorRainGauge(NodeManager* node_manager, int child_id, int pin): Sensor(node_manager,child_id, pin) {
   // set presentation, type and value type
   setPresentation(S_RAIN);
   setType(V_RAIN);
@@ -678,7 +679,7 @@ void SensorRainGauge::onReceive(const MyMessage & message) {
 */
 
 // contructor
-SensorRain::SensorRain(int child_id, int pin): SensorAnalogInput(child_id, pin) {
+SensorRain::SensorRain(NodeManager* node_manager, int child_id, int pin): SensorAnalogInput(node_manager,child_id, pin) {
   // set presentation and type and reverse
   setPresentation(S_RAIN);
   setType(V_RAINRATE);
@@ -693,7 +694,7 @@ SensorRain::SensorRain(int child_id, int pin): SensorAnalogInput(child_id, pin)
 */
 
 // contructor
-SensorSoilMoisture::SensorSoilMoisture(int child_id, int pin): SensorAnalogInput(child_id, pin) {
+SensorSoilMoisture::SensorSoilMoisture(NodeManager* node_manager, int child_id, int pin): SensorAnalogInput(node_manager, child_id, pin) {
   // set presentation and type and reverse
   setPresentation(S_MOISTURE);
   setType(V_LEVEL);
@@ -707,7 +708,7 @@ SensorSoilMoisture::SensorSoilMoisture(int child_id, int pin): SensorAnalogInput
 /*
  * SensorMQ
  */
-SensorMQ::SensorMQ(int child_id, int pin): Sensor(child_id,pin) {
+SensorMQ::SensorMQ(NodeManager* node_manager, int child_id, int pin): Sensor(node_manager,child_id,pin) {
   setPresentation(S_AIR_QUALITY);
   setType(V_LEVEL);
 }
@@ -853,7 +854,7 @@ int SensorMQ::_MQGetPercentage(float rs_ro_ratio, float *pcurve) {
 */
 
 // contructor
-SensorDigitalInput::SensorDigitalInput(int child_id, int pin): Sensor(child_id, pin) {
+SensorDigitalInput::SensorDigitalInput(NodeManager* node_manager, int child_id, int pin): Sensor(node_manager,child_id, pin) {
 }
 
 // what to do during before
@@ -893,7 +894,7 @@ void SensorDigitalInput::onReceive(const MyMessage & message) {
 */
 
 // contructor
-SensorDigitalOutput::SensorDigitalOutput(int child_id, int pin): Sensor(child_id, pin) {
+SensorDigitalOutput::SensorDigitalOutput(NodeManager* node_manager, int child_id, int pin): Sensor(node_manager,child_id, pin) {
 }
 
 // what to do during before
@@ -974,7 +975,7 @@ void SensorDigitalOutput::onReceive(const MyMessage & message) {
 */
 
 // contructor
-SensorRelay::SensorRelay(int child_id, int pin): SensorDigitalOutput(child_id, pin) {
+SensorRelay::SensorRelay(NodeManager* node_manager, int child_id, int pin): SensorDigitalOutput(node_manager, child_id, pin) {
   // set presentation and type
   setPresentation(S_BINARY);
   setType(V_STATUS);
@@ -991,7 +992,7 @@ void SensorRelay::onLoop() {
 */
 
 // contructor
-SensorLatchingRelay::SensorLatchingRelay(int child_id, int pin): SensorRelay(child_id, pin) {
+SensorLatchingRelay::SensorLatchingRelay(NodeManager* node_manager, int child_id, int pin): SensorRelay(node_manager, child_id, pin) {
   // like a sensor with a default pulse set
   setPulseWidth(50);
 }
@@ -1001,7 +1002,7 @@ SensorLatchingRelay::SensorLatchingRelay(int child_id, int pin): SensorRelay(chi
 */
 #if MODULE_DHT == 1
 // contructor
-SensorDHT::SensorDHT(int child_id, int pin, DHT* dht, int sensor_type, int dht_type): Sensor(child_id, pin) {
+SensorDHT::SensorDHT(NodeManager* node_manager, int child_id, int pin, DHT* dht, int sensor_type, int dht_type): Sensor(node_manager, child_id, pin) {
   // store the dht object
   _dht = dht;
   _sensor_type = sensor_type;
@@ -1074,7 +1075,7 @@ void SensorDHT::onReceive(const MyMessage & message) {
 */
 #if MODULE_SHT21 == 1
 // contructor
-SensorSHT21::SensorSHT21(int child_id, int sensor_type): Sensor(child_id,A2) {
+SensorSHT21::SensorSHT21(NodeManager* node_manager, int child_id, int sensor_type): Sensor(node_manager,child_id,A2) {
   // store the sensor type (0: temperature, 1: humidity)
   _sensor_type = sensor_type;
   if (_sensor_type == SensorSHT21::TEMPERATURE) {
@@ -1145,14 +1146,14 @@ void SensorSHT21::onReceive(const MyMessage & message) {
  */
  #if MODULE_SHT21 == 1
 // constructor
-SensorHTU21D::SensorHTU21D(int child_id, int pin): SensorSHT21(child_id, pin) {
+SensorHTU21D::SensorHTU21D(NodeManager* node_manager, int child_id, int pin): SensorSHT21(node_manager, child_id, pin) {
 }
 #endif 
 
 /*
  * SensorSwitch
  */
-SensorSwitch::SensorSwitch(int child_id, int pin): Sensor(child_id,pin) {
+SensorSwitch::SensorSwitch(NodeManager* node_manager, int child_id, int pin): Sensor(node_manager,child_id,pin) {
   setType(V_TRIPPED);
 }
 
@@ -1219,14 +1220,14 @@ void SensorSwitch::onReceive(const MyMessage & message) {
 /*
  * SensorDoor
  */
-SensorDoor::SensorDoor(int child_id, int pin): SensorSwitch(child_id,pin) {
+SensorDoor::SensorDoor(NodeManager* node_manager, int child_id, int pin): SensorSwitch(node_manager,child_id,pin) {
   setPresentation(S_DOOR);
 }
 
 /*
  * SensorMotion
  */
-SensorMotion::SensorMotion(int child_id, int pin): SensorSwitch(child_id,pin) {
+SensorMotion::SensorMotion(NodeManager* node_manager, int child_id, int pin): SensorSwitch(node_manager, child_id,pin) {
   setPresentation(S_MOTION);
   // capture only when it triggers
   setMode(RISING);
@@ -1239,7 +1240,7 @@ SensorMotion::SensorMotion(int child_id, int pin): SensorSwitch(child_id,pin) {
 */
 #if MODULE_DS18B20 == 1
 // contructor
-SensorDs18b20::SensorDs18b20(int child_id, int pin, DallasTemperature* sensors, int index): Sensor(child_id, pin) {
+SensorDs18b20::SensorDs18b20(NodeManager* node_manager, int child_id, int pin, DallasTemperature* sensors, int index): Sensor(node_manager,child_id, pin) {
   setPresentation(S_TEMP);
   setType(V_TEMP);
   setValueType(TYPE_FLOAT);
@@ -1314,7 +1315,7 @@ void SensorDs18b20::setSleepDuringConversion(bool value) {
 */
 #if MODULE_BH1750 == 1
 // contructor
-SensorBH1750::SensorBH1750(int child_id): Sensor(child_id,A4) {
+SensorBH1750::SensorBH1750(NodeManager* node_manager, int child_id): Sensor(node_manager,child_id,A4) {
   setPresentation(S_LIGHT_LEVEL);
   setType(V_LEVEL);
   _lightSensor = new BH1750();
@@ -1352,7 +1353,7 @@ void SensorBH1750::onReceive(const MyMessage & message) {
 */
 #if MODULE_MLX90614 == 1
 // contructor
-SensorMLX90614::SensorMLX90614(int child_id, Adafruit_MLX90614* mlx, int sensor_type): Sensor(child_id,A4) {
+SensorMLX90614::SensorMLX90614(NodeManager* node_manager, int child_id, Adafruit_MLX90614* mlx, int sensor_type): Sensor(node_manager,child_id,A4) {
   _sensor_type = sensor_type;
   _mlx = mlx;
   // set presentation and type
@@ -1397,7 +1398,7 @@ void SensorMLX90614::onReceive(const MyMessage & message) {
 */
 #if MODULE_BME280 == 1 || MODULE_BMP085 == 1
 // contructor
-SensorBosch::SensorBosch(int child_id, int sensor_type): Sensor(child_id,A4) {
+SensorBosch::SensorBosch(NodeManager* node_manager, int child_id, int sensor_type): Sensor(node_manager, child_id,A4) {
   _sensor_type = sensor_type;
   if (_sensor_type == SensorBosch::TEMPERATURE) {
     // temperature sensor
@@ -1562,7 +1563,7 @@ uint8_t SensorBosch::GetI2CAddress(uint8_t chip_id) {
  * SensorBME280
  */
 #if MODULE_BME280 == 1
-SensorBME280::SensorBME280(int child_id, Adafruit_BME280* bme, int sensor_type): SensorBosch(child_id,sensor_type) {
+SensorBME280::SensorBME280(NodeManager* node_manager, int child_id, Adafruit_BME280* bme, int sensor_type): SensorBosch(node_manager, child_id,sensor_type) {
   _bme = bme;
 }
 
@@ -1625,7 +1626,7 @@ void SensorBME280::onLoop() {
 */
 #if MODULE_BMP085 == 1
 // contructor
-SensorBMP085::SensorBMP085(int child_id, Adafruit_BMP085* bmp, int sensor_type): SensorBosch(child_id,sensor_type) {
+SensorBMP085::SensorBMP085(NodeManager* node_manager, int child_id, Adafruit_BMP085* bmp, int sensor_type): SensorBosch(node_manager, child_id,sensor_type) {
   _bmp = bmp;
 }
 
@@ -1675,7 +1676,7 @@ void SensorBMP085::onLoop() {
 */
 #if MODULE_SONOFF == 1
 // contructor
-SensorSonoff::SensorSonoff(int child_id): Sensor(child_id,1) {
+SensorSonoff::SensorSonoff(NodeManager* node_manager, int child_id): Sensor(node_manager, child_id,1) {
   setPresentation(S_BINARY);
   setType(V_STATUS);
 }
@@ -1775,7 +1776,7 @@ void SensorSonoff::_blink() {
 */
 #if MODULE_HCSR04 == 1
 // contructor
-SensorHCSR04::SensorHCSR04(int child_id, int pin): Sensor(child_id, pin) {
+SensorHCSR04::SensorHCSR04(NodeManager* node_manager, int child_id, int pin): Sensor(node_manager, child_id, pin) {
   // set presentation and type
   setPresentation(S_DISTANCE);
   setType(V_DISTANCE);
@@ -1827,7 +1828,7 @@ void SensorHCSR04::onReceive(const MyMessage & message) {
 */
 #if MODULE_MCP9808 == 1
 // contructor
-SensorMCP9808::SensorMCP9808(int child_id, Adafruit_MCP9808* mcp): Sensor(child_id,A2) {
+SensorMCP9808::SensorMCP9808(NodeManager* node_manager, int child_id, Adafruit_MCP9808* mcp): Sensor(node_manager, child_id,A2) {
   _mcp = mcp;
   setPresentation(S_TEMP);
   setType(V_TEMP);
@@ -1958,49 +1959,49 @@ int NodeManager::registerSensor(int sensor_type, int pin, int child_id) {
   // based on the given sensor type instantiate the appropriate class
   if (sensor_type == 0) return -1;
   #if MODULE_ANALOG_INPUT == 1
-    else if (sensor_type == SENSOR_ANALOG_INPUT) return registerSensor(new SensorAnalogInput(child_id, pin));
-    else if (sensor_type == SENSOR_LDR) return registerSensor(new SensorLDR(child_id, pin));
-    else if (sensor_type == SENSOR_THERMISTOR) return registerSensor(new SensorThermistor(child_id, pin));
-    else if (sensor_type == SENSOR_MQ) return registerSensor(new SensorMQ(child_id, pin));
-    else if (sensor_type == SENSOR_ML8511) return registerSensor(new SensorML8511(child_id, pin));
-    else if (sensor_type == SENSOR_ACS712) return registerSensor(new SensorACS712(child_id, pin));
-    else if (sensor_type == SENSOR_RAIN_GAUGE) return registerSensor(new SensorRainGauge(child_id, pin));
-    else if (sensor_type == SENSOR_RAIN) return registerSensor(new SensorRain(child_id, pin));
-    else if (sensor_type == SENSOR_SOIL_MOISTURE) return registerSensor(new SensorSoilMoisture(child_id, pin));
+    else if (sensor_type == SENSOR_ANALOG_INPUT) return registerSensor(new SensorAnalogInput(this,child_id, pin));
+    else if (sensor_type == SENSOR_LDR) return registerSensor(new SensorLDR(this,child_id, pin));
+    else if (sensor_type == SENSOR_THERMISTOR) return registerSensor(new SensorThermistor(this,child_id, pin));
+    else if (sensor_type == SENSOR_MQ) return registerSensor(new SensorMQ(this,child_id, pin));
+    else if (sensor_type == SENSOR_ML8511) return registerSensor(new SensorML8511(this,child_id, pin));
+    else if (sensor_type == SENSOR_ACS712) return registerSensor(new SensorACS712(this,child_id, pin));
+    else if (sensor_type == SENSOR_RAIN_GAUGE) return registerSensor(new SensorRainGauge(this,child_id, pin));
+    else if (sensor_type == SENSOR_RAIN) return registerSensor(new SensorRain(this,child_id, pin));
+    else if (sensor_type == SENSOR_SOIL_MOISTURE) return registerSensor(new SensorSoilMoisture(this,child_id, pin));
   #endif
   #if MODULE_DIGITAL_INPUT == 1
-    else if (sensor_type == SENSOR_DIGITAL_INPUT) return registerSensor(new SensorDigitalInput(child_id, pin));
+    else if (sensor_type == SENSOR_DIGITAL_INPUT) return registerSensor(new SensorDigitalInput(this,child_id, pin));
   #endif
   #if MODULE_DIGITAL_OUTPUT == 1
-    else if (sensor_type == SENSOR_DIGITAL_OUTPUT) return registerSensor(new SensorDigitalOutput(child_id, pin));
-    else if (sensor_type == SENSOR_RELAY) return registerSensor(new SensorRelay(child_id, pin));
-    else if (sensor_type == SENSOR_LATCHING_RELAY) return registerSensor(new SensorLatchingRelay(child_id, pin));
+    else if (sensor_type == SENSOR_DIGITAL_OUTPUT) return registerSensor(new SensorDigitalOutput(this,child_id, pin));
+    else if (sensor_type == SENSOR_RELAY) return registerSensor(new SensorRelay(this,child_id, pin));
+    else if (sensor_type == SENSOR_LATCHING_RELAY) return registerSensor(new SensorLatchingRelay(this,child_id, pin));
   #endif
   #if MODULE_DHT == 1
     else if (sensor_type == SENSOR_DHT11 || sensor_type == SENSOR_DHT22) {
       int dht_type = sensor_type == SENSOR_DHT11 ? DHT11 : DHT22;
       DHT* dht = new DHT(pin,dht_type);
       // register temperature sensor
-      registerSensor(new SensorDHT(child_id,pin,dht,SensorDHT::TEMPERATURE,dht_type));
+      registerSensor(new SensorDHT(this,child_id,pin,dht,SensorDHT::TEMPERATURE,dht_type));
       // register humidity sensor
       child_id = _getAvailableChildId();
-      return registerSensor(new SensorDHT(child_id,pin,dht,SensorDHT::HUMIDITY,dht_type));
+      return registerSensor(new SensorDHT(this,child_id,pin,dht,SensorDHT::HUMIDITY,dht_type));
     }
   #endif
   #if MODULE_SHT21 == 1
     else if (sensor_type == SENSOR_SHT21) {
       // register temperature sensor
-      registerSensor(new SensorSHT21(child_id,SensorSHT21::TEMPERATURE));
+      registerSensor(new SensorSHT21(this,child_id,SensorSHT21::TEMPERATURE));
       // register humidity sensor
       child_id = _getAvailableChildId();
-      return registerSensor(new SensorSHT21(child_id,SensorSHT21::HUMIDITY));
+      return registerSensor(new SensorSHT21(this,child_id,SensorSHT21::HUMIDITY));
     }
     else if (sensor_type == SENSOR_HTU21D) {
       // register temperature sensor
-      registerSensor(new SensorHTU21D(child_id,SensorHTU21D::TEMPERATURE));
+      registerSensor(new SensorHTU21D(this,child_id,SensorHTU21D::TEMPERATURE));
       // register humidity sensor
       child_id = _getAvailableChildId();
-      return registerSensor(new SensorHTU21D(child_id,SensorHTU21D::HUMIDITY));
+      return registerSensor(new SensorHTU21D(this,child_id,SensorHTU21D::HUMIDITY));
     }
   #endif
   #if MODULE_SWITCH == 1
@@ -2009,9 +2010,9 @@ int NodeManager::registerSensor(int sensor_type, int pin, int child_id) {
       if (pin != INTERRUPT_PIN_1 && pin != INTERRUPT_PIN_2) return -1;
       // register the sensor
       int index = 0;
-      if (sensor_type == SENSOR_SWITCH) index = registerSensor(new SensorSwitch(child_id, pin));
-      else if (sensor_type == SENSOR_DOOR) index = registerSensor(new SensorDoor(child_id, pin));
-      else if (sensor_type == SENSOR_MOTION) index = registerSensor(new SensorMotion(child_id, pin));
+      if (sensor_type == SENSOR_SWITCH) index = registerSensor(new SensorSwitch(this,child_id, pin));
+      else if (sensor_type == SENSOR_DOOR) index = registerSensor(new SensorDoor(this,child_id, pin));
+      else if (sensor_type == SENSOR_MOTION) index = registerSensor(new SensorMotion(this,child_id, pin));
       // set an interrupt on the pin and set the initial value
       SensorSwitch* sensor = (SensorSwitch*)getSensor(index);
       sensor->setInterruptPin(pin);
@@ -2030,24 +2031,24 @@ int NodeManager::registerSensor(int sensor_type, int pin, int child_id) {
       // register a new child for each sensor on the bus
       for(int i = 0; i < sensors->getDeviceCount(); i++) {
         if (i > 0) child_id = _getAvailableChildId();
-        index = registerSensor(new SensorDs18b20(child_id,pin,sensors,i));
+        index = registerSensor(new SensorDs18b20(this,child_id,pin,sensors,i));
       }
       return index;
     }
   #endif
   #if MODULE_BH1750 == 1
     else if (sensor_type == SENSOR_BH1750) {
-      return registerSensor(new SensorBH1750(child_id));
+      return registerSensor(new SensorBH1750(this,child_id));
     }
   #endif
   #if MODULE_MLX90614 == 1
     else if (sensor_type == SENSOR_MLX90614) {
       Adafruit_MLX90614* mlx = new Adafruit_MLX90614();
       // register ambient temperature sensor
-      registerSensor(new SensorMLX90614(child_id,mlx,SensorMLX90614::TEMPERATURE_AMBIENT));
+      registerSensor(new SensorMLX90614(this,child_id,mlx,SensorMLX90614::TEMPERATURE_AMBIENT));
       // register object temperature sensor
       child_id = _getAvailableChildId();
-      return registerSensor(new SensorMLX90614(child_id,mlx,SensorMLX90614::TEMPERATURE_OBJECT));
+      return registerSensor(new SensorMLX90614(this,child_id,mlx,SensorMLX90614::TEMPERATURE_OBJECT));
     }
   #endif
   #if MODULE_BME280 == 1
@@ -2060,21 +2061,21 @@ int NodeManager::registerSensor(int sensor_type, int pin, int child_id) {
         return -1;
       }
       // register temperature sensor
-      registerSensor(new SensorBME280(child_id,bme,SensorBME280::TEMPERATURE));
+      registerSensor(new SensorBME280(this,child_id,bme,SensorBME280::TEMPERATURE));
       child_id = _getAvailableChildId();
       // register humidity sensor
-      registerSensor(new SensorBME280(child_id,bme,SensorBME280::HUMIDITY));
+      registerSensor(new SensorBME280(this,child_id,bme,SensorBME280::HUMIDITY));
       // register pressure sensor
       child_id = _getAvailableChildId();
-      registerSensor(new SensorBME280(child_id,bme,SensorBME280::PRESSURE));
+      registerSensor(new SensorBME280(this,child_id,bme,SensorBME280::PRESSURE));
       // register forecast sensor
       child_id = _getAvailableChildId();
-      return registerSensor(new SensorBME280(child_id,bme,SensorBME280::FORECAST));
+      return registerSensor(new SensorBME280(this,child_id,bme,SensorBME280::FORECAST));
     }
   #endif
   #if MODULE_SONOFF == 1
     else if (sensor_type == SENSOR_SONOFF) {
-      return registerSensor(new SensorSonoff(child_id));
+      return registerSensor(new SensorSonoff(this,child_id));
     }
   #endif
   #if MODULE_BMP085 == 1
@@ -2087,18 +2088,18 @@ int NodeManager::registerSensor(int sensor_type, int pin, int child_id) {
         return -1;
       }
       // register temperature sensor
-      registerSensor(new SensorBMP085(child_id,bmp,SensorBMP085::TEMPERATURE));
+      registerSensor(new SensorBMP085(this,child_id,bmp,SensorBMP085::TEMPERATURE));
       // register pressure sensor
       child_id = _getAvailableChildId();
-      registerSensor(new SensorBMP085(child_id,bmp,SensorBMP085::PRESSURE));
+      registerSensor(new SensorBMP085(this,child_id,bmp,SensorBMP085::PRESSURE));
       // register forecast sensor
       child_id = _getAvailableChildId();
-      return registerSensor(new SensorBMP085(child_id,bmp,SensorBMP085::FORECAST));
+      return registerSensor(new SensorBMP085(this,child_id,bmp,SensorBMP085::FORECAST));
     }
   #endif
   #if MODULE_HCSR04 == 1
     else if (sensor_type == SENSOR_HCSR04) {
-      return registerSensor(new SensorHCSR04(child_id, pin));
+      return registerSensor(new SensorHCSR04(this,child_id, pin));
     }
   #endif
   #if MODULE_MCP9808 == 1
@@ -2111,7 +2112,7 @@ int NodeManager::registerSensor(int sensor_type, int pin, int child_id) {
         return -1;
       }
       // register temperature sensor
-      registerSensor(new SensorMCP9808(child_id,mcp));
+      registerSensor(new SensorMCP9808(this,child_id,mcp));
     }
   #endif
   else {
diff --git a/NodeManager.h b/NodeManager.h
index 33b5bfb..9da4318 100644
--- a/NodeManager.h
+++ b/NodeManager.h
@@ -302,6 +302,7 @@ enum supported_sensors {
 /**************************************
    Classes
 */
+class NodeManager;
 
 /*
    PowerManager
@@ -328,7 +329,7 @@ class PowerManager {
 */
 class Sensor {
   public:
-    Sensor(int child_id, int pin);
+    Sensor(NodeManager* node_manager, int child_id, int pin);
     // where the sensor is attached to (default: not set)
     void setPin(int value);
     int getPin();
@@ -392,6 +393,7 @@ class Sensor {
     virtual void onReceive(const MyMessage & message) = 0;
   protected:
     MyMessage _msg;
+    NodeManager* _node_manager;
     int _sleep_between_send = 0;
     int _pin = -1;
     int _child_id;
@@ -426,7 +428,7 @@ class Sensor {
 */
 class SensorAnalogInput: public Sensor {
   public:
-    SensorAnalogInput(int child_id, int pin);
+    SensorAnalogInput(NodeManager* node_manager, int child_id, int pin);
     // the analog reference to use (default: not set, can be either INTERNAL or DEFAULT)
     void setReference(int value);
     // reverse the value or the percentage (e.g. 70% -> 30%) (default: false)
@@ -457,7 +459,7 @@ class SensorAnalogInput: public Sensor {
 */
 class SensorLDR: public SensorAnalogInput {
   public:
-    SensorLDR(int child_id, int pin);
+    SensorLDR(NodeManager* node_manager, int child_id, int pin);
 };
 
 /*
@@ -465,7 +467,7 @@ class SensorLDR: public SensorAnalogInput {
 */
 class SensorThermistor: public Sensor {
   public:
-    SensorThermistor(int child_id, int pin);
+    SensorThermistor(NodeManager* node_manager, int child_id, int pin);
     // resistance at 25 degrees C (default: 10000)
     void setNominalResistor(long value);
     // temperature for nominal resistance (default: 25)
@@ -494,7 +496,7 @@ class SensorThermistor: public Sensor {
  */
 class SensorMQ: public Sensor {
   public:
-    SensorMQ(int child_id, int pin);
+    SensorMQ(NodeManager* node_manager, int child_id, int pin);
     // define the target gas whose ppm has to be returned. 0: LPG, 1: CO, 2: Smoke (default: 1);
     void setTargetGas(int value);
     // define the load resistance on the board, in kilo ohms (default: 1);
@@ -550,7 +552,7 @@ class SensorMQ: public Sensor {
 
 class SensorML8511: public Sensor {
   public:
-    SensorML8511(int child_id, int pin);
+    SensorML8511(NodeManager* node_manager, int child_id, int pin);
     // define what to do at each stage of the sketch
     void onBefore();
     void onSetup();
@@ -566,7 +568,7 @@ class SensorML8511: public Sensor {
 
 class SensorACS712: public Sensor {
   public:
-    SensorACS712(int child_id, int pin);
+    SensorACS712(NodeManager* node_manager, int child_id, int pin);
     // set how many mV are equivalent to 1 Amp. The value depends on the module (100 for 20A Module, 66 for 30A Module) (default: 185);
     void setmVPerAmp(int value);
     // set ACS offset (default: 2500);
@@ -587,7 +589,7 @@ class SensorACS712: public Sensor {
 
 class SensorRainGauge: public Sensor {
   public:
-    SensorRainGauge(int child_id, int pin);
+    SensorRainGauge(NodeManager* node_manager, int child_id, int pin);
     // set how frequently to report back to the controller in minutes. After reporting the measure is resetted (default: 60);
     void setReportInterval(int value);
     // set how many mm of rain to count for each tip (default: 0.11);
@@ -612,7 +614,7 @@ class SensorRainGauge: public Sensor {
 */
 class SensorRain: public SensorAnalogInput {
   public:
-    SensorRain(int child_id, int pin);
+    SensorRain(NodeManager* node_manager, int child_id, int pin);
 };
 
 /*
@@ -620,7 +622,7 @@ class SensorRain: public SensorAnalogInput {
 */
 class SensorSoilMoisture: public SensorAnalogInput {
   public:
-    SensorSoilMoisture(int child_id, int pin);
+    SensorSoilMoisture(NodeManager* node_manager, int child_id, int pin);
 };
 
 /*
@@ -628,7 +630,7 @@ class SensorSoilMoisture: public SensorAnalogInput {
 */
 class SensorDigitalInput: public Sensor {
   public:
-    SensorDigitalInput(int child_id, int pin);
+    SensorDigitalInput(NodeManager* node_manager, int child_id, int pin);
     // define what to do at each stage of the sketch
     void onBefore();
     void onSetup();
@@ -641,7 +643,7 @@ class SensorDigitalInput: public Sensor {
 */
 class SensorDigitalOutput: public Sensor {
   public:
-    SensorDigitalOutput(int child_id, int pin);
+    SensorDigitalOutput(NodeManager* node_manager, int child_id, int pin);
     // set how to initialize the output (default: LOW)
     void setInitialValue(int value);
     // if greater than 0, send a pulse of the given duration in ms and then restore the output back to the original value (default: 0)
@@ -669,7 +671,7 @@ class SensorDigitalOutput: public Sensor {
 */
 class SensorRelay: public SensorDigitalOutput {
   public:
-    SensorRelay(int child_id, int pin);
+    SensorRelay(NodeManager* node_manager, int child_id, int pin);
     // define what to do at each stage of the sketch
     void onLoop();
 };
@@ -679,7 +681,7 @@ class SensorRelay: public SensorDigitalOutput {
 */
 class SensorLatchingRelay: public SensorRelay {
   public:
-    SensorLatchingRelay(int child_id, int pin);
+    SensorLatchingRelay(NodeManager* node_manager, int child_id, int pin);
 };
 
 /*
@@ -688,7 +690,7 @@ class SensorLatchingRelay: public SensorRelay {
 #if MODULE_DHT == 1
 class SensorDHT: public Sensor {
   public:
-    SensorDHT(int child_id, int pin, DHT* dht, int sensor_type, int dht_type);
+    SensorDHT(NodeManager* node_manager, int child_id, int pin, DHT* dht, int sensor_type, int dht_type);
     // define what to do at each stage of the sketch
     void onBefore();
     void onSetup();
@@ -711,7 +713,7 @@ class SensorDHT: public Sensor {
 #if MODULE_SHT21 == 1
 class SensorSHT21: public Sensor {
   public:
-    SensorSHT21(int child_id, int sensor_type);
+    SensorSHT21(NodeManager* node_manager, int child_id, int sensor_type);
     // define what to do at each stage of the sketch
     void onBefore();
     void onSetup();
@@ -731,7 +733,7 @@ class SensorSHT21: public Sensor {
 
 class SensorHTU21D: public SensorSHT21 {
   public:
-    SensorHTU21D(int child_id, int pin);
+    SensorHTU21D(NodeManager* node_manager, int child_id, int pin);
 };
 #endif
 
@@ -740,7 +742,7 @@ class SensorHTU21D: public SensorSHT21 {
  */
 class SensorSwitch: public Sensor {
   public:
-    SensorSwitch(int child_id, int pin);
+    SensorSwitch(NodeManager* node_manager, int child_id, int pin);
     // set the interrupt mode. Can be CHANGE, RISING, FALLING (default: CHANGE)
     void setMode(int value);
     int getMode();
@@ -768,7 +770,7 @@ class SensorSwitch: public Sensor {
  */
 class SensorDoor: public SensorSwitch {
   public:
-    SensorDoor(int child_id, int pin);
+    SensorDoor(NodeManager* node_manager, int child_id, int pin);
 };
 
 /*
@@ -776,7 +778,7 @@ class SensorDoor: public SensorSwitch {
  */
 class SensorMotion: public SensorSwitch {
   public:
-    SensorMotion(int child_id, int pin);
+    SensorMotion(NodeManager* node_manager, int child_id, int pin);
 };
 
 /*
@@ -785,7 +787,7 @@ class SensorMotion: public SensorSwitch {
 #if MODULE_DS18B20 == 1
 class SensorDs18b20: public Sensor {
   public:
-    SensorDs18b20(int child_id, int pin, DallasTemperature* sensors, int index);
+    SensorDs18b20(NodeManager* node_manager, int child_id, int pin, DallasTemperature* sensors, int index);
     // return the sensors' device address
     DeviceAddress* getDeviceAddress();
     // returns the sensor's resolution in bits
@@ -814,7 +816,7 @@ class SensorDs18b20: public Sensor {
 #if MODULE_BH1750 == 1
 class SensorBH1750: public Sensor {
   public:
-    SensorBH1750(int child_id);
+    SensorBH1750(NodeManager* node_manager, int child_id);
     // define what to do at each stage of the sketch
     void onBefore();
     void onSetup();
@@ -831,7 +833,7 @@ class SensorBH1750: public Sensor {
 #if MODULE_MLX90614 == 1
 class SensorMLX90614: public Sensor {
   public:
-    SensorMLX90614(int child_id, Adafruit_MLX90614* mlx, int sensor_type);
+    SensorMLX90614(NodeManager* node_manager, int child_id, Adafruit_MLX90614* mlx, int sensor_type);
     // define what to do at each stage of the sketch
     void onBefore();
     void onSetup();
@@ -854,7 +856,7 @@ class SensorMLX90614: public Sensor {
 #if MODULE_BME280 == 1 || MODULE_BMP085 == 1
 class SensorBosch: public Sensor {
   public:
-    SensorBosch(int child_id, int sensor_type);
+    SensorBosch(NodeManager* node_manager, int child_id, int sensor_type);
     // define how many pressure samples to keep track of for calculating the forecast (default: 5)
     void setForecastSamplesCount(int value);
     // define what to do at each stage of the sketch
@@ -889,7 +891,7 @@ class SensorBosch: public Sensor {
 #if MODULE_BME280 == 1
 class SensorBME280: public SensorBosch {
   public:
-    SensorBME280(int child_id, Adafruit_BME280* bme, int sensor_type);
+    SensorBME280(NodeManager* node_manager, int child_id, Adafruit_BME280* bme, int sensor_type);
     void onLoop();
   protected:
     Adafruit_BME280* _bme;
@@ -902,7 +904,7 @@ class SensorBME280: public SensorBosch {
 #if MODULE_BMP085 == 1
 class SensorBMP085: public SensorBosch {
   public:
-    SensorBMP085(int child_id, Adafruit_BMP085* bmp, int sensor_type);
+    SensorBMP085(NodeManager* node_manager, int child_id, Adafruit_BMP085* bmp, int sensor_type);
     void onLoop();
   protected:
     Adafruit_BMP085* _bmp;
@@ -915,7 +917,7 @@ class SensorBMP085: public SensorBosch {
 #if MODULE_HCSR04 == 1
 class SensorHCSR04: public Sensor {
   public:
-    SensorHCSR04(int child_id, int pin);
+    SensorHCSR04(NodeManager* node_manager, int child_id, int pin);
     // Arduino pin tied to trigger pin on the ultrasonic sensor (default: the pin set while registering the sensor)
     void setTriggerPin(int value);
     // Arduino pin tied to echo pin on the ultrasonic sensor (default: the pin set while registering the sensor)
@@ -941,7 +943,7 @@ class SensorHCSR04: public Sensor {
 #if MODULE_SONOFF == 1
 class SensorSonoff: public Sensor {
   public:
-    SensorSonoff(int child_id);
+    SensorSonoff(NodeManager* node_manager, int child_id);
     // set the button's pin (default: 0)
     void setButtonPin(int value);
     // set the relay's pin (default: 12)
@@ -975,7 +977,7 @@ class SensorSonoff: public Sensor {
 #if MODULE_MCP9808 == 1
 class SensorMCP9808: public Sensor {
   public:
-    SensorMCP9808(int child_id, Adafruit_MCP9808* mcp);
+    SensorMCP9808(NodeManager* node_manager, int child_id, Adafruit_MCP9808* mcp);
     // define what to do at each stage of the sketch
     void onBefore();
     void onSetup();
diff --git a/README.md b/README.md
index 1eaba15..22eb60c 100644
--- a/README.md
+++ b/README.md
@@ -310,7 +310,7 @@ When called, registerSensor returns the child_id of the sensor so you will be ab
 
 #### Creating a custom sensor
 
-If you want to create a custom sensor and register it with NodeManager so it can take care of all the common tasks, you can create a class inheriting from `Sensor` and implement the following methods:
+If you want to create a custom sensor and register it with NodeManager so it can take care of all the common tasks, you can create an inline class inheriting from `Sensor` or other subclasses and implement the following methods:
 ~~~c
     // define what to do during before() to setup the sensor
     void onBefore();
@@ -324,7 +324,7 @@ If you want to create a custom sensor and register it with NodeManager so it can
 
 You can then instantiate your newly created class and register with NodeManager:
 ~~~c
-	nodeManager.registerSensor(new SensorCustom(child_id, pin));
+	nodeManager.registerSensor(new SensorCustom(&nodeManager,child_id, pin));
 ~~~
 
 ### Configuring the sensors
@@ -397,7 +397,7 @@ The following methods are available for all the sensors:
 
 Each sensor class can expose additional methods.
 
-** SensorAnalogInput / SensorLDR / SensorRain / SensorSoilMoisture **
+* SensorAnalogInput / SensorLDR / SensorRain / SensorSoilMoisture *
 ~~~c
     // the analog reference to use (default: not set, can be either INTERNAL or DEFAULT)
     void setReference(int value);
@@ -411,7 +411,7 @@ Each sensor class can expose additional methods.
     void setRangeMax(int value);
 ~~~
 
-** SensorThermistor **
+* SensorThermistor *
 ~~~c
     // resistance at 25 degrees C (default: 10000)
     void setNominalResistor(long value);
@@ -425,7 +425,7 @@ Each sensor class can expose additional methods.
     void setOffset(float value);
 ~~~
 
-** SensorMQ **
+* SensorMQ *
 ~~~c
     // define the target gas whose ppm has to be returned. 0: LPG, 1: CO, 2: Smoke (default: 1);
     void setTargetGas(int value);
@@ -451,7 +451,7 @@ Each sensor class can expose additional methods.
     void setSmokeCurve(float *value);
 ~~~
 
-** SensorDigitalOutput / SensorRelay / SensorLatchingRelay ** 
+* SensorDigitalOutput / SensorRelay / SensorLatchingRelay * 
 ~~~c
     // set how to initialize the output (default: LOW)
     void setInitialValue(int value);
@@ -463,7 +463,7 @@ Each sensor class can expose additional methods.
     void setLegacyMode(bool value);
 ~~~
 
-**  SensorSwitch / SensorDoor / SensorMotion **
+*  SensorSwitch / SensorDoor / SensorMotion *
 ~~~c
     // set the interrupt mode. Can be CHANGE, RISING, FALLING (default: CHANGE)
     void setMode(int value);
@@ -475,7 +475,7 @@ Each sensor class can expose additional methods.
     void setInitial(int value);
 ~~~
 
-**  SensorDs18b20**
+*  SensorDs18b20**
 ~~~c
     // return the sensors' device address
     DeviceAddress* getDeviceAddress();
@@ -487,13 +487,13 @@ Each sensor class can expose additional methods.
     void setSleepDuringConversion(bool value);
 ~~~
 
-**  SensorBME280 **
+*  SensorBME280 *
 ~~~c
     // define how many pressure samples to keep track of for calculating the forecast (default: 5)
     void setForecastSamplesCount(int value);
 ~~~
 
-**  SensorSonoff **
+*  SensorSonoff *
 ~~~c
     // set the button's pin (default: 0)
     void setButtonPin(int value);
@@ -503,13 +503,13 @@ Each sensor class can expose additional methods.
     void setLedPin(int value);
 ~~~
 
-** SensorBMP085 **
+* SensorBMP085 *
 ~~~c
     // define how many pressure samples to keep track of for calculating the forecast (default: 5)
     void setForecastSamplesCount(int value);
 ~~~
 
-** SensorHCSR04 **
+* SensorHCSR04 *
 ~~~c
     // Arduino pin tied to trigger pin on the ultrasonic sensor (default: the pin set while registering the sensor)
     void setTriggerPin(int value);
@@ -519,7 +519,7 @@ Each sensor class can expose additional methods.
     void setMaxDistance(int value);
 ~~~
 
-** SensorACS712 **
+* SensorACS712 *
 ~~~c
     // set how many mV are equivalent to 1 Amp. The value depends on the module (100 for 20A Module, 66 for 30A Module) (default: 185);
     void setmVPerAmp(int value);
@@ -527,7 +527,7 @@ Each sensor class can expose additional methods.
     void setOffset(int value);
 ~~~
 
-** SensorRainGauge **
+* SensorRainGauge *
 ~~~c
     // set how frequently to report back to the controller in minutes. After reporting the measure is resetted (default: 60);
     void setReportInterval(int value);
@@ -594,38 +594,38 @@ If `PERSIST` is enabled, the settings provided with `INTVLnnnX` and `MODEx` are
 
 A NodeManager object must be created and called from within your sketch during `before()`, `presentation()`, `loop()` and `receive()` to work properly. NodeManager will do the following during each phase:
 
-** NodeManager::before() **
+* NodeManager::before() *
 * Setup the interrupt pins to wake up the board based on the configured interrupts (e.g. stop sleeping when the pin is connected to ground or wake up and notify when a motion sensor has trigger)
 * If persistance is enabled, restore from the EEPROM the latest sleeping settings
 * Call `before()` of each registered sensor
 
-**  Sensor::before() **
+*  Sensor::before() *
 * Call sensor-specific implementation of before by invoking `onBefore()` to initialize the sensor
 
-**  NodeManager::setup() ** 
+*  NodeManager::setup() * 
 * Send a custom message with a STARTED payload to the controller
 * Call `setup()` of each registered sensor
 
-**  Sensor::setup() ** 
+*  Sensor::setup() * 
 * Call sensor-specific implementation of setup by invoking `onSetup()` to initialize the sensor
 
-**  NodeManager::loop() ** 
+*  NodeManager::loop() * 
 * If all the sensors are powered by an arduino pin, this is set to HIGH
 * Call `loop()` of each registered sensor
 * If all the sensors are powered by an arduino pin, this is set to LOW
 
-**  Sensor::loop() ** 
+*  Sensor::loop() * 
 * If the sensor is powered by an arduino pin, this is set to HIGH
 * For each registered sensor, the sensor-specific `onLoop()` is called. If multiple samples are requested, this is run multiple times.
 * In case multiple samples have been collected, the average is calculated
 * A message is sent to the gateway with the calculated value. Depending on the configuration, this is not sent if it is the same as the previous value or sent anyway after a given number of cycles. These functionalies are not sensor-specific and common to all the sensors inheriting from the `Sensor` class.
 * If the sensor is powered by an arduino pin, this is set to LOW
 
-**  NodeManager::receive() ** 
+*  NodeManager::receive() * 
 * Receive a message from the radio network 
 * If the destination child id is the configuration node, it will handle the incoming message, otherwise will dispatch the message to the recipient sensor
 
-**  Sensor::receive() ** 
+*  Sensor::receive() * 
 * Invoke `Sensor::loop()` which will execute the sensor main taks and eventually call `Sensor::onReceive()`
 
 ## Examples
@@ -698,7 +698,7 @@ Register a latching relay connecting to pin 6 (set) and pin 7 (unset):
 
 ## Example Sketches
 
-**  Analog Light and Temperature Sensor ** 
+*  Analog Light and Temperature Sensor * 
 
 The following sketch can be used to report the temperature and the light level based on a thermistor and LDR sensors attached to two analog pins of the arduino board (A1 and A2). Both the thermistor and the LDR are connected to ground on one side and to vcc via a resistor on the other so to measure the voltage drop across each of them through the analog pins. 
 
@@ -749,8 +749,6 @@ void before() {
 
 // presentation
 void presentation() {
-  // Send the sketch version information to the gateway and Controller
-	sendSketchInfo(SKETCH_NAME,SKETCH_VERSION);
   // call NodeManager presentation routine
   nodeManager.presentation();
 
@@ -774,9 +772,15 @@ void receive(const MyMessage &message) {
   // call NodeManager receive routine
   nodeManager.receive(message);
 }
+
+// receiveTime
+void receiveTime(unsigned long ts) {
+  // call NodeManager receiveTime routine
+  nodeManager.receiveTime(ts);
+}
 ~~~
 
-**  Motion Sensor ** 
+*  Motion Sensor * 
 
 The following sketch can be used to report back to the controller when a motion sensor attached to the board's pin 3 triggers. In this example, the board will be put to sleep just after startup and will report a heartbeat every hour. NodeManager will take care of configuring an interrupt associated to the provided pin so automatically wake up when a motion is detected and report a V_TRIPPED message back. This sketch requires MODULE_SWITCH to be enabled in the global config.h file.
 
@@ -797,6 +801,10 @@ Documentation available on: https://github.com/mysensors/NodeManager
  
 // load user settings
 #include "config.h"
+// include supporting libraries
+#ifdef MY_GATEWAY_ESP8266
+  #include <ESP8266WiFi.h>
+#endif
 // load MySensors library
 #include <MySensors.h>
 // load NodeManager library
@@ -823,8 +831,6 @@ void before() {
 
 // presentation
 void presentation() {
-  // Send the sketch version information to the gateway and Controller
-	sendSketchInfo(SKETCH_NAME,SKETCH_VERSION);
   // call NodeManager presentation routine
   nodeManager.presentation();
 
@@ -848,9 +854,15 @@ void receive(const MyMessage &message) {
   // call NodeManager receive routine
   nodeManager.receive(message);
 }
+
+// receiveTime
+void receiveTime(unsigned long ts) {
+  // call NodeManager receiveTime routine
+  nodeManager.receiveTime(ts);
+}
 ~~~
 
-**  Boiler Sensor ** 
+*  Boiler Sensor * 
 
 The following sketch controls a latching relay connected to a boiler. A latching relay (requiring only a pulse to switch) has been chosen to minimize the power consumption required by a traditional relay to stay on. This relay has normally two pins, one for closing and the other for opening the controlled circuit, connected to pin 6 and 7 of the arduino board. This is why we have to register two sensors against NodeManager so to control the two funtions indipendently. Since using a SENSOR_LATCHING_RELAY type of sensor, NodeManager will take care of just sending out a single pulse only when a REQ command of type V_STATUS is sent to one or the other child id.
 
@@ -875,6 +887,10 @@ Documentation available on: https://github.com/mysensors/NodeManager
  
 // load user settings
 #include "config.h"
+// include supporting libraries
+#ifdef MY_GATEWAY_ESP8266
+  #include <ESP8266WiFi.h>
+#endif
 // load MySensors library
 #include <MySensors.h>
 // load NodeManager library
@@ -904,8 +920,6 @@ void before() {
 
 // presentation
 void presentation() {
-  // Send the sketch version information to the gateway and Controller
-	sendSketchInfo(SKETCH_NAME,SKETCH_VERSION);
   // call NodeManager presentation routine
   nodeManager.presentation();
 
@@ -929,10 +943,16 @@ void receive(const MyMessage &message) {
   // call NodeManager receive routine
   nodeManager.receive(message);
 }
+
+// receiveTime
+void receiveTime(unsigned long ts) {
+  // call NodeManager receiveTime routine
+  nodeManager.receiveTime(ts);
+}
 ~~~
 
 
-**  Rain and Soil Moisture Sensor ** 
+*  Rain and Soil Moisture Sensor * 
 
 The following sketch can be used to report the rain level and the soil moisture based on two sensors connected to the board's analog pins (A1 and A2). In this case we are customizing the out-of-the-box SENSOR_ANALOG_INPUT sensor type since we just need to measure an analog input but we also want to provide the correct type and presentation for each sensor. 
 
@@ -960,6 +980,10 @@ Documentation available on: https://github.com/mysensors/NodeManager
  
 // load user settings
 #include "config.h"
+// include supporting libraries
+#ifdef MY_GATEWAY_ESP8266
+  #include <ESP8266WiFi.h>
+#endif
 // load MySensors library
 #include <MySensors.h>
 // load NodeManager library
@@ -1008,8 +1032,6 @@ void before() {
 
 // presentation
 void presentation() {
-  // Send the sketch version information to the gateway and Controller
-	sendSketchInfo(SKETCH_NAME,SKETCH_VERSION);
   // call NodeManager presentation routine
   nodeManager.presentation();
 
@@ -1033,6 +1055,12 @@ void receive(const MyMessage &message) {
   // call NodeManager receive routine
   nodeManager.receive(message);
 }
+
+// receiveTime
+void receiveTime(unsigned long ts) {
+  // call NodeManager receiveTime routine
+  nodeManager.receiveTime(ts);
+}
 ~~~
 
 ## Contributing
@@ -1069,6 +1097,7 @@ Create a branch for the fix/feature you want to work on and apply changes to the
 * Fill in the request with a significant title and description and select the "development" branch from the main repository to be compared against your branch
 * Submit the request and start the discussion
 * Any additional commits to your branch which will be presented within the same pull request
+* When the pull request is merged, delete your working branch: `git branch -d <yourbranch>`
 
 If there are changes introduced to the development branch that conflicts with an open pull request, you will have to resolve the conflicts and update the PR:
 * Fetch and merge into development any change from upstream/development as detailed above
-- 
GitLab