Skip to content

Commit

Permalink
Merge pull request Aircoookie#1043 from calebmah/sensor-usermods
Browse files Browse the repository at this point in the history
Photoresistor and PIR sensor MQTT usermods
  • Loading branch information
Aircoookie authored Jul 19, 2020
2 parents e5dc473 + 432755e commit 2cd8ee4
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 0 deletions.
9 changes: 9 additions & 0 deletions usermods/PIR_sensor_mqtt_v1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# PIR sensor with MQTT

This simple usermod allows attaching a PIR sensor like the AM312 and publish the readings over MQTT. A message is sent when motion is detected as well as when motion has stopped.

This usermod has only been tested with the AM312 sensor though should work for any other PIR sensor. Note that this does not control the LED strip directly, it only publishes MQTT readings for use with other integrations like Home Assistant.

## Installation

Copy and replace the file `usermod.cpp` in wled00 directory.
55 changes: 55 additions & 0 deletions usermods/PIR_sensor_mqtt_v1/usermod.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include "wled.h"
/*
* This v1 usermod file allows you to add own functionality to WLED more easily
* See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality
* EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in const.h)
* If you just need 8 bytes, use 2551-2559 (you do not need to increase EEPSIZE)
*
* Consider the v2 usermod API if you need a more advanced feature set!
*/

//Use userVar0 and userVar1 (API calls &U0=,&U1=, uint16_t)

// PIR sensor pin
const int MOTION_PIN = 16;
// MQTT topic for sensor values
const char MQTT_TOPIC[] = "/motion";

int prevState = LOW;

//gets called once at boot. Do all initialization that doesn't depend on network here
void userSetup()
{
pinMode(MOTION_PIN, INPUT);
}

//gets called every time WiFi is (re-)connected. Initialize own network interfaces here
void userConnected()
{

}

void publishMqtt(String state)
{
//Check if MQTT Connected, otherwise it will crash the 8266
if (mqtt != nullptr){
char subuf[38];
strcpy(subuf, mqttDeviceTopic);
strcat(subuf, MQTT_TOPIC);
mqtt->publish(subuf, 0, true, state.c_str());
}
}

//loop. You can use "if (WLED_CONNECTED)" to check for successful connection
void userLoop()
{
if (digitalRead(MOTION_PIN) == HIGH && prevState == LOW) { // Motion detected
publishMqtt("ON");
prevState = HIGH;
}
if (digitalRead(MOTION_PIN) == LOW && prevState == HIGH) { // Motion stopped
publishMqtt("OFF");
prevState = LOW;
}
}

11 changes: 11 additions & 0 deletions usermods/photoresistor_sensor_mqtt_v1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Photoresister sensor with MQTT

This simple usermod allows attaching a photoresistor sensor like the KY-018 and publish the readings in percentage over MQTT. The frequency of MQTT messages can be modified, and there is a threshold value that can be set so that significant changes in the readings can be published immediately instead of waiting for the next update. This was found to be a good compromise between spamming MQTT messages and delayed updates.

I also found it useful to limit the frequency of analog pin reads because otherwise the board hangs.

This usermod has only been tested with the KY-018 sensor though should work for any other analog pin sensor. Note that this does not control the LED strip directly, it only publishes MQTT readings for use with other integrations like Home Assistant.

## Installation

Copy and replace the file `usermod.cpp` in wled00 directory.
70 changes: 70 additions & 0 deletions usermods/photoresistor_sensor_mqtt_v1/usermod.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include "wled.h"
/*
* This v1 usermod file allows you to add own functionality to WLED more easily
* See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality
* EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in const.h)
* If you just need 8 bytes, use 2551-2559 (you do not need to increase EEPSIZE)
*
* Consider the v2 usermod API if you need a more advanced feature set!
*/

//Use userVar0 and userVar1 (API calls &U0=,&U1=, uint16_t)

const int LIGHT_PIN = A0; // define analog pin
const long UPDATE_MS = 30000; // Upper threshold between mqtt messages
const char MQTT_TOPIC[] = "/light"; // MQTT topic for sensor values
const int CHANGE_THRESHOLD = 5; // Change threshold in percentage to send before UPDATE_MS

// variables
long lastTime = 0;
long timeDiff = 0;
long readTime = 0;
int lightValue = 0;
float lightPercentage = 0;
float lastPercentage = 0;

//gets called once at boot. Do all initialization that doesn't depend on network here
void userSetup()
{
pinMode(LIGHT_PIN, INPUT);
}

//gets called every time WiFi is (re-)connected. Initialize own network interfaces here
void userConnected()
{

}

void publishMqtt(float state)
{
//Check if MQTT Connected, otherwise it will crash the 8266
if (mqtt != nullptr){
char subuf[38];
strcpy(subuf, mqttDeviceTopic);
strcat(subuf, MQTT_TOPIC);
mqtt->publish(subuf, 0, true, String(state).c_str());
}
}

//loop. You can use "if (WLED_CONNECTED)" to check for successful connection
void userLoop()
{
// Read only every 500ms, otherwise it causes the board to hang
if (millis() - readTime > 500)
{
readTime = millis();
timeDiff = millis() - lastTime;

// Convert value to percentage
lightValue = analogRead(LIGHT_PIN);
lightPercentage = ((float)lightValue * -1 + 1024)/(float)1024 *100;

// Send MQTT message on significant change or after UPDATE_MS
if (abs(lightPercentage - lastPercentage) > CHANGE_THRESHOLD || timeDiff > UPDATE_MS)
{
publishMqtt(lightPercentage);
lastTime = millis();
lastPercentage = lightPercentage;
}
}
}

0 comments on commit 2cd8ee4

Please sign in to comment.