-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
added new usermod adc_sensor_mqtt_v2 with hass integration #4635
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
546839c
c331fec
5760d4d
5dececb
5fd149f
e12587c
243ceb7
ee8743c
21d4340
9dae91a
7882dcf
e1ae636
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # Photoresister sensor with MQTT ## based on LDR_Dusk_Dawn_v2 usermod from [@jeffwdh](https://github.com/jeffwdh) | ||
| This usermod will obtain readings from a Light Dependent Resistor (LDR). This is useful for exterior lighting situations where you want the lights to only be on when it is dark out. but this mod is designed for more hass application. it will publish auto discovery message to hass mqtt and attach the light sensor to the wled integration automatically | ||
|
||
|
|
||
| # Installation | ||
| Add "photoresistor_sensor_mqtt_v2" to your platformio.ini environment's custom_usermods and build. | ||
|
|
||
| Example: | ||
| ``` | ||
| [env:usermod_LDR_Dusk_Dawn_esp32dev] | ||
| extends = env:esp32dev | ||
| custom_usermods = ${env:esp32dev.custom_usermods} | ||
| photoresistor_sensor_mqtt_v2 # Enable LDR Dusk Dawn Usermod | ||
| ``` | ||
|
|
||
| # Usermod Settings | ||
| Setting | Description | Default | ||
| --- | --- | --- | ||
| Enabled | Enable/Disable the LDR functionality. | Disabled | ||
| LDR Pin | The analog capable pin your LDR is connected to. | A0 | ||
| LDR update interval | update interval to read the analog pin ( in ms ) | 3000 | ||
| LDR inverted | invert readings based on your own hardware setup ( invert mapping analog to digital value to 0V = 100% or 3.3V = 100% ) | false | ||
| change threshould | the minimum limit to detect change and publish the value (in % ; float ; ex 0.8 ) . | 1.0 | ||
|
|
||
| ## Author | ||
| [@jeffrommo911wdh](https://github.com/rommo911) | ||
|
||
| based on : | ||
| [@jeffwdh](https://github.com/jeffwdh) | ||
| [email protected] | ||
|
|
||
| Enables attaching a photoresistor sensor like the KY-018 and publishing the readings as a percentage, via MQTT. The frequency of MQTT messages is user definable. | ||
| A threshold value can be set so significant changes in the readings are published immediately vice waiting for the next update. This was found to be a good compromise between excessive MQTT traffic and delayed updates. | ||
|
|
||
| I also found it useful to limit the frequency of analog pin reads, otherwise the board hangs. | ||
|
|
||
| This usermod has only been tested with the KY-018 sensor though it should work for any other analog pin sensor. | ||
| Note: this does not control the LED strip directly, it only publishes MQTT readings for use with other integrations like Home Assistant. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| { | ||
| "name:": "photoresistor_sensor_mqtt_v2" | ||
| } | ||
rommo911 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,204 @@ | ||
| #include "wled.h" | ||
|
|
||
| class photoresistor_sensor_mqtt_v2 : public Usermod | ||
| { | ||
| private: | ||
| unsigned long update_interval = 3000; | ||
| float change_threshold = 1; | ||
| static const char MQTT_TOPIC[]; | ||
| static const char _name[]; | ||
| const bool HomeAssistantDiscovery = true; // is HA discovery turned on by default | ||
| int ldrPin = A0; | ||
|
||
| unsigned long lastTime = 0; | ||
| unsigned int lightValue = 0; | ||
| float lightPercentage = 0; | ||
| float lastPercentage = 0; | ||
| bool hassDiscoverySent = false; | ||
| bool ldrEnabled = true; | ||
| bool inverted = false; | ||
| bool initDone = false; | ||
| String topic_buf; | ||
|
|
||
| public: | ||
| photoresistor_sensor_mqtt_v2() {} | ||
|
|
||
| void setup() | ||
| { | ||
| // register ldrPin | ||
| if ((ldrPin >= 0) && ldrEnabled) | ||
| { | ||
| if (!PinManager::allocatePin(ldrPin, false, PinOwner::UM_PHOTO_RESISTOR_MQTT)) | ||
| { | ||
| ldrEnabled = false; // pin already in use -> disable usermod | ||
| } | ||
| else | ||
| { | ||
| pinMode(ldrPin, INPUT); // alloc success -> configure pin for input | ||
| } | ||
| } | ||
| else | ||
| { | ||
| ldrEnabled = false; // invalid pin -> disable usermod | ||
| } | ||
| initDone = true; | ||
| } | ||
|
|
||
| void connected() | ||
| { | ||
| if (WLED_MQTT_CONNECTED && HomeAssistantDiscovery) | ||
| { | ||
| publishDiscovery(); | ||
| } | ||
| } | ||
|
|
||
| void loop() | ||
| { | ||
| if (initDone && ldrEnabled && WLED_MQTT_CONNECTED) | ||
| { | ||
| bool force_update = (millis() - lastTime) > (update_interval * 100); // to keep the mqtt alive if the light is not changing | ||
| bool regular_update = (millis() - lastTime) > update_interval; | ||
| if (regular_update || force_update) | ||
| { | ||
| lightValue = analogRead(ldrPin); | ||
| #ifdef ESP32 | ||
| const float mapping = 4096.0; // ESP32 ADC resolution is 12 bit, so 4096 values | ||
| #else | ||
| const float mapping = 1024.0; // ESP8266 ADC resolution is 10 bit, so 1024 values | ||
| #endif | ||
| if (inverted) | ||
| { | ||
| lightPercentage = 100.0 - ((float)lightValue * -1 + mapping) / (float)mapping * 100; | ||
| } | ||
| else | ||
| { | ||
| lightPercentage = ((float)lightValue * -1 + mapping) / (float)mapping * 100; | ||
| } | ||
|
|
||
| if (abs(lightPercentage - lastPercentage) > change_threshold || force_update) | ||
| { | ||
| if (WLED_MQTT_CONNECTED) | ||
| { | ||
| publishMqtt(lightPercentage); | ||
| } | ||
| lastTime = millis(); | ||
| lastPercentage = lightPercentage; | ||
| // debug | ||
| char buf[64]; | ||
| sprintf_P(buf, PSTR("LDR: %d (%d)"), (int)lightPercentage, lightValue); | ||
| DEBUG_PRINTLN(buf); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| void addToConfig(JsonObject &root) | ||
| { | ||
| JsonObject top = root.createNestedObject(FPSTR(_name)); | ||
| top["Enabled"] = ldrEnabled; | ||
| top["LDR Pin"] = ldrPin; | ||
| top["LDR update interval"] = update_interval; | ||
| top["LDR inverted"] = inverted; | ||
| top["change threshould"] = change_threshold; | ||
| } | ||
|
|
||
| bool readFromConfig(JsonObject &root) | ||
| { | ||
| int8_t oldLdrPin = ldrPin; | ||
| JsonObject top = root[FPSTR(_name)]; | ||
| bool configComplete = !top.isNull(); | ||
| configComplete &= getJsonValue(top["Enabled"], ldrEnabled); | ||
| configComplete &= getJsonValue(top["LDR Pin"], ldrPin); | ||
|
||
| configComplete &= getJsonValue(top["LDR update interval"], update_interval); | ||
|
||
| configComplete &= getJsonValue(top["LDR inverted"], inverted); | ||
| configComplete &= getJsonValue(top["change threshould"], change_threshold); | ||
| // pin changed - un-register previous pin, register new pin | ||
| PinManager::deallocatePin(oldLdrPin, PinOwner::UM_PHOTO_RESISTOR_MQTT); | ||
| if (ldrEnabled && ldrPin > 0) | ||
|
||
| { | ||
| setup(); // setup again | ||
| } | ||
| return configComplete; | ||
| } | ||
|
|
||
| void addToJsonInfo(JsonObject &root) | ||
| { | ||
| // If "u" object does not exist yet we need to create it | ||
| JsonObject user = root["u"]; | ||
| if (user.isNull()) | ||
| user = root.createNestedObject("u"); | ||
|
|
||
| JsonArray LDR_Enabled = user.createNestedArray("LDR enabled"); | ||
| LDR_Enabled.add(ldrEnabled); | ||
| if (!ldrEnabled) | ||
| return; // do not add more if usermod is disabled | ||
|
|
||
| JsonArray LDR_Reading = user.createNestedArray("LDR reading"); | ||
| LDR_Reading.add(lightPercentage); | ||
|
|
||
| JsonArray LDR_interval = user.createNestedArray("LDR interval"); | ||
| LDR_interval.add(update_interval); | ||
|
|
||
| JsonArray LDR_change_threshold = user.createNestedArray("change threshould"); | ||
| LDR_change_threshold.add(change_threshold); | ||
| } | ||
|
|
||
| uint16_t getId() | ||
| { | ||
| return USERMOD_PHOTORESISTOR_MQTT_V2; | ||
| } | ||
|
|
||
| void publishMqtt(float state) | ||
| { | ||
| if (WLED_MQTT_CONNECTED) | ||
| { | ||
| topic_buf = mqttDeviceTopic; | ||
| topic_buf += MQTT_TOPIC; | ||
| if (!hassDiscoverySent && HomeAssistantDiscovery) | ||
| { | ||
| publishDiscovery(); | ||
| } | ||
| mqtt->publish(topic_buf.c_str(), 0, true, String(state).c_str()); | ||
| } | ||
| } | ||
|
|
||
| void publishDiscovery() | ||
| { | ||
| StaticJsonDocument<600> doc; | ||
| String uid = escapedMac.c_str(); | ||
| doc[F("name")] = F("Light Sensor"); | ||
| doc[F("stat_t")] = topic_buf.c_str(); | ||
| uid += F("_ldr"); | ||
| doc[F("uniq_id")] = uid; | ||
| doc[F("dev_cla")] = F("illuminance"); | ||
| doc[F("unit_of_meas")] = F("lx"); | ||
| doc[F("val_tpl")] = F("{{ value }}"); | ||
|
|
||
| JsonObject device = doc.createNestedObject(F("device")); // attach the sensor to the same device | ||
| device[F("name")] = serverDescription; | ||
| device[F("ids")] = serverDescription; | ||
| device[F("mf")] = F(WLED_BRAND); | ||
| device[F("mdl")] = F(WLED_PRODUCT_NAME); | ||
| device[F("sw")] = versionString; | ||
| #ifdef ESP32 | ||
| device[F("hw_version")] = F("esp32"); | ||
| #else | ||
| device[F("hw_version")] = F("esp8266"); | ||
| #endif | ||
| JsonArray connections = device[F("connections")].createNestedArray(); | ||
| connections.add(F("mac")); | ||
| connections.add(WiFi.macAddress()); | ||
|
|
||
| String discovery_topic = F("homeassistant/sensor/"); | ||
| discovery_topic += uid; | ||
| discovery_topic += F("/ldr/config"); | ||
| char json_str[600]; | ||
| size_t payload_size = serializeJson(doc, json_str); | ||
| mqtt->publish(discovery_topic.c_str(), 0, true, json_str, payload_size); | ||
| hassDiscoverySent = true; | ||
| } | ||
| }; | ||
| const char photoresistor_sensor_mqtt_v2::_name[] PROGMEM = "photoresistor_sensor_mqtt_v2"; | ||
| const char photoresistor_sensor_mqtt_v2::MQTT_TOPIC[] PROGMEM = "/ldr"; | ||
|
|
||
| static photoresistor_sensor_mqtt_v2 photoresistor_sensor_mqtt_v2_instance; | ||
| REGISTER_USERMOD(photoresistor_sensor_mqtt_v2_instance); | ||
Uh oh!
There was an error while loading. Please reload this page.