From 01a2857990dd5d45afc8b62531d6870017f4f66a Mon Sep 17 00:00:00 2001 From: Piotr Dobrowolski Date: Mon, 6 Mar 2017 17:56:37 +0100 Subject: [PATCH] Refucktor --- spejsiot/Endpoint.cpp | 110 ++---------------- spejsiot/Endpoint.h | 61 +++------- spejsiot/SpejsNode.cpp | 42 +++++-- spejsiot/SpejsNode.h | 3 + spejsiot/endpoints/DHTEndpoint.cpp | 29 +++++ spejsiot/endpoints/DHTEndpoint.h | 24 ++++ spejsiot/endpoints/ImplementationEndpoint.cpp | 71 +++++++++++ spejsiot/endpoints/ImplementationEndpoint.h | 18 +++ spejsiot/endpoints/OutputEndpoint.cpp | 22 ++++ spejsiot/endpoints/OutputEndpoint.h | 22 ++++ 10 files changed, 252 insertions(+), 150 deletions(-) create mode 100644 spejsiot/endpoints/DHTEndpoint.cpp create mode 100644 spejsiot/endpoints/DHTEndpoint.h create mode 100644 spejsiot/endpoints/ImplementationEndpoint.cpp create mode 100644 spejsiot/endpoints/ImplementationEndpoint.h create mode 100644 spejsiot/endpoints/OutputEndpoint.cpp create mode 100644 spejsiot/endpoints/OutputEndpoint.h diff --git a/spejsiot/Endpoint.cpp b/spejsiot/Endpoint.cpp index a4d9a0d..2086cae 100644 --- a/spejsiot/Endpoint.cpp +++ b/spejsiot/Endpoint.cpp @@ -16,107 +16,19 @@ void Endpoint::onConnected() { parent->notify(name + "/$type", type); } -EndpointResult OutputEndpoint::onValue(String property, String value) { - if (value == "1" or value == "on" or value == "true") { - currentValue = 1; - } else if (value == "0" or value == "off" or value == "false") { - currentValue = 0; - } else { - return 400; +void Endpoint::onMessage(String topic, String payload) { + String devicePrefix = parent->DEV_TOPIC(""); + + if(!topic.startsWith(devicePrefix)) { + Serial.println("ignoring"); + return; } - digitalWrite(pin, inverted ^ currentValue); - notify("on", currentValue ? "true" : "false"); - return 200; -} + int propPos = topic.indexOf("/", devicePrefix.length()); + String endpoint = topic.substring(devicePrefix.length(), propPos); + String property = topic.substring(propPos+1, topic.indexOf("/", propPos+1)); -void DHTEndpoint::bind(String _name, SpejsNode* _parent) { - Endpoint::bind(_name, _parent); - - sensor.begin(); - samplingTimer.initializeMs(samplingRate, TimerDelegate(&DHTEndpoint::sample, this)).start(); -} - -void DHTEndpoint::sample() { - TempAndHumidity th; - if(sensor.readTempAndHumidity(th)) - { - notify("degree", String(th.temp)); - notify("humidity", String(th.humid)); - } - else - { - Serial.print("Failed to read from DHT: "); - Serial.print(sensor.getLastError()); - } -} - -EndpointResult ImplementationEndpoint::onValue(String property, String value) { - if (property == "ota" and value == "true") { - startOTA(); - return 200; - } - return 400; -} - -void ImplementationEndpoint::startOTA() { - uint8_t slot; - rboot_config bootconf; - String romURL = OTA_URL + parent->deviceID + "/rom0.bin"; - String spiffsURL = OTA_URL + parent->deviceID + "/spiff_rom.bin"; - - Serial.println("Updating..."); - - // need a clean object, otherwise if run before and failed will not run again - if (otaUpdater) delete otaUpdater; - otaUpdater = new rBootHttpUpdate(); - - bootconf = rboot_get_config(); - - if (parent->currentSlot == 0) - slot = 1; - else - slot = 0; - - Serial.printf("Updating to rom %d.\r\n", slot); - - // flash rom to position indicated in the rBoot config rom table - otaUpdater->addItem(bootconf.roms[slot], romURL); - -#ifndef DISABLE_SPIFFS - // use user supplied values (defaults for 4mb flash in makefile) - if (slot == 0) { - otaUpdater->addItem(RBOOT_SPIFFS_0, spiffsURL); - } else { - otaUpdater->addItem(RBOOT_SPIFFS_1, spiffsURL); - } -#endif - - otaUpdater->setCallback(otaUpdateDelegate(&ImplementationEndpoint::otaUpdateCallback, this)); - otaUpdater->start(); - - notify("ota", "started"); -} - -void ImplementationEndpoint::otaUpdateCallback(rBootHttpUpdate& updater, bool result) { - if(result == true) { - // success - notify("ota", "finished"); - - uint8 slot; - - if (parent->currentSlot == 0) - slot = 1; - else - slot = 0; - - // set to boot new rom and then reboot - Serial.printf("Firmware updated, rebooting to rom %d...\r\n", slot); - - rboot_set_temp_rom(slot); - - System.restart(); - } else { - notify("ota", "failed"); + if(name.equals(endpoint)) { + Serial.printf("%s - %s response: %d\n", endpoint.c_str(), property.c_str(), onValue(property, payload).status); } } diff --git a/spejsiot/Endpoint.h b/spejsiot/Endpoint.h index 501ff96..be8b7f9 100644 --- a/spejsiot/Endpoint.h +++ b/spejsiot/Endpoint.h @@ -28,6 +28,7 @@ public: virtual void bind(String _name, SpejsNode* _parent); void notify(String property, String value); + virtual void onMessage(String topic, String payload); virtual EndpointResult onValue(String property, String value) { return 400; } @@ -35,22 +36,6 @@ public: void onConnected(); }; -class OutputEndpoint : public Endpoint { -private: - int pin; - bool inverted; - bool currentValue; - -public: - OutputEndpoint(int _pin, bool _inverted = false) : Endpoint("output"), - pin(_pin), inverted(_inverted), currentValue(inverted) { - pinMode(pin, OUTPUT); - digitalWrite(pin, currentValue); - } - - EndpointResult onValue(String property, String value); -}; - template class ValueEndpoint : public Endpoint { protected: T value; @@ -60,35 +45,27 @@ public: ValueEndpoint(String _type) : Endpoint(_type) {} }; -#include - -class DHTEndpoint : public ValueEndpoint { -private: - DHT sensor; - Timer samplingTimer; - int samplingRate; - -protected: - void sample(); - -public: - DHTEndpoint(int _pin, int _samplingRate = 10000, int _sensor_type=DHT11) : - ValueEndpoint("dht"), sensor(_pin, _sensor_type), - samplingRate(_samplingRate) {} - - void bind(String name, SpejsNode* _parent); +struct endpoint_def { + char* name; + Endpoint* (*constructor)(void); }; -class ImplementationEndpoint : public Endpoint { -protected: - rBootHttpUpdate* otaUpdater = 0; +//extern int __papiez_pedofil; -public: - ImplementationEndpoint() : Endpoint("$implementation") {} +extern struct endpoint_def* __stop_endpoints[]; +extern struct endpoint_def* __start_endpoints[]; - EndpointResult onValue(String property, String value); - void otaUpdateCallback(rBootHttpUpdate& updater, bool result); - void startOTA(); -}; + +#define DECLARE_ENDPOINT(name, constructor) \ + struct endpoint_def name ## _def __attribute__ ((section (".endpoints"))) = {\ + (char*) #name, constructor \ + }; + +// static struct endpoint_def name ## _def = { \ +// (char*) #name, constructor \ +// }; \ +//& name##_def + +#define ENDPOINTS_COUNT (((uint8_t*) __stop_endpoints - (uint8_t*) __start_endpoints) / sizeof(struct endpoint_def)) #endif diff --git a/spejsiot/SpejsNode.cpp b/spejsiot/SpejsNode.cpp index 8d0aaac..5575490 100644 --- a/spejsiot/SpejsNode.cpp +++ b/spejsiot/SpejsNode.cpp @@ -2,6 +2,8 @@ #include #include +#include + void SpejsNode::init() { deviceID = WifiStation.getMAC().substring(6, 12); @@ -26,6 +28,25 @@ void SpejsNode::init() { }); registerEndpoint("$implementation", new ImplementationEndpoint()); + + loadJSON(); +} + +//extern int __papiez_pedofil; + +void SpejsNode::loadJSON() { + /* + Serial.printf("start: %08x\n", __start_endpoints); + Serial.printf("stop: %08x\n", __stop_endpoints); + Serial.printf("Endpoints count: %d\n", ENDPOINTS_COUNT); + + + for(int i = 0; i < ENDPOINTS_COUNT; i++) { + struct endpoint_def* endpoint = __start_endpoints[i]; + Serial.printf(" -> %08x\r\n", endpoint); + Serial.printf(" -> name: %s\r\n", endpoint->name); + } + */ } void SpejsNode::keepAliveHandler() { @@ -54,7 +75,11 @@ void SpejsNode::keepAliveHandler() { } } -#define DEV_TOPIC(t) (TOPIC_PREFIX + deviceID + "/" + t) +//#define DEV_TOPIC(t) (TOPIC_PREFIX + deviceID + "/" + t) + +inline String SpejsNode::DEV_TOPIC(String t) { + return TOPIC_PREFIX + deviceID + "/" + t; +} void SpejsNode::httpIndex(HttpRequest &request, HttpResponse &response) { @@ -135,6 +160,7 @@ void SpejsNode::httpFile(HttpRequest &request, HttpResponse &response) void SpejsNode::initializeMDNS() { + /* static struct mdns_info *info = (struct mdns_info *)os_zalloc(sizeof(struct mdns_info)); char tmp_name[32]; ("iot-" + deviceID).toCharArray(tmp_name, 32); @@ -153,6 +179,7 @@ void SpejsNode::initializeMDNS() { info->txt_data[1] = tmp_type; espconn_mdns_init(info); + */ } /* @@ -180,14 +207,7 @@ void SpejsNode::registerEndpoint(String key, Endpoint* endpoint) { } void SpejsNode::mqttCallback(String origtopic, String value) { - String devicePrefix = DEV_TOPIC(""); - - if(!origtopic.startsWith(devicePrefix)) { - Serial.println("ignoring"); - return; - } - - int propPos = origtopic.indexOf("/", devicePrefix.length()); + /*int propPos = origtopic.indexOf("/", devicePrefix.length()); String endpoint = origtopic.substring(devicePrefix.length(), propPos); String property = origtopic.substring(propPos+1, origtopic.indexOf("/", propPos+1)); @@ -195,5 +215,9 @@ void SpejsNode::mqttCallback(String origtopic, String value) { Serial.printf("%s - %s response: %d\n", endpoint.c_str(), property.c_str(), endpoints[endpoint]->onValue(property, value).status); } else { Serial.println("unknown topic? " + endpoint); + }*/ + + for(unsigned int i = 0 ; i < endpoints.count() ; i++) { + endpoints.valueAt(i)->onMessage(origtopic, value); } } diff --git a/spejsiot/SpejsNode.h b/spejsiot/SpejsNode.h index fd934d1..f4da607 100644 --- a/spejsiot/SpejsNode.h +++ b/spejsiot/SpejsNode.h @@ -53,6 +53,9 @@ public: void registerEndpoint(String key, Endpoint* cb); + String DEV_TOPIC(String t); + + void loadJSON(); }; #endif diff --git a/spejsiot/endpoints/DHTEndpoint.cpp b/spejsiot/endpoints/DHTEndpoint.cpp new file mode 100644 index 0000000..3f58ce7 --- /dev/null +++ b/spejsiot/endpoints/DHTEndpoint.cpp @@ -0,0 +1,29 @@ +#include + +void DHTEndpoint::bind(String _name, SpejsNode* _parent) { + Endpoint::bind(_name, _parent); + + sensor.begin(); + samplingTimer.initializeMs(samplingRate, TimerDelegate(&DHTEndpoint::sample, this)).start(); +} + +void DHTEndpoint::sample() { + TempAndHumidity th; + if(sensor.readTempAndHumidity(th)) + { + notify("degree", String(th.temp)); + notify("humidity", String(th.humid)); + } + else + { + Serial.print("Failed to read from DHT: "); + Serial.print(sensor.getLastError()); + } +} + +DECLARE_ENDPOINT( + kolejnypapiez, + *[]() { + return (Endpoint*) new DHTEndpoint(5); + } +); diff --git a/spejsiot/endpoints/DHTEndpoint.h b/spejsiot/endpoints/DHTEndpoint.h new file mode 100644 index 0000000..03bae83 --- /dev/null +++ b/spejsiot/endpoints/DHTEndpoint.h @@ -0,0 +1,24 @@ +#ifndef DHTENDPOINT_H +#define DHTENDPOINT_H + +#include +#include + +class DHTEndpoint : public ValueEndpoint { +private: + DHT sensor; + Timer samplingTimer; + int samplingRate; + +protected: + void sample(); + +public: + DHTEndpoint(int _pin, int _samplingRate = 10000, int _sensor_type=DHT11) : + ValueEndpoint("dht"), sensor(_pin, _sensor_type), + samplingRate(_samplingRate) {} + + void bind(String name, SpejsNode* _parent); +}; + +#endif diff --git a/spejsiot/endpoints/ImplementationEndpoint.cpp b/spejsiot/endpoints/ImplementationEndpoint.cpp new file mode 100644 index 0000000..4e30ab1 --- /dev/null +++ b/spejsiot/endpoints/ImplementationEndpoint.cpp @@ -0,0 +1,71 @@ +#include + +EndpointResult ImplementationEndpoint::onValue(String property, String value) { + if (property == "ota" and value == "true") { + startOTA(); + return 200; + } + return 400; +} + +void ImplementationEndpoint::startOTA() { + uint8_t slot; + rboot_config bootconf; + String romURL = OTA_URL + parent->deviceID + "/rom0.bin"; + String spiffsURL = OTA_URL + parent->deviceID + "/spiff_rom.bin"; + + Serial.println("Updating..."); + + // need a clean object, otherwise if run before and failed will not run again + if (otaUpdater) delete otaUpdater; + otaUpdater = new rBootHttpUpdate(); + + bootconf = rboot_get_config(); + + if (parent->currentSlot == 0) + slot = 1; + else + slot = 0; + + Serial.printf("Updating to rom %d.\r\n", slot); + + // flash rom to position indicated in the rBoot config rom table + otaUpdater->addItem(bootconf.roms[slot], romURL); + +#ifndef DISABLE_SPIFFS + // use user supplied values (defaults for 4mb flash in makefile) + if (slot == 0) { + otaUpdater->addItem(RBOOT_SPIFFS_0, spiffsURL); + } else { + otaUpdater->addItem(RBOOT_SPIFFS_1, spiffsURL); + } +#endif + + otaUpdater->setCallback(otaUpdateDelegate(&ImplementationEndpoint::otaUpdateCallback, this)); + otaUpdater->start(); + + notify("ota", "started"); +} + +void ImplementationEndpoint::otaUpdateCallback(rBootHttpUpdate& updater, bool result) { + if(result == true) { + // success + notify("ota", "finished"); + + uint8 slot; + + if (parent->currentSlot == 0) + slot = 1; + else + slot = 0; + + // set to boot new rom and then reboot + Serial.printf("Firmware updated, rebooting to rom %d...\r\n", slot); + + rboot_set_temp_rom(slot); + + System.restart(); + } else { + notify("ota", "failed"); + } +} diff --git a/spejsiot/endpoints/ImplementationEndpoint.h b/spejsiot/endpoints/ImplementationEndpoint.h new file mode 100644 index 0000000..28df0e1 --- /dev/null +++ b/spejsiot/endpoints/ImplementationEndpoint.h @@ -0,0 +1,18 @@ +#ifndef IMPLEMENTATIONENDPOINT_H +#define IMPLEMENTATIONENDPOINT_H + +#include +#include + +class ImplementationEndpoint : public Endpoint { +protected: + rBootHttpUpdate* otaUpdater = 0; + +public: + ImplementationEndpoint() : Endpoint("$implementation") {} + + EndpointResult onValue(String property, String value); + void otaUpdateCallback(rBootHttpUpdate& updater, bool result); + void startOTA(); +}; +#endif diff --git a/spejsiot/endpoints/OutputEndpoint.cpp b/spejsiot/endpoints/OutputEndpoint.cpp new file mode 100644 index 0000000..6cf95d6 --- /dev/null +++ b/spejsiot/endpoints/OutputEndpoint.cpp @@ -0,0 +1,22 @@ +#include + +EndpointResult OutputEndpoint::onValue(String property, String value) { + if (value == "1" or value == "on" or value == "true") { + currentValue = 1; + } else if (value == "0" or value == "off" or value == "false") { + currentValue = 0; + } else { + return 400; + } + + digitalWrite(pin, inverted ^ currentValue); + notify("on", currentValue ? "true" : "false"); + return 200; +} + +DECLARE_ENDPOINT( + papiezpedofilxD, + *[]() { + return (Endpoint*) new OutputEndpoint(5); + } +); diff --git a/spejsiot/endpoints/OutputEndpoint.h b/spejsiot/endpoints/OutputEndpoint.h new file mode 100644 index 0000000..7ac85be --- /dev/null +++ b/spejsiot/endpoints/OutputEndpoint.h @@ -0,0 +1,22 @@ +#ifndef OUTPUTENDPOINT_H +#define OUTPUTENDPOINT_H value + +#include + +class OutputEndpoint : public Endpoint { +private: + int pin; + bool inverted; + bool currentValue; + +public: + OutputEndpoint(int _pin, bool _inverted = false) : Endpoint("output"), + pin(_pin), inverted(_inverted), currentValue(inverted) { + pinMode(pin, OUTPUT); + digitalWrite(pin, currentValue); + } + + EndpointResult onValue(String property, String value); +}; + +#endif /* ifndef OUTPUTENDPOINT_H */