From 5e67dc7438804771c11a13c130c5dd9e75ab1696 Mon Sep 17 00:00:00 2001 From: Maxim Slipenko Date: Fri, 30 Dec 2022 18:31:20 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D1=8F?= =?UTF-8?q?=D0=B5=D1=82=20HALightBrightness?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 13 ++++ include/IRLight.h | 46 ++++++++++-- lib/HomeAssistantDevices/HALight.cpp | 72 +++++++++++-------- lib/HomeAssistantDevices/HALight.hpp | 7 ++ .../HALightBrightness.cpp | 37 ++++++++++ .../HALightBrightness.hpp | 25 +++++++ .../HomeAssistantDevices.hpp | 3 +- platformio.ini | 1 + src/IRLight.cpp | 64 +++++++++++++++-- src/IRLightController.cpp | 8 ++- src/IRLightController.hpp | 7 +- src/main.cpp | 61 ++++------------ 12 files changed, 257 insertions(+), 87 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 lib/HomeAssistantDevices/HALightBrightness.cpp create mode 100644 lib/HomeAssistantDevices/HALightBrightness.hpp diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..89f6be4 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,13 @@ +{ + "files.associations": { + "array": "cpp", + "deque": "cpp", + "list": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "string_view": "cpp", + "initializer_list": "cpp", + "ranges": "cpp" + } +} \ No newline at end of file diff --git a/include/IRLight.h b/include/IRLight.h index 107196b..9a44245 100644 --- a/include/IRLight.h +++ b/include/IRLight.h @@ -1,14 +1,18 @@ #pragma once +#include #include #include +#include -class IRLight { +class IRLight: public HALightBrightnessController { private: bool state; + short brightness; + IRsend *irsend; - const uint16_t rawDataOn[67] = { + const uint16_t RDOn[67] = { 8980, 4420, 580, 520, 630, 470, 630, 520, 580, 520, 630, 470, 630, 520, 580, 520, 630, 1570, 630, 1620, 580, 1620, 630, 1620, 580, 1570, 680, 1570, 630, 1570, 630, 1570, 630, 520, 630, 1570, @@ -16,7 +20,7 @@ private: 630, 470, 630, 520, 630, 1570, 630, 1570, 630, 1620, 630, 1570, 630, 1570, 630, 1570, 680, 1570, 630}; - const uint16_t rawDataOff[67] = { + const uint16_t RDOff[67] = { 8980, 4370, 680, 420, 730, 420, 680, 420, 680, 420, 730, 420, 680, 420, 680, 420, 730, 1470, 730, 1520, 680, 1520, 730, 1470, 730, 1470, 730, 1520, 680, 1520, 730, 1470, 730, 420, 680, 470, @@ -24,14 +28,46 @@ private: 680, 470, 580, 1620, 630, 470, 630, 1570, 630, 520, 580, 520, 630, 1570, 680, 1520, 730, 1520, 680}; + const uint16_t RDCentralButton[67] = { + 9030, 4320, 680, 470, 630, 470, 680, 420, 680, 470, 630, 470, + 680, 420, 680, 470, 630, 1570, 680, 1520, 680, 1520, 680, 1520, + 730, 1520, 680, 1520, 680, 1520, 680, 1570, 680, 420, 680, 1520, + 680, 470, 680, 1520, 680, 470, 630, 470, 680, 420, 680, 470, + 630, 470, 630, 470, 680, 1520, 680, 470, 680, 1520, 630, 1570, + 680, 1520, 680, 1570, 680, 1520, 680}; + + const uint16_t RDBrightnessUp[67] = { + 9080,4270, 730,420, 680,420, 680,420, 730,420, 680,420, 680,420, 730,420, + 680,1520, 680,1520, 730,1470, 730,1470, 730,1520, 680,1520, 730,1470, + 730,1520, 680,420, 680,470, 580,1620, 580,520, 630,520, 580,1620, 580,520, + 630,520, 580,520, 630,1570, 580,570, 580,1570, 630,1620, 630,520, 580,1570, + 730,1520, 680,1520, 730}; + + const uint16_t RDBrightnessDown[67] = { + 9030, 4320, 630, 520, 630, 470, 630, 470, 630, 520, 630, 470, + 630, 470, 630, 520, 630, 1570, 630, 1570, 630, 1620, 630, 1570, + 630, 1570, 630, 1620, 630, 1570, 630, 1570, 630, 470, 680, 470, + 630, 1570, 630, 1570, 680, 1570, 630, 1570, 630, 470, 680, 470, + 630, 470, 630, 1570, 680, 470, 630, 470, 630, 470, 680, 470, + 630, 1570, 630, 1570, 680, 1570, 630}; + public: IRLight(int pin); IRLight(IRsend *irsend); + + void setState(bool state); + bool getState(); void on(); void off(); - void begin(); - bool getState(); + void setBrightness(int brightness); + int getBrightness(); + + void brightnessUp(); + void brightnessDown(); + int getBrightnessScale(); + + void begin(); ~IRLight(); }; \ No newline at end of file diff --git a/lib/HomeAssistantDevices/HALight.cpp b/lib/HomeAssistantDevices/HALight.cpp index 8c6ce3c..842b830 100644 --- a/lib/HomeAssistantDevices/HALight.cpp +++ b/lib/HomeAssistantDevices/HALight.cpp @@ -1,32 +1,16 @@ #include +HALight::HALight(PubSubClient &client, const char *name, const char *unique_id) + : HAControllableDevice(client, "light", name, unique_id) {} + HALight::HALight(PubSubClient &client, const char *name, const char *unique_id, HALightController &baseLight) : HAControllableDevice(client, "light", name, unique_id), light(&baseLight) {} -void HALight::sendState() { - StaticJsonDocument<256> doc; - - buffer[0] = '\0'; - - if (light->getState()) { - doc["state"] = "ON"; - } else { - doc["state"] = "OFF"; - } - - serializeJson(doc, buffer, buffer_size); - - Serial.println(state_topic); - client.publish(state_topic, buffer, true); -} - -void HALight::sendConfig() { - StaticJsonDocument<256> doc; - - buffer[0] = '\0'; - +JSON_DOCUMENT_TYPE HALight::createConfigJSON() { + JSON_DOCUMENT_TYPE doc; + doc["~"] = device_topic; doc["name"] = name; doc["unique_id"] = unique_id; @@ -34,6 +18,42 @@ void HALight::sendConfig() { doc["stat_t"] = "~/state"; doc["schema"] = "json"; + return doc; +} + +JSON_DOCUMENT_TYPE HALight::createStateJSON() { + JSON_DOCUMENT_TYPE doc; + + if (light->getState()) { + doc["state"] = "ON"; + } else { + doc["state"] = "OFF"; + } + + return doc; +} + +void HALight::innerHanlder(JSON_DOCUMENT_TYPE &doc) { + if (strcmp(doc["state"], "ON") == 0) { + light->setState(true); + } else { + light->setState(false); + } +} + +void HALight::sendState() { + JSON_DOCUMENT_TYPE doc = createStateJSON(); + + buffer[0] = '\0'; + serializeJson(doc, buffer, buffer_size); + + Serial.println(state_topic); + client.publish(state_topic, buffer, true); +} + +void HALight::sendConfig() { + JSON_DOCUMENT_TYPE doc = createConfigJSON(); + buffer[0] = '\0'; serializeJson(doc, buffer, buffer_size); client.publish(config_topic, buffer, true); } @@ -42,14 +62,10 @@ void HALight::handle(char *topic, byte *payload, unsigned int length) { if (strcmp(topic, command_topic) != 0) return; - StaticJsonDocument<256> doc; + JSON_DOCUMENT_TYPE doc; deserializeJson(doc, (const byte *)payload, length); - if (strcmp(doc["state"], "ON") == 0) { - light->setState(true); - } else { - light->setState(false); - } + innerHanlder(doc); sendState(); } \ No newline at end of file diff --git a/lib/HomeAssistantDevices/HALight.hpp b/lib/HomeAssistantDevices/HALight.hpp index 49b4112..fbc3b39 100644 --- a/lib/HomeAssistantDevices/HALight.hpp +++ b/lib/HomeAssistantDevices/HALight.hpp @@ -8,10 +8,17 @@ public: virtual bool getState() = 0; }; +#define JSON_DOCUMENT_TYPE StaticJsonDocument<256> + class HALight : public HAControllableDevice { private: HALightController *light; +protected: + virtual JSON_DOCUMENT_TYPE createConfigJSON(); + virtual JSON_DOCUMENT_TYPE createStateJSON(); + virtual void innerHanlder(JSON_DOCUMENT_TYPE &doc); + HALight(PubSubClient &client, const char *name, const char *unique_id); public: HALight(PubSubClient &client, const char *name, const char *unique_id, HALightController &baseLight); diff --git a/lib/HomeAssistantDevices/HALightBrightness.cpp b/lib/HomeAssistantDevices/HALightBrightness.cpp new file mode 100644 index 0000000..864e491 --- /dev/null +++ b/lib/HomeAssistantDevices/HALightBrightness.cpp @@ -0,0 +1,37 @@ +#include + + +HALightBrightness::HALightBrightness(PubSubClient &client, const char *name, const char *unique_id, + HALightBrightnessController &baseLight) + : HALight(client, "light", name, baseLight), + light(&baseLight) {} + + +JSON_DOCUMENT_TYPE HALightBrightness::createConfigJSON() { + JSON_DOCUMENT_TYPE doc = HALight::createConfigJSON(); + + doc["brightness"] = true; + doc["brightness_scale"] = light->getBrightnessScale(); + // doc["color_mode"] = true; + // doc["supported_color_modes"] = + + // JSON_DOCUMENT_TYPE doc; + return doc; +} + +JSON_DOCUMENT_TYPE HALightBrightness::createStateJSON() { + JSON_DOCUMENT_TYPE doc = HALight::createStateJSON(); + + doc["brightness"] = light->getBrightness(); + + // JSON_DOCUMENT_TYPE doc; + return doc; +} + +void HALightBrightness::innerHanlder(JSON_DOCUMENT_TYPE &doc) { + if (doc.containsKey("brightness")) { + light->setBrightness(doc["brightness"]); + } + delay(50); + HALight::innerHanlder(doc); +} \ No newline at end of file diff --git a/lib/HomeAssistantDevices/HALightBrightness.hpp b/lib/HomeAssistantDevices/HALightBrightness.hpp new file mode 100644 index 0000000..a0a5f65 --- /dev/null +++ b/lib/HomeAssistantDevices/HALightBrightness.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include + +class HALightBrightnessController: public HALightController { +public: + virtual void setBrightness(int value) = 0; + virtual int getBrightness() = 0; + + + virtual int getBrightnessScale() = 0; +}; + +class HALightBrightness : public HALight { +private: + HALightBrightnessController *light; + +protected: + JSON_DOCUMENT_TYPE createConfigJSON(); + JSON_DOCUMENT_TYPE createStateJSON(); + void innerHanlder(JSON_DOCUMENT_TYPE &doc); +public: + HALightBrightness(PubSubClient &client, const char *name, const char *unique_id, + HALightBrightnessController &baseLight); +}; \ No newline at end of file diff --git a/lib/HomeAssistantDevices/HomeAssistantDevices.hpp b/lib/HomeAssistantDevices/HomeAssistantDevices.hpp index d1142b5..75533e5 100644 --- a/lib/HomeAssistantDevices/HomeAssistantDevices.hpp +++ b/lib/HomeAssistantDevices/HomeAssistantDevices.hpp @@ -1,3 +1,4 @@ #pragma once -#include \ No newline at end of file +#include +#include \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 1a8634d..7b85205 100644 --- a/platformio.ini +++ b/platformio.ini @@ -19,3 +19,4 @@ lib_deps = bblanchon/ArduinoJson@^6.19.4 crankyoldgit/IRremoteESP8266@^2.8.2 monitor_speed = 115200 +monitor_filters = default, esp8266_exception_decoder \ No newline at end of file diff --git a/src/IRLight.cpp b/src/IRLight.cpp index 9dd1f43..7158b90 100644 --- a/src/IRLight.cpp +++ b/src/IRLight.cpp @@ -10,18 +10,72 @@ IRLight::IRLight(IRsend *irsend) { state = false; } +void IRLight::setState(bool state) { + if (state) + on(); + else + off(); +} + void IRLight::on() { state = true; - irsend->sendRaw(rawDataOn, 67, 38); + irsend->sendRaw(RDOn, 67, 38); } void IRLight::off() { state = false; - irsend->sendRaw(rawDataOff, 67, 38); + irsend->sendRaw(RDOff, 67, 38); } -void IRLight::begin() { irsend->begin(); } +void IRLight::setBrightness(int newBrightness) { + if (newBrightness > brightness) { + for (int i = 0; i < newBrightness - brightness; i++) { + brightnessUp(); + delay(250); + } + } else if (newBrightness < brightness) { + for (int i = 0; i < brightness - newBrightness; i++) { + brightnessDown(); + delay(250); + } + } + brightness = newBrightness; +} -bool IRLight::getState() { return state; } +void IRLight::brightnessUp() { + if (brightness < getBrightnessScale()) { + brightness++; + irsend->sendRaw(RDBrightnessUp, 67, 38); + } +} -IRLight::~IRLight() { delete irsend; } \ No newline at end of file +void IRLight::brightnessDown() { + if (brightness > 0) { + brightness--; + irsend->sendRaw(RDBrightnessDown, 67, 38); + } +} + +void IRLight::begin() { + irsend->begin(); + irsend->sendRaw(RDCentralButton, 67, 38); + brightness = 14; + delay(250); + off(); +} + +int IRLight::getBrightnessScale() { + return 14; +} + +int IRLight::getBrightness() { + return brightness; +} + +bool IRLight::getState() { + return state; +} + +IRLight::~IRLight() { + delete irsend; +} \ No newline at end of file diff --git a/src/IRLightController.cpp b/src/IRLightController.cpp index 8cf8a1c..a33a7fe 100644 --- a/src/IRLightController.cpp +++ b/src/IRLightController.cpp @@ -12,6 +12,12 @@ void IRLightController::setState(bool state) { } } -bool IRLightController::getState() { return irlight.getState(); } +bool IRLightController::getState() { + return irlight.getState(); +} + +void IRLightController::setBrightness(int value) { + +} IRLightController::~IRLightController() {} \ No newline at end of file diff --git a/src/IRLightController.hpp b/src/IRLightController.hpp index 4d846d0..f2c33ce 100644 --- a/src/IRLightController.hpp +++ b/src/IRLightController.hpp @@ -3,7 +3,7 @@ #include #include -class IRLightController : public HALightController { +class IRLightController : public HALightBrightnessController { private: IRLight &irlight; @@ -12,5 +12,10 @@ public: void begin(); void setState(bool state); bool getState(); + + void setBrightness(int value); + int getBrightness(); + int getBrightnessScale(); + ~IRLightController(); }; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index a8fa2cf..1fa9c19 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,8 +17,7 @@ DHT dht(DHTPIN, DHTTYPE); IRLight irlight(4); -IRLightController light(irlight); -HALight halight(client, "light", "l-1", light); +HALightBrightness halight(client, "light", "l-1", irlight); void setup_wifi(); void reconnect(); @@ -45,11 +44,19 @@ void setup() { } dht.begin(); - light.begin(); + irlight.begin(); client.subscribe("homeassistant/status"); halight.subscribeToCommandTopic(); + if (WiFi.status() == WL_CONNECTED) { + mqtt_publish_config(); + delay(100); + // mqtt_publish_state(); + halight.sendState(); + } + + /* mqtt_publish_config(); if (WiFi.status() == WL_CONNECTED) { @@ -59,6 +66,7 @@ void setup() { mqtt_publish_state(); halight.sendState(); } + */ } void loop() { @@ -67,15 +75,17 @@ void loop() { } client.loop(); + /* long now = millis(); if (now - lastMsg > 60000) { lastMsg = now; temp = round2(dht.readTemperature()); + hum = round2(dht.readHumidity()); mqtt_publish_state(); } - + */ delay(100); } @@ -93,7 +103,7 @@ void mqtt_callback(char *topic, byte *payload, unsigned int length) { mqtt_publish_config(); } } - + halight.handle(topic, payload, length); } @@ -137,51 +147,10 @@ void reconnect() { } void mqtt_publish_config() { - /* - StaticJsonDocument<256> doc; - char buffer[256]; - - doc["device_class"] = "temperature"; - doc["name"] = "Temperature"; - doc["unit_of_meas"] = "°C"; - doc["stat_t"] = HOMEASSISTANT_TOPIC "/state"; - doc["value_template"] = "{{value_json.temperature}}"; - doc["unique_id"] = "t"; - - serializeJson(doc, buffer); - - client.publish(HOMEASSISTANT_TOPIC "/t/config", buffer, true); - - doc["device_class"] = "humidity"; - doc["name"] = "Humidity"; - doc["unit_of_meas"] = "%"; - doc["stat_t"] = HOMEASSISTANT_TOPIC "/state"; - doc["value_template"] = "{{value_json.humidity}}"; - doc["unique_id"] = "h"; - - serializeJson(doc, buffer); - - client.publish(HOMEASSISTANT_TOPIC "/h/config", buffer, true); - */ halight.sendConfig(); } void mqtt_publish_state() { - /* - Serial.println("===== Sending Data ====="); - StaticJsonDocument<256> doc; - char buffer[256]; - - doc["temperature"] = round2(temp); - doc["humidity"] = round2(hum); - - Serial.printf("Temperature: %f\n", round2(temp)); - Serial.printf("Humidity: %f\n", round2(hum)); - - serializeJson(doc, buffer); - - client.publish(HOMEASSISTANT_TOPIC "/state", buffer, true); - */ // Loop until we're reconnected while (!client.connected()) { Serial.print("Attempting MQTT connection...");