diff --git a/src/platform/arduino/MQTTTelemetry.cpp b/src/platform/arduino/MQTTTelemetry.cpp index ee9403c..89e3ffa 100644 --- a/src/platform/arduino/MQTTTelemetry.cpp +++ b/src/platform/arduino/MQTTTelemetry.cpp @@ -6,7 +6,7 @@ #include "../../Config.h" #include "../../Platform.h" -StaticJsonDocument<1024> m_json; +static StaticJsonDocument<1024> m_json; struct MQTTDevice { const String id; @@ -107,59 +107,67 @@ MQTTTelemetry::MQTTTelemetry() : BufferedInputSource("MQTT"), memset(m_hostBuf, 0, sizeof(m_hostBuf)); } +void +MQTTTelemetry::publishScenes() +{ + for(auto scene : Static::instance()->scenes()) { + m_json.clear(); + String strName{scene.name}; + MQTTEntity sceneObj { + "scene", + Device, + strName + }; + sceneObj.toJson(m_json, false); + m_json["cmd_t"] = "~/set"; + m_json["ret"] = false; + m_json["payload_on"] = "active"; + publishDoc(sceneObj.configTopic().c_str(), false); + m_mqtt.subscribe(sceneObj.commandTopic().c_str()); + Log.info("Published scene %s", sceneObj.configTopic().c_str()); + } +} + +void +MQTTTelemetry::onMQTTOnline() +{ + Log.notice("Connected to MQTT"); + String logTopic = m_debugTopic + "/log"; + Log.info("MQTT logs are available at %s", logTopic.c_str()); + m_needHeartbeat = true; + + m_json.clear(); + Lightswitch.toJson(m_json); + m_json["brightness"] = true; + m_json["rgb"] = true; + + publishDoc(Lightswitch.configTopic().c_str(), true); + m_mqtt.subscribe(Lightswitch.commandTopic().c_str()); + + publishScenes(); + + m_json.clear(); + FPSSensor.toJson(m_json, false); + m_json["unit_of_meas"] = "Frames/s"; + publishDoc(FPSSensor.configTopic().c_str(), true); + +#ifdef ESP8266 + struct rst_info resetInfo = *ESP.getResetInfoPtr(); + if (resetInfo.reason != 0) { + char buff[200]; + sprintf(&buff[0], "Fatal exception:%d flag:%d (%s) epc1:0x%08x epc2:0x%08x epc3:0x%08x excvaddr:0x%08x depc:0x%08x", resetInfo.exccause, resetInfo.reason, (resetInfo.reason == 0 ? "DEFAULT" : resetInfo.reason == 1 ? "WDT" : resetInfo.reason == 2 ? "EXCEPTION" : resetInfo.reason == 3 ? "SOFT_WDT" : resetInfo.reason == 4 ? "SOFT_RESTART" : resetInfo.reason == 5 ? "DEEP_SLEEP_AWAKE" : resetInfo.reason == 6 ? "EXT_SYS_RST" : "???"), resetInfo.epc1, resetInfo.epc2, resetInfo.epc3, resetInfo.excvaddr, resetInfo.depc); + Log.warning("Previous crash detected! %s", buff); + } +#endif +} + void MQTTTelemetry::handleEventOnline(const InputEvent& evt) { if (!m_mqtt.connected()) { Log.notice("Connecting to MQTT as %s on %s...", Platform::deviceID(), Device.availabilityTopic.c_str()); if (m_mqtt.connect(Platform::deviceID(), NULL, NULL, Device.availabilityTopic.c_str(), 0, true, "offline")) { - Log.notice("Connected to MQTT"); - String logTopic = m_debugTopic + "/log"; - Log.info("MQTT logs are available at %s", logTopic.c_str()); - m_needHeartbeat = true; - - m_json.clear(); - Lightswitch.toJson(m_json); - m_json["brightness"] = true; - m_json["rgb"] = true; - - publishDoc(Lightswitch.configTopic().c_str(), true); - m_mqtt.subscribe(Lightswitch.commandTopic().c_str()); - - for(auto scene : Static::instance()->scenes()) { - m_json.clear(); - String strName{scene.name}; - MQTTEntity sceneObj { - "scene", - Device, - strName - }; - sceneObj.toJson(m_json, false); - m_json["cmd_t"] = "~/set"; - m_json["ret"] = false; - m_json["payload_on"] = "active"; - publishDoc(sceneObj.configTopic().c_str(), false); - m_mqtt.subscribe(sceneObj.commandTopic().c_str()); - Log.info("Published scene %s", sceneObj.configTopic().c_str()); - } - - m_json.clear(); - FPSSensor.toJson(m_json, false); - m_json["unit_of_meas"] = "Frames/s"; - publishDoc(FPSSensor.configTopic().c_str(), true); - - //Log.verbose("Publish %s %s", FPSSensor.configTopic().c_str(), buf); - //m_mqtt.publish(FPSSensor.configTopic().c_str(), (uint8_t*)buf, strlen(buf), true); - m_mqtt.subscribe(FPSSensor.commandTopic().c_str()); - -#ifdef BOARD_ESP8266 - struct rst_info resetInfo = *ESP.getResetInfoPtr(); - if (resetInfo.reason != 0) { - char buff[200]; - sprintf(&buff[0], "Fatal exception:%d flag:%d (%s) epc1:0x%08x epc2:0x%08x epc3:0x%08x excvaddr:0x%08x depc:0x%08x", resetInfo.exccause, resetInfo.reason, (resetInfo.reason == 0 ? "DEFAULT" : resetInfo.reason == 1 ? "WDT" : resetInfo.reason == 2 ? "EXCEPTION" : resetInfo.reason == 3 ? "SOFT_WDT" : resetInfo.reason == 4 ? "SOFT_RESTART" : resetInfo.reason == 5 ? "DEEP_SLEEP_AWAKE" : resetInfo.reason == 6 ? "EXT_SYS_RST" : "???"), resetInfo.epc1, resetInfo.epc2, resetInfo.epc3, resetInfo.excvaddr, resetInfo.depc); - Log.warning("Previous crash detected! %s", buff); - } -#endif + onMQTTOnline(); } else { Log.warning("Could not connect to MQTT"); } @@ -185,7 +193,6 @@ MQTTTelemetry::handleEventOnline(const InputEvent& evt) publishDoc(statTopic.c_str()); } else if (evt.intent == InputEvent::SetScene) { m_json.clear(); - m_json["effect"] = evt.asString(); m_json["state"] = m_isOn ? "ON" : "OFF"; publishDoc(statTopic.c_str()); } @@ -246,27 +253,31 @@ MQTTTelemetry::loopOnline() m_needHeartbeat = true; } if (m_needHeartbeat) { - m_json.clear(); - m_json["device_id"] = Platform::deviceID(); - m_json["sketch_version"] = ESP.getSketchMD5(); - m_json["os_version"] = ESP.getSdkVersion(); - m_json["localip"] = WiFi.localIP().toString(); - m_json["pixelCount"] = Static::instance()->coordMap()->physicalPixelCount(); - m_json["loadedProfile"] = Static::instance()->loadedProfile(); - m_json["RSSI"] = WiFi.RSSI(); - m_json["free_ram"] = ESP.getFreeHeap(); - m_json["fps"] = FastLED.getFPS(); - String availTopic = m_rootTopic + "/available"; - publishDoc(Lightswitch.heartbeatTopic().c_str()); - m_mqtt.publish(Device.availabilityTopic.c_str(), "online"); - - String fpsCounter = String(FastLED.getFPS()); - m_mqtt.publish(FPSSensor.statTopic().c_str(), fpsCounter.c_str()); - + publishHeartbeat(); m_needHeartbeat = false; } } +void +MQTTTelemetry::publishHeartbeat() +{ + m_json.clear(); + m_json["device_id"] = Platform::deviceID(); + m_json["sketch_version"] = ESP.getSketchMD5(); + m_json["os_version"] = Platform::version(); + m_json["localip"] = WiFi.localIP().toString(); + m_json["pixelCount"] = Static::instance()->coordMap()->physicalPixelCount(); + m_json["loadedProfile"] = Static::instance()->loadedProfile(); + m_json["RSSI"] = WiFi.RSSI(); + m_json["free_ram"] = Platform::freeRam(); + m_json["fps"] = FastLED.getFPS(); + publishDoc(Lightswitch.heartbeatTopic().c_str()); + m_mqtt.publish(Device.availabilityTopic.c_str(), "online"); + + String fpsCounter = String(FastLED.getFPS()); + m_mqtt.publish(FPSSensor.statTopic().c_str(), fpsCounter.c_str()); +} + void MQTTTelemetry::callback(char* topic, const char* payload) { @@ -285,57 +296,6 @@ MQTTTelemetry::callback(char* topic, const char* payload) } } - if (m_json.containsKey("start")) { - strcpy(m_patternBuf, m_json["start"].as()); - setEvent(InputEvent{InputEvent::StartThing, m_patternBuf}); - } - - if (m_json.containsKey("stop")) { - if (m_json["stop"] == name) { - Log.warning("You can't kill an idea, or stop the MQTT Task via MQTT."); - } else { - strcpy(m_patternBuf, m_json["stop"].as()); - setEvent(InputEvent{InputEvent::StopThing, m_patternBuf}); - } - } - - if (m_json.containsKey("pixelCount")) { - Log.notice("Pixel count changed"); - setEvent(InputEvent{InputEvent::SetDisplayLength, m_json["pixelCount"].as()}); - } - - if (m_json.containsKey("startPixel")) { - Log.notice("Start pixel changed"); - setEvent(InputEvent{InputEvent::SetDisplayOffset, m_json["startPixel"].as()}); - } - - if (m_json.containsKey("loadConfig")) { - Log.notice("Loading new config"); - setEvent(InputEvent{InputEvent::LoadConfigurationByName, m_json["loadConfig"].as()}); - } - - if (m_json.containsKey("save")) { - setEvent(InputEvent{InputEvent::SaveConfigurationRequest}); - } - - if (m_json.containsKey("restart")) { - Platform::restart(); - } - - if (m_json.containsKey("reconnect")) { - m_mqtt.disconnect(); - } - - if (m_json.containsKey("ping")) { - m_needHeartbeat = true; - Log.notice("Queuing up heartbeat"); - } - - if (m_json.containsKey("effect")) { - strcpy(m_patternBuf, m_json["effect"].as()); - setEvent(InputEvent{InputEvent::SetScene, m_patternBuf}); - } - if (m_json.containsKey("color")) { uint8_t r = m_json["color"]["r"]; uint8_t g = m_json["color"]["g"]; diff --git a/src/platform/arduino/MQTTTelemetry.h b/src/platform/arduino/MQTTTelemetry.h index 433875a..80c676b 100644 --- a/src/platform/arduino/MQTTTelemetry.h +++ b/src/platform/arduino/MQTTTelemetry.h @@ -73,6 +73,10 @@ class MQTTTelemetry : public BufferedInputSource, OnlineTaskMixin, ConfigTaskMix void publishDoc(const char* topic); void publishDoc(const char* topic, bool retain); + void onMQTTOnline(); + void publishScenes(); + void publishHeartbeat(); + Sequencer *m_sequencer = 0; WiFiClient m_wifi; PubSubClient m_mqtt;