I am having problem with a my HA and MySensors config and cannot get the Batter level reporting in HA alongside several child sensors.
My configuration is as follows:
I have an ESP8266 with NRF24l01 radio configured as a a MySensor gateway, this is relaying MySensor node information to my Hassbian setup which has MQTT installed.
My Sensor node is configured using an Arduino pro Mini, NRF24L01, DHT22 and a BH1750 lux sensor. The sensor node is assigned a Node id of 2.
so far so good…
I have configured my pro mini sketch to talk to the gateway and send Humidity, Temperature, Lux(light), Heat Index (temp) and Battery Level - each has a child assigned 1 thru 4 with the battery being an internal message.
MQTT and HA works well with ‘other’ non MySensor nodes
HA is configured to debug log mysensors
Now to the problems…
I can see data on MQTT by monitoring the relevant topics with MQTTfx - which shows that humidity, temp, lux and heat index are being sent - although HA is only picking up Humidity and Lux (child ids 1&3)
I cannot see on MQTT or within the HA logs any activity to do with they battery (sendBatteryLevel) although I do get the following in the Node Serial debug log
!TSF:MSG:SEND,2-2-0-0,s=255,c=3,t=0,pt=1,l=1,sg=0,ft=0,st=NACK:96
Can someone please check over my sketch below to ensure that I am not doing anything stupid or offer any ideas as to why I am seeing this behavior?
Thanks
#define MY_DEBUG true // Enable debug prints
#define MY_RADIO_NRF24 // Enable and select radio type attached
#define MY_NODE_ID 2 // Set the node ID manually - this must be set the mysensors.h call
#include <DHT_U.h>
#include <SPI.h>
#include <MySensors.h>
#include<Wire.h>
#include<BH1750.h>
BH1750 lightMeter(0x23); /* BH1750 can be physically configured to use two I2C addresses:
- 0x23 (most common) (if ADD pin had < 0.7VCC voltage)
- 0x5C (if ADD pin had > 0.7VCC voltage)
Library use 0x23 address as default, but you can define any other address.
If you had troubles with default value - try to change it to 0x5C.*/
#define DHTPIN 3 // DHT PIN MAP
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
#define SENSOR_TEMP_OFFSET 0.00 // Set this offset if the sensor has a permanent small offset to the real temperatures
static const uint64_t UPDATE_INTERVAL = 300000; // Sleep time between sensor updates (in milliseconds)
// Must be >1000ms for DHT22 and >2000ms for DHT11
static const uint8_t FORCE_UPDATE_N_READS = 2; // Force sending an update of the temperature after n sensor reads, so a controller showing the
// timestamp of the last update doesn't show something like 3 hours in the unlikely case, that
// the value didn't change since;
// i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms]
#define CHILD_ID_HUM 1
#define CHILD_ID_TEMP 2
#define CHILD_ID_LIGHT 3
#define CHILD_ID_HEATINDEX 4
#define CHILD_ID_BATTERY 5
float lastTemp;
float lastHum;
float lux; // Light meter lux level
uint8_t nNoUpdatesTemp;
uint8_t nNoUpdatesHum;
bool metric = true;
float hic_temp = 0;
int BATTERY_SENSE_PIN = A0; // Define battery sense pins
int oldBatteryPcnt = 0;
MyMessage msgHum(CHILD_ID_HUM, V_HUM);
MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
MyMessage msgLux(CHILD_ID_LIGHT, V_LEVEL);
MyMessage msgHeatIndex(CHILD_ID_HEATINDEX, V_TEMP);
//MyMessage msgBattery(CHILD_ID_BATTERY, V_VOLTAGE);
/*************************************************************************************************************/
/************************************************ Presentation ****************************************/
/*************************************************************************************************************/
void presentation()
{
sendSketchInfo("LPMultiSensor","1.0"); // Send the sketch version information to the gateway
present(CHILD_ID_HUM, S_HUM); // Register all sensors to gw (they will be created as child devices)
present(CHILD_ID_TEMP, S_TEMP);
present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
present(CHILD_ID_HEATINDEX, S_TEMP);
// present(CHILD_ID_BATTERY, S_MULTIMETER);
metric = getControllerConfig().isMetric;
}
/*************************************************************************************************************/
/************************************************ Setup ****************************************/
/*************************************************************************************************************/
void setup(){
analogReference(INTERNAL);
Wire.begin(); //start lightmeter and set mode - pin assignments (SCL ([A5], SDA [A4} ) fixed for pro mini
lightMeter.begin(BH1750_CONTINUOUS_HIGH_RES_MODE); /*Start I2C for GY 30 - BH1750
Full mode list:
BH1750_CONTINUOUS_LOW_RES_MODE
BH1750_CONTINUOUS_HIGH_RES_MODE (default)
BH1750_CONTINUOUS_HIGH_RES_MODE_2
BH1750_ONE_TIME_LOW_RES_MODE
BH1750_ONE_TIME_HIGH_RES_MODE
BH1750_ONE_TIME_HIGH_RES_MODE_2
*/
dht.begin(); // start temp/ humidity sensor
delay(1000);
}
/*************************************************************************************************************/
/************************************************ Main Loop ****************************************/
/*************************************************************************************************************/
void loop(){
float temperature = dht.readTemperature(); // Get temperature from DHT library
if (isnan(temperature)) {
Serial.println("Failed reading temperature from DHT!");
} else
{
temperature += SENSOR_TEMP_OFFSET;
send(msgTemp.set(temperature, 1));
}
float humidity = dht.readHumidity(); // Get humidity from DHT library
if (isnan(humidity)) {
Serial.println("Failed reading humidity from DHT");
} else
{
hic_temp = dht.computeHeatIndex(temperature, humidity, false); // Compute heat index in Celsius (Fahreheit = false)
send(msgHum.set(humidity, 1));
send(msgHeatIndex.set(hic_temp, 1));
}
lux = lightMeter.readLightLevel(); // Read Lightmeter
send(msgLux.set(lux, 1));
int sensorValue = analogRead(BATTERY_SENSE_PIN); // Read Battery level
Serial.print("Battery level: ");
Serial.println(sensorValue);
/* 1M, 470K divider across battery and using internal ADC ref of 1.1V
Sense point is bypassed with 0.1 uF cap to reduce noise at that point
((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
3.44/1023 = Volts per bit = 0.003363075
3.28/1023 = Volts per bit = 0.003206256 */
float batteryV = sensorValue * 0.003206256;
int batteryPcnt = sensorValue / 10;
Serial.print("Battery Voltage: ");
Serial.print(batteryV);
Serial.println(" V");
Serial.print("Battery percent: ");
Serial.print(batteryPcnt);
Serial.println(" %");
sendBatteryLevel(batteryPcnt);
Serial.println(" ");
Serial.print("Child ID ");
Serial.print(CHILD_ID_HUM);
Serial.print(" - Hum: ");
Serial.println(humidity);
Serial.print("Child ID ");
Serial.print(CHILD_ID_TEMP);
Serial.print(" - Temp: ");
Serial.println(temperature);
Serial.print("Child ID ");
Serial.print(CHILD_ID_LIGHT);
Serial.print(" - Lux: ");
Serial.println(lux);
Serial.print("Child ID ");
Serial.print(CHILD_ID_HEATINDEX);
Serial.print(" - Feels Like: ");
Serial.println(hic_temp);
Serial.print("Child ID ");
Serial.print(CHILD_ID_BATTERY);
Serial.print(" - Battery: ");
Serial.print(batteryV);
Serial.print(" V");
Serial.println(" ");
Serial.println(" ");
sleep(UPDATE_INTERVAL); // Sleep for a while to save energy
}