diff --git a/.gitignore b/.gitignore index 6c97aa4..baf3230 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .pioenvs .piolibdeps +.pio data/homie/config.json nbproject diff --git a/platformio.ini b/platformio.ini index d111ac2..4b6f9f1 100644 --- a/platformio.ini +++ b/platformio.ini @@ -24,4 +24,4 @@ board = nodemcu upload_speed=921600 build_flags = -D PIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY -lib_deps = https://github.com/homieiot/homie-esp8266.git#develop, Syslog +lib_deps = https://github.com/homieiot/homie-esp8266.git#develop-v3, Syslog diff --git a/src/main.cpp b/src/main.cpp index 022586c..4785209 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,55 +5,77 @@ WiFiUDP udpClient; Syslog syslog(udpClient, SYSLOG_PROTO_IETF); const int PIN_RELAY = D1; -int timer = 0; -HomieNode powerNode("power", "switch"); - - - -bool powerOnHandler(const HomieRange& range, const String& value) { - if (value != "true" && value != "false") return false; - bool on = (value == "true"); - digitalWrite(PIN_RELAY, on ? LOW : HIGH); - powerNode.setProperty("on").send(value); - Homie.getLogger() << "Power is " << (on ? "on" : "off") << endl; +#define OUTPUT_SET(x) digitalWrite(PIN_RELAY, x ? LOW : HIGH); +unsigned int timer = 0; +unsigned int next_timer_update = 0; +HomieNode powerNode("power", "Power", "switch"); +bool powerStateHandler(const HomieRange& range, const String& value) { + if (value != "on" && value != "off") return false; + powerNode.setProperty("state").send(value); + powerNode.setProperty("timer").send("0"); + timer = 0; + if(value == "on") { + OUTPUT_SET(true); + Homie.getLogger() << "Power is on" << endl; + } else { + OUTPUT_SET(false); + Homie.getLogger() << "Power is off" << endl; + } + return true; } +bool powerTimerHandler(const HomieRange& range, const String& value) { + int settimer = value.toInt(); + if(settimer == 0 || settimer > 120) + return false; + + timer = millis() + (settimer * 1000 * 60); + next_timer_update = millis() + 60*1000; + powerNode.setProperty("timer").send(String(settimer)); + powerNode.setProperty("state").send("on"); + Homie.getLogger() << "Power is on for " << settimer << "minutes" << endl; + OUTPUT_SET(true); + return true; +} + + void setupHandler() { pinMode(PIN_RELAY, OUTPUT); - digitalWrite(PIN_RELAY, HIGH); + OUTPUT_SET(false); + powerNode.setProperty("state").send("off"); + powerNode.setProperty("timer").send("0"); +} - powerNode.setProperty("on").send("false"); +void loopHandler() { + if(timer) + { + if(timer < millis()) + { + timer = 0; + OUTPUT_SET(false); + powerNode.setProperty("timer").send("0"); + powerNode.setProperty("state").send("off"); + } + if(millis() > next_timer_update) { + next_timer_update = millis() + 60*1000; + unsigned int time_remaining = timer - millis(); + unsigned int min_left = time_remaining / (60*1000); + powerNode.setProperty("timer").send(String(min_left)); + + } + } } void onHomieEvent(const HomieEvent& event) { switch(event.type) { - case HomieEventType::STANDALONE_MODE: - // Do whatever you want when standalone mode is started - break; - case HomieEventType::CONFIGURATION_MODE: - // Do whatever you want when configuration mode is started - break; - case HomieEventType::NORMAL_MODE: - // Do whatever you want when normal mode is started - break; - case HomieEventType::OTA_STARTED: - // Do whatever you want when OTA is started - break; - case HomieEventType::OTA_PROGRESS: - // Do whatever you want when OTA is in progress - - // You can use event.sizeDone and event.sizeTotal - break; case HomieEventType::OTA_FAILED: + syslog.log(LOG_INFO, "OTA failed"); // Do whatever you want when OTA is failed break; case HomieEventType::OTA_SUCCESSFUL: - // Do whatever you want when OTA is successful - break; - case HomieEventType::ABOUT_TO_RESET: - // Do whatever you want when the device is about to reset + syslog.log(LOG_INFO, "OTA completed"); break; case HomieEventType::WIFI_CONNECTED: // Do whatever you want when Wi-Fi is connected in normal mode @@ -61,39 +83,20 @@ void onHomieEvent(const HomieEvent& event) { syslog.appName("deskcontrol"); syslog.defaultPriority(LOG_ERR); syslog.log(LOG_INFO, "WiFi Connected, software version: 1.0"); - // You can use event.ip, event.gateway, event.mask - break; - case HomieEventType::WIFI_DISCONNECTED: - // Do whatever you want when Wi-Fi is disconnected in normal mode - - // You can use event.wifiReason break; case HomieEventType::MQTT_READY: - // Do whatever you want when MQTT is connected in normal mode syslog.log(LOG_INFO, "MQTT connected"); break; case HomieEventType::MQTT_DISCONNECTED: - // Do whatever you want when MQTT is disconnected in normal mode syslog.log(LOG_INFO, "MQTT disconnected"); - // You can use event.mqttReason break; - case HomieEventType::MQTT_PACKET_ACKNOWLEDGED: - // Do whatever you want when an MQTT packet with QoS > 0 is acknowledged by the broker - - // You can use event.packetId - break; - case HomieEventType::READY_TO_SLEEP: - // After you've called `prepareToSleep()`, the event is triggered when MQTT is disconnected - break; - case HomieEventType::SENDING_STATISTICS: - // Do whatever you want when statistics are sent in normal mode + default: break; } } void setup() { syslog.server("192.168.1.100", 514); - Serial.begin(115200); @@ -104,10 +107,11 @@ void setup() { Homie_setFirmware("deskcontrol", "1.0.0"); Homie_setBrand("FuryFire"); - powerNode.advertise("on").settable(powerOnHandler); - + powerNode.advertise("state").settable(powerStateHandler); + powerNode.advertise("timer").settable(powerTimerHandler); Homie.setSetupFunction(setupHandler); - Homie.onEvent(onHomieEvent); // before Homie.setup() + Homie.onEvent(onHomieEvent); // before Homie.setup() + Homie.setLoopFunction(loopHandler); Homie.setup(); }