diff --git a/README.md b/README.md index c1a1139b..f053e5b2 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,38 @@ # ESPurna -ESPurna ("spark" in Catalan) is a custom C firmware for [ITead Sonoff][1] Smart WiFi Switch. -This device has an ESP8266 on board with a 8Mbit flash memory chip, a mains to 3V3 transformer -and a relay (GPIO12). It also features a button (GPIO0), an LED (GPIO13) and an unpopulated header you can use to reprogram it. +ESPurna ("spark" in Catalan) is a custom C firmware for ESP8266 based smart switches. It was originally developed with the **[ITead Sonoff][1]** in mind. This device has an ESP8266 on board with a 8Mbit flash memory chip, a mains to 3V3 transformer and a relay (GPIO12). It also features a button (GPIO0), an LED (GPIO13) and an unpopulated header you can use to reprogram it. You can read about this board and firmware in [my blog][2]. ![Sonoff board - front view](/images/pinout_front.jpg) ![Sonoff board - back view](/images/pinout_back.jpg) +## Hardware support + +* [ITead Sonoff TH][1] +* [ITead Sonoff RF][8] +* [ITead Slampher][9] +* [ITead S20 Smart Socket][10] +* Tinkerman ESPurna board + ## Features -* WebServer for configuration and simple relay toggle -* Flashing firmware Over-The-Air (OTA) -* Up to 3 configurable WIFI networks -* MQTT support with configurable host and topic +* **WebServer for configuration** and simple relay toggle +* **Flashing firmware Over-The-Air** (OTA) +* Up to **3 configurable WIFI networks** +* **MQTT support** with configurable host and topic * Manual switch ON/OFF with button (single click the button) * AP mode backup (double click the button) -* Support for custom RF module (check blog post) * Visual status of the connection via the LED +* Support for custom **[RF module][2]** +* Support for **automatic over-the-air updates** through the [NoFUSS Library][6] +* Support for **current monitoring** through then [EmonLiteESP Library][7] +* Support for **DHT22** sensors + ## Flashing -The unpopulated header has all the required pins. My board has a 5 pins header -in-line with the button. They are (from the button outwards): +The unpopulated header has all the required pins. My board has a 5 pins header in-line with the button. They are (from the button outwards): * 3V3 * RX @@ -31,14 +40,10 @@ in-line with the button. They are (from the button outwards): * GND * GPIO14 -Last one is not necessary. Mind it's a **3V3 device**, if connected to 5V you will -probably fry it. Button is connected to GPIO0 on the ESP8266 chip, so to enter -flash mode you have to hold the button pressed while powering on the board, then -you can realease it again. +Last one is not necessary. Mind it's a **3V3 device**, if connected to 5V you will probably fry it. Button is connected to GPIO0 on the ESP8266 chip, so to enter flash mode you have to hold the button pressed while powering on the board, then you can realease it again. The project is ready to be build using [PlatformIO][3]. -Please refer to their web page for instructions on how to install the builder. -Once installed: +Please refer to their web page for instructions on how to install the builder. Once installed: ```bash > platformio run --target upload -e wire @@ -59,36 +64,28 @@ When using OTA environment it defaults to the IP address of the device in SoftAP > platformio run --target uploadfs -e ota --upload-port 192.168.1.151 ``` +You can also use the automatic OTA update feature. Check the [NoFUSS library][6] for more info. Library dependencies are automatically managed via PlatformIO Library Manager. ## Usage -On normal boot (i.e. button not pressed) it will execute the firmware. -It configures the hardware (button, LED, relay), the SPIFFS memory access, the -WIFI, the WebServer and MQTT connection. +On normal boot (i.e. button not pressed) it will execute the firmware. It configures the hardware (button, LED, relay), the SPIFFS memory access, the WIFI, the WebServer and MQTT connection. -Obviously the default values for WIFI network and MQTT will probably not match -your requirements. The device will start in Soft AP creating a WIFI SSID named "SONOFF_XXXXXX", where XXXXXX are the last 3 bytes of the radio MAC. Connect with -phone, PC, laptop, whatever to that network, password is "fibonacci". Once connected -browse to 192.168.4.1 and you will be presented a configuration page where you will -be able to define up to 3 possible WIFI networks and the MQTT configuration parameters. +Obviously the default values for WIFI network and MQTT will probably not match your requirements. The device will start in Soft AP creating a WIFI SSID named "SONOFF_XXXXXX", where XXXXXX are the last 3 bytes of the radio MAC. Connect with phone, PC, laptop, whatever to that network, password is "fibonacci". Once connected +browse to 192.168.4.1 and you will be presented a configuration page where you will be able to define up to 3 possible WIFI networks and the MQTT configuration parameters. -It will then try to connect to the first WIFI network. If fail it will try the second -in 30 seconds, and so on. Once connected it will try to connect the MQTT server. If there are no configured networks or none of the configured ones is reachable it defaults to SoftAP mode. You can also switch to SoftAP mode by double clicking the on board button. +It will then try to connect to the configure WIFI networks one after the other. If none of the 3 attempts succeed it will default to SoftAP mode again. Once connected it will try to connect the MQTT server. You can also switch to SoftAP mode by long clicking the on board button or reset the board double clicking the it. -The device will publish the relay state to the given topic and it will subscribe to -the same topic plus "/set" for remote switching. So if your topic is "/home/living/switch" -you will be able to switch it on/off sending "1"/"0" to "/home/living/switch/set". +The device will publish the relay state to the given topic and it will subscribe to the same topic for remote switching. Don't worry, it avoids infinite loops. -You can also use "{identifier}" as place holder in the topic. It will be translated to -your device ID (same as the soft AP network it creates). +You can also use "{identifier}" as place holder in the topic. It will be translated to your device ID (same as the soft AP network it creates). ## Troubleshooting After flashing the firmware via serial do a hard reset of the device (unplug & plug). There is an issue with the ESP.reset() method. Check [https://github.com/esp8266/Arduino/issues/1017][4] for more info. -Current version of ESP8266httpUpdate restarts the modules after SPIFFS update, thus preventing the firmware to be updated too. There is a recent commit fixing that which is not yet pushed to PLatformIO. Check [Fix example for ESP8266httpUpdate][5] for more info. +Current version of ESP8266httpUpdate restarts the modules after SPIFFS update, thus preventing the firmware to be updated too. There is a recent commit fixing that which is not yet pushed to PLatformIO. Check [Fix example for ESP8266httpUpdate][5] for more info. Anyway, current expected behaviour is to not resetting the board from the ESP8266httpUpdate class (comment out line 300 in ```ESP8266httpUpdate.cpp```). [1]: https://www.itead.cc/sonoff-wifi-wireless-switch.html @@ -96,3 +93,8 @@ Current version of ESP8266httpUpdate restarts the modules after SPIFFS update, t [3]: http://www.platformio.org [4]: https://github.com/esp8266/Arduino/issues/1017 [5]: https://github.com/esp8266/Arduino/pull/2251 +[6]: https://bitbucket.org/xoseperez/nofuss +[7]: https://bitbucket.org/xoseperez +[8]: https://www.itead.cc/sonoff-rf.html +[9]: https://www.itead.cc/slampher-wifi-wireless-light-holder.html +[10]: https://www.itead.cc/smart-socket-eu.html diff --git a/code/lib/AutoOTA/AutoOTA.cpp b/code/lib/AutoOTA/AutoOTA.cpp deleted file mode 100644 index d96e58bd..00000000 --- a/code/lib/AutoOTA/AutoOTA.cpp +++ /dev/null @@ -1,145 +0,0 @@ -#include "AutoOTA.h" -#include -#include -#include - -void AutoOTAClass::setServer(String server) { - _server = server; -} - -void AutoOTAClass::setModel(String model) { - _model = model; -} - -void AutoOTAClass::setVersion(String version) { - _version = version; -} - -void AutoOTAClass::onMessage(TMessageFunction fn) { - _callback = fn; -} - -String AutoOTAClass::getNewVersion() { - return _newVersion; -} - -String AutoOTAClass::getNewFirmware() { - return _newFirmware; -} - -String AutoOTAClass::getNewFileSystem() { - return _newFileSystem; -} - -int AutoOTAClass::getErrorNumber() { - return _errorNumber; -} - -String AutoOTAClass::getErrorString() { - return _errorString; -} - -String AutoOTAClass::_getPayload() { - - HTTPClient http; - char url[100]; - String payload = ""; - - _callback(AUTO_OTA_START); - - sprintf(url, "%s/%s/%s", _server.c_str(), _model.c_str(), _version.c_str()); - http.begin(url); - int httpCode = http.GET(); - if (httpCode > 0) payload = http.getString(); - http.end(); - - return payload; - -} - -bool AutoOTAClass::_checkUpdates() { - - String payload = _getPayload(); - if (payload.length() == 0) { - _callback(AUTO_OTA_NO_RESPONSE_ERROR); - return false; - } - - StaticJsonBuffer<500> jsonBuffer; - JsonObject& response = jsonBuffer.parseObject(payload); - - if (!response.success()) { - _callback(AUTO_OTA_PARSE_ERROR); - return false; - } - - if (response.size() == 0) { - _callback(AUTO_OTA_UPTODATE); - return false; - } - - _newVersion = response.get("version"); - _newFileSystem = response.get("spiffs"); - _newFirmware = response.get("firmware"); - - _callback(AUTO_OTA_UPDATING); - return true; - -} - -void AutoOTAClass::_doUpdate() { - - char url[100]; - bool error = false; - uint8_t updates = 0; - - if (_newFileSystem.length() > 0) { - - // Update SPIFFS - sprintf(url, "%s/%s", _server.c_str(), _newFileSystem.c_str()); - t_httpUpdate_return ret = ESPhttpUpdate.updateSpiffs(url); - - if (ret == HTTP_UPDATE_FAILED) { - error = true; - _errorNumber = ESPhttpUpdate.getLastError(); - _errorString = ESPhttpUpdate.getLastErrorString(); - _callback(AUTO_OTA_FILESYSTEM_UPDATE_ERROR); - } else if (ret == HTTP_UPDATE_OK) { - updates++; - _callback(AUTO_OTA_FILESYSTEM_UPDATED); - } - - } - - if (!error && (_newFirmware.length() > 0)) { - - // Update binary - sprintf(url, "%s%s", _server.c_str(), _newFirmware.c_str()); - t_httpUpdate_return ret = ESPhttpUpdate.update(url); - - if (ret == HTTP_UPDATE_FAILED) { - error = true; - _errorNumber = ESPhttpUpdate.getLastError(); - _errorString = ESPhttpUpdate.getLastErrorString(); - _callback(AUTO_OTA_FIRMWARE_UPDATE_ERROR); - } else if (ret == HTTP_UPDATE_OK) { - updates++; - _callback(AUTO_OTA_FIRMWARE_UPDATED); - } - - } - - if (!error && (updates > 0)) { - _callback(AUTO_OTA_RESET); - ESP.restart(); - } - -} - -void AutoOTAClass::handle() { - _callback(AUTO_OTA_START); - if (_checkUpdates()) _doUpdate(); - _callback(AUTO_OTA_END); -} - -AutoOTAClass AutoOTA; diff --git a/code/lib/AutoOTA/AutoOTA.h b/code/lib/AutoOTA/AutoOTA.h deleted file mode 100644 index 8c0a3744..00000000 --- a/code/lib/AutoOTA/AutoOTA.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef _AUTO_OTA_h -#define _AUTO_OTA_h - -#include -#include -#include - -typedef enum { - AUTO_OTA_START, - AUTO_OTA_UPTODATE, - AUTO_OTA_UPDATING, - AUTO_OTA_FILESYSTEM_UPDATED, - AUTO_OTA_FIRMWARE_UPDATED, - AUTO_OTA_RESET, - AUTO_OTA_END, - AUTO_OTA_NO_RESPONSE_ERROR, - AUTO_OTA_PARSE_ERROR, - AUTO_OTA_FILESYSTEM_UPDATE_ERROR, - AUTO_OTA_FIRMWARE_UPDATE_ERROR -} auto_ota_t; - -class AutoOTAClass { - - public: - - typedef std::function TMessageFunction; - - void setServer(String server); - void setModel(String model); - void setVersion(String version); - - String getNewVersion(); - String getNewFirmware(); - String getNewFileSystem(); - - int getErrorNumber(); - String getErrorString(); - - void onMessage(TMessageFunction fn); - void handle(); - - private: - - String _server; - String _model; - String _version; - - String _newVersion; - String _newFirmware; - String _newFileSystem; - - int _errorNumber; - String _errorString; - - TMessageFunction _callback; - - String _getPayload(); - bool _checkUpdates(); - void _doUpdate(); - -}; - -extern AutoOTAClass AutoOTA; - -#endif /* _AUTO_OTA_h */ diff --git a/code/src/Config.cpp b/code/src/Config.cpp index d246ba6a..a00df8a2 100644 --- a/code/src/Config.cpp +++ b/code/src/Config.cpp @@ -29,8 +29,8 @@ bool ConfigClass::save() { content += "mqttTopic=" + mqttTopic + "|"; content += "rfChannel=" + rfChannel + "|"; content += "rfDevice=" + rfDevice + "|"; - content += "otaServer=" + otaServer + "|"; - content += "otaInterval=" + otaInterval + "|"; + content += "nofussServer=" + nofussServer + "|"; + content += "nofussInterval=" + nofussInterval + "|"; content += "pwMainsVoltage=" + pwMainsVoltage + "|"; content += "pwCurrentRatio=" + pwCurrentRatio + "|"; @@ -92,8 +92,8 @@ bool ConfigClass::load() { else if (line.startsWith("mqttTopic=")) mqttTopic = line.substring(10); else if (line.startsWith("rfChannel=")) rfChannel = line.substring(10); else if (line.startsWith("rfDevice=")) rfDevice = line.substring(9); - else if (line.startsWith("otaServer=")) otaServer = line.substring(10); - else if (line.startsWith("otaInterval=")) otaInterval = line.substring(12); + else if (line.startsWith("nofussServer=")) nofussServer = line.substring(13); + else if (line.startsWith("nofussInterval=")) nofussInterval = line.substring(15); else if (line.startsWith("pwMainsVoltage=")) pwMainsVoltage = line.substring(15); else if (line.startsWith("pwCurrentRatio=")) pwCurrentRatio = line.substring(15); diff --git a/code/src/Config.h b/code/src/Config.h index b9714eca..00403c4c 100644 --- a/code/src/Config.h +++ b/code/src/Config.h @@ -22,8 +22,8 @@ #define MQTT_PORT 1883 #define MQTT_TOPIC "/test/switch/{identifier}" -#define AUTOOTA_SERVER "http://192.168.1.100" -#define AUTOOTA_INTERVAL 600000 +#define NOFUSS_SERVER "http://192.168.1.100" +#define NOFUSS_INTERVAL 600000 #define MAINS_VOLTAGE 230 #define CURRENT_RATIO 180 @@ -53,8 +53,8 @@ class ConfigClass { String rfChannel = String(RF_CHANNEL); String rfDevice = String(RF_DEVICE); - String otaServer = String(AUTOOTA_SERVER); - String otaInterval = String(AUTOOTA_INTERVAL); + String nofussServer = String(NOFUSS_SERVER); + String nofussInterval = String(NOFUSS_INTERVAL); String pwMainsVoltage = String(MAINS_VOLTAGE); String pwCurrentRatio = String(CURRENT_RATIO); diff --git a/code/src/main.cpp b/code/src/main.cpp index d9f43fb2..35c8d39e 100644 --- a/code/src/main.cpp +++ b/code/src/main.cpp @@ -30,7 +30,7 @@ along with this program. If not, see . #include "FS.h" #include "Config.h" -#include "AutoOTA.h" +#include "NoFUSSClient.h" #include #include @@ -52,7 +52,7 @@ along with this program. If not, see . #define ENABLE_RF 0 #define ENABLE_OTA 1 -#define ENABLE_OTA_AUTO 0 +#define ENABLE_NOFUSS 1 #define ENABLE_MQTT 1 #define ENABLE_WEBSERVER 1 #define ENABLE_ENERGYMONITOR 0 @@ -273,6 +273,85 @@ void toggleRelay() { } } +// ----------------------------------------------------------------------------- +// NoFUSS +// ----------------------------------------------------------------------------- + +#if ENABLE_NOFUSS + + void nofussSetup() { + + NoFUSSClient.setServer(config.nofussServer); + NoFUSSClient.setDevice(MODEL); + NoFUSSClient.setVersion(APP_VERSION); + + NoFUSSClient.onMessage([](nofuss_t code) { + + if (code == NOFUSS_START) { + Serial.println(F("[NoFUSS] Start")); + } + + if (code == NOFUSS_UPTODATE) { + Serial.println(F("[NoFUSS] Already in the last version")); + } + + if (code == NOFUSS_PARSE_ERROR) { + Serial.println(F("[NoFUSS] Error parsing server response")); + } + + if (code == NOFUSS_UPDATING) { + Serial.println(F("[NoFUSS] Updating")); + Serial.print( F(" New version: ")); + Serial.println(NoFUSSClient.getNewVersion()); + Serial.print( F(" Firmware: ")); + Serial.println(NoFUSSClient.getNewFirmware()); + Serial.print( F(" File System: ")); + Serial.println(NoFUSSClient.getNewFileSystem()); + } + + if (code == NOFUSS_FILESYSTEM_UPDATE_ERROR) { + Serial.print(F("[NoFUSS] File System Update Error: ")); + Serial.println(NoFUSSClient.getErrorString()); + } + + if (code == NOFUSS_FILESYSTEM_UPDATED) { + Serial.println(F("[NoFUSS] File System Updated")); + } + + if (code == NOFUSS_FIRMWARE_UPDATE_ERROR) { + Serial.print(F("[NoFUSS] Firmware Update Error: ")); + Serial.println(NoFUSSClient.getErrorString()); + } + + if (code == NOFUSS_FIRMWARE_UPDATED) { + Serial.println(F("[NoFUSS] Firmware Updated")); + } + + if (code == NOFUSS_RESET) { + Serial.println(F("[NoFUSS] Resetting board")); + } + + if (code == NOFUSS_END) { + Serial.println(F("[NoFUSS] End")); + } + + }); + + } + + void nofussLoop() { + + static unsigned long last_check = 0; + if (WiFi.status() != WL_CONNECTED) return; + if ((last_check > 0) && ((millis() - last_check) < config.nofussInterval.toInt())) return; + last_check = millis(); + NoFUSSClient.handle(); + + } + +#endif + + // ----------------------------------------------------------------------------- // OTA // ----------------------------------------------------------------------------- @@ -320,83 +399,11 @@ void toggleRelay() { #endif }); - #if ENABLE_OTA_AUTO - - AutoOTA.setServer(config.otaServer); - AutoOTA.setModel(MODEL); - AutoOTA.setVersion(APP_VERSION); - - AutoOTA.onMessage([](auto_ota_t code) { - - if (code == AUTO_OTA_FILESYSTEM_UPDATED) { - #ifdef DEBUG - Serial.print(F("[AUTOOTA] File System Updated")); - #endif - config.save(); - } - #ifdef DEBUG - - if (code == AUTO_OTA_START) { - Serial.println(F("[AUTOOTA] Start")); - } - - if (code == AUTO_OTA_UPTODATE) { - Serial.println(F("[AUTOOTA] Already in the last version")); - } - - if (code == AUTO_OTA_PARSE_ERROR) { - Serial.println(F("[AUTOOTA] Error parsing server response")); - } - - if (code == AUTO_OTA_UPDATING) { - Serial.println(F("[AUTOOTA] Updating")); - Serial.print( F(" New version: ")); - Serial.println(AutoOTA.getNewVersion()); - Serial.print( F(" Firmware: ")); - Serial.println(AutoOTA.getNewFirmware()); - Serial.print( F(" File System: ")); - Serial.println(AutoOTA.getNewFileSystem()); - } - - if (code == AUTO_OTA_FILESYSTEM_UPDATE_ERROR) { - Serial.print(F("[AUTOOTA] File System Update Error: ")); - Serial.println(AutoOTA.getErrorString()); - } - - if (code == AUTO_OTA_FIRMWARE_UPDATE_ERROR) { - Serial.print(F("[AUTOOTA] Firmware Update Error: ")); - Serial.println(AutoOTA.getErrorString()); - } - - if (code == AUTO_OTA_FIRMWARE_UPDATED) { - Serial.print(F("[AUTOOTA] Firmware Updated")); - } - - if (code == AUTO_OTA_RESET) { - Serial.println(F("[AUTOOTA] Resetting board")); - } - - if (code == AUTO_OTA_END) { - Serial.println(F("[AUTOOTA] End")); - } - - #endif - }); - - #endif - ArduinoOTA.begin(); } void OTALoop() { - #if ENABLE_OTA_AUTO - static unsigned long last_check = 0; - if (WiFi.status() != WL_CONNECTED) return; - if ((last_check > 0) && ((millis() - last_check) < config.otaInterval.toInt())) return; - last_check = millis(); - AutoOTA.handle(); - #endif ArduinoOTA.handle(); } @@ -481,21 +488,27 @@ void wifiSetupSTA() { #endif if (WiFi.status() == WL_CONNECTED) { + WiFi.setAutoConnect(true); status = WIFI_STATUS_CONNECTED; + #ifdef DEBUG Serial.print(F("[WIFI] STATION Mode, SSID: ")); Serial.print(WiFi.SSID()); Serial.print(F(", IP address: ")); Serial.println(WiFi.localIP()); #endif - #if ENABLE_OTA_AUTO - AutoOTA.handle(); + + #if ENABLE_NOFUSS + NoFUSSClient.handle(); #endif + } else { + #ifdef DEBUG Serial.println(F("[WIFI] Not connected")); #endif + } } @@ -1180,6 +1193,9 @@ void setup() { #if ENABLE_OTA OTASetup(); #endif + #if ENABLE_NOFUSS + nofussSetup(); + #endif #if ENABLE_MQTT mqttSetup(); #endif @@ -1206,6 +1222,9 @@ void loop() { #if ENABLE_OTA OTALoop(); #endif + #if ENABLE_NOFUSS + nofussLoop(); + #endif #if ENABLE_MQTT mqttLoop(); #endif diff --git a/server/.gitignore b/server/.gitignore deleted file mode 100644 index d66a419a..00000000 --- a/server/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/cache/ -/vendor/ -/logs/* -!/logs/README.md diff --git a/server/README.md b/server/README.md deleted file mode 100644 index 438f9acc..00000000 --- a/server/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# ESPurna Update Server - -First version of an ESPurna update server, an API that responfs to ESPurna devices with information about the last available firmware. - -## Use - -1. Modify ```data/versions.js``` with info about available firmware versions depending on current model (device type) and firmware version. -1. Perform GET queries against http:////, for instance: ```http://192.168.1.105/espurna/0.9.1``` diff --git a/server/composer.json b/server/composer.json deleted file mode 100644 index 9fb9927f..00000000 --- a/server/composer.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "tinkerman/espurna-update-server", - "description": "Update server that listen to ESPurna devices queries and returns last available firmware", - "keywords": ["esp8266", "ota", "espurna", "firmware"], - "homepage": "http://tinkerman.cat", - "license": "GPLv3", - "authors": [ - { - "name": "Xose PĂ©rez", - "email": "xose.perez@gmail.com", - "homepage": "http://tinkerman.cat/" - } - ], - "require": { - "php": ">=5.5.0", - "slim/slim": "^3.1", - "slim/php-view": "^2.0", - "monolog/monolog": "^1.17", - "slim/twig-view": "^2.1", - "akrabat/rka-ip-address-middleware": "^0.4.0" - } -} diff --git a/server/composer.lock b/server/composer.lock deleted file mode 100644 index 4b3198e9..00000000 --- a/server/composer.lock +++ /dev/null @@ -1,580 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", - "This file is @generated automatically" - ], - "hash": "6cce6f8ddf6f041bbf61a8c85f1cb7a3", - "content-hash": "e9593bb6457c08a899298c347997dd68", - "packages": [ - { - "name": "akrabat/rka-ip-address-middleware", - "version": "0.4", - "source": { - "type": "git", - "url": "https://github.com/akrabat/rka-ip-address-middleware.git", - "reference": "1c9947fdbaad04614e8b15d55f191f11c39293d1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/akrabat/rka-ip-address-middleware/zipball/1c9947fdbaad04614e8b15d55f191f11c39293d1", - "reference": "1c9947fdbaad04614e8b15d55f191f11c39293d1", - "shasum": "" - }, - "require": { - "psr/http-message": "^1.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8", - "squizlabs/php_codesniffer": "^2.3", - "zendframework/zend-diactoros": "^1.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "RKA\\Middleware\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Rob Allen", - "email": "rob@akrabat.com", - "homepage": "http://akrabat.com" - } - ], - "description": "PSR-7 Middleware that determines the client IP address and stores it as an ServerRequest attribute", - "homepage": "http://github.com/akrabat/rka-ip-address-middleware", - "keywords": [ - "IP", - "middleware", - "psr7" - ], - "time": "2015-11-06 10:38:17" - }, - { - "name": "container-interop/container-interop", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/container-interop/container-interop.git", - "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/container-interop/container-interop/zipball/fc08354828f8fd3245f77a66b9e23a6bca48297e", - "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e", - "shasum": "" - }, - "type": "library", - "autoload": { - "psr-4": { - "Interop\\Container\\": "src/Interop/Container/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", - "time": "2014-12-30 15:22:37" - }, - { - "name": "monolog/monolog", - "version": "1.20.0", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/monolog.git", - "reference": "55841909e2bcde01b5318c35f2b74f8ecc86e037" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/55841909e2bcde01b5318c35f2b74f8ecc86e037", - "reference": "55841909e2bcde01b5318c35f2b74f8ecc86e037", - "shasum": "" - }, - "require": { - "php": ">=5.3.0", - "psr/log": "~1.0" - }, - "provide": { - "psr/log-implementation": "1.0.0" - }, - "require-dev": { - "aws/aws-sdk-php": "^2.4.9", - "doctrine/couchdb": "~1.0@dev", - "graylog2/gelf-php": "~1.0", - "jakub-onderka/php-parallel-lint": "0.9", - "php-amqplib/php-amqplib": "~2.4", - "php-console/php-console": "^3.1.3", - "phpunit/phpunit": "~4.5", - "phpunit/phpunit-mock-objects": "2.3.0", - "ruflin/elastica": ">=0.90 <3.0", - "sentry/sentry": "^0.13", - "swiftmailer/swiftmailer": "~5.3" - }, - "suggest": { - "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", - "doctrine/couchdb": "Allow sending log messages to a CouchDB server", - "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", - "ext-mongo": "Allow sending log messages to a MongoDB server", - "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", - "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver", - "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", - "php-console/php-console": "Allow sending log messages to Google Chrome", - "rollbar/rollbar": "Allow sending log messages to Rollbar", - "ruflin/elastica": "Allow sending log messages to an Elastic Search server", - "sentry/sentry": "Allow sending log messages to a Sentry server" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Monolog\\": "src/Monolog" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - } - ], - "description": "Sends your logs to files, sockets, inboxes, databases and various web services", - "homepage": "http://github.com/Seldaek/monolog", - "keywords": [ - "log", - "logging", - "psr-3" - ], - "time": "2016-07-02 14:02:10" - }, - { - "name": "nikic/fast-route", - "version": "v1.0.1", - "source": { - "type": "git", - "url": "https://github.com/nikic/FastRoute.git", - "reference": "8ea928195fa9b907f0d6e48312d323c1a13cc2af" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/FastRoute/zipball/8ea928195fa9b907f0d6e48312d323c1a13cc2af", - "reference": "8ea928195fa9b907f0d6e48312d323c1a13cc2af", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "FastRoute\\": "src/" - }, - "files": [ - "src/functions.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov", - "email": "nikic@php.net" - } - ], - "description": "Fast request router for PHP", - "keywords": [ - "router", - "routing" - ], - "time": "2016-06-12 19:08:51" - }, - { - "name": "pimple/pimple", - "version": "v3.0.2", - "source": { - "type": "git", - "url": "https://github.com/silexphp/Pimple.git", - "reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/silexphp/Pimple/zipball/a30f7d6e57565a2e1a316e1baf2a483f788b258a", - "reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Pimple": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "Pimple, a simple Dependency Injection Container", - "homepage": "http://pimple.sensiolabs.org", - "keywords": [ - "container", - "dependency injection" - ], - "time": "2015-09-11 15:10:35" - }, - { - "name": "psr/http-message", - "version": "1.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", - "reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "time": "2015-05-04 20:22:00" - }, - { - "name": "psr/log", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", - "shasum": "" - }, - "type": "library", - "autoload": { - "psr-0": { - "Psr\\Log\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "time": "2012-12-21 11:40:51" - }, - { - "name": "slim/php-view", - "version": "2.1.0", - "source": { - "type": "git", - "url": "https://github.com/slimphp/PHP-View.git", - "reference": "8bae5b10d10c51596ef8d8113b3b63678718adcb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/slimphp/PHP-View/zipball/8bae5b10d10c51596ef8d8113b3b63678718adcb", - "reference": "8bae5b10d10c51596ef8d8113b3b63678718adcb", - "shasum": "" - }, - "require": { - "psr/http-message": "^1.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.0", - "slim/slim": "^3.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Slim\\Views\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Glenn Eggleton", - "email": "geggleto@gmail.com" - } - ], - "description": "Render PHP view scripts into a PSR-7 Response object.", - "keywords": [ - "framework", - "php", - "phtml", - "renderer", - "slim", - "template", - "view" - ], - "time": "2016-03-04 09:48:50" - }, - { - "name": "slim/slim", - "version": "3.4.2", - "source": { - "type": "git", - "url": "https://github.com/slimphp/Slim.git", - "reference": "a132385f736063d00632b52b3f8a389fe66fe4fa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/slimphp/Slim/zipball/a132385f736063d00632b52b3f8a389fe66fe4fa", - "reference": "a132385f736063d00632b52b3f8a389fe66fe4fa", - "shasum": "" - }, - "require": { - "container-interop/container-interop": "^1.1", - "nikic/fast-route": "^1.0", - "php": ">=5.5.0", - "pimple/pimple": "^3.0", - "psr/http-message": "^1.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0", - "squizlabs/php_codesniffer": "^2.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Slim\\": "Slim" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Rob Allen", - "email": "rob@akrabat.com", - "homepage": "http://akrabat.com" - }, - { - "name": "Josh Lockhart", - "email": "hello@joshlockhart.com", - "homepage": "https://joshlockhart.com" - }, - { - "name": "Gabriel Manricks", - "email": "gmanricks@me.com", - "homepage": "http://gabrielmanricks.com" - }, - { - "name": "Andrew Smith", - "email": "a.smith@silentworks.co.uk", - "homepage": "http://silentworks.co.uk" - } - ], - "description": "Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs", - "homepage": "http://slimframework.com", - "keywords": [ - "api", - "framework", - "micro", - "router" - ], - "time": "2016-05-25 11:23:38" - }, - { - "name": "slim/twig-view", - "version": "2.1.1", - "source": { - "type": "git", - "url": "https://github.com/slimphp/Twig-View.git", - "reference": "16fded26a44b8e8e0e041f1cff32afa21daeb284" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/slimphp/Twig-View/zipball/16fded26a44b8e8e0e041f1cff32afa21daeb284", - "reference": "16fded26a44b8e8e0e041f1cff32afa21daeb284", - "shasum": "" - }, - "require": { - "php": ">=5.5.0", - "psr/http-message": "^1.0", - "twig/twig": "^1.18" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Slim\\Views\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Josh Lockhart", - "email": "hello@joshlockhart.com", - "homepage": "http://joshlockhart.com" - } - ], - "description": "Slim Framework 3 view helper built on top of the Twig templating component", - "homepage": "http://slimframework.com", - "keywords": [ - "framework", - "slim", - "template", - "twig", - "view" - ], - "time": "2016-03-13 20:58:41" - }, - { - "name": "twig/twig", - "version": "v1.24.1", - "source": { - "type": "git", - "url": "https://github.com/twigphp/Twig.git", - "reference": "3566d311a92aae4deec6e48682dc5a4528c4a512" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/3566d311a92aae4deec6e48682dc5a4528c4a512", - "reference": "3566d311a92aae4deec6e48682dc5a4528c4a512", - "shasum": "" - }, - "require": { - "php": ">=5.2.7" - }, - "require-dev": { - "symfony/debug": "~2.7", - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.24-dev" - } - }, - "autoload": { - "psr-0": { - "Twig_": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "role": "Project Founder" - }, - { - "name": "Twig Team", - "homepage": "http://twig.sensiolabs.org/contributors", - "role": "Contributors" - } - ], - "description": "Twig, the flexible, fast, and secure template language for PHP", - "homepage": "http://twig.sensiolabs.org", - "keywords": [ - "templating" - ], - "time": "2016-05-30 09:11:59" - } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=5.5.0" - }, - "platform-dev": [] -} diff --git a/server/data/versions.json b/server/data/versions.json deleted file mode 100644 index 528adbef..00000000 --- a/server/data/versions.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "origin": { - "model": "SONOFF", - "min": "*", - "max": "0.9.2" - }, - "target": { - "version": "0.9.3", - "firmware": "/firmware/espurna-0.9.3.bin", - "spiffs": "/firmware/espurna-0.9.3-spiffs.bin" - } - } -] diff --git a/server/public/.htaccess b/server/public/.htaccess deleted file mode 100644 index c506092e..00000000 --- a/server/public/.htaccess +++ /dev/null @@ -1,10 +0,0 @@ -RewriteEngine On - -# Some hosts may require you to use the `RewriteBase` directive. -# If you need to use the `RewriteBase` directive, it should be the -# absolute physical path to the directory that contains this htaccess file. -# -# RewriteBase / - -RewriteCond %{REQUEST_FILENAME} !-f -RewriteRule ^ index.php [QSA,L] diff --git a/server/public/index.php b/server/public/index.php deleted file mode 100644 index 2784ee00..00000000 --- a/server/public/index.php +++ /dev/null @@ -1,30 +0,0 @@ -run(); diff --git a/server/src/dependencies.php b/server/src/dependencies.php deleted file mode 100644 index 2e7af52c..00000000 --- a/server/src/dependencies.php +++ /dev/null @@ -1,45 +0,0 @@ -getContainer(); - -// view renderer -// Register component on container -$container['view'] = function ($container) { - $settings = $container->get('settings')['renderer']; - $view = new \Slim\Views\Twig($settings['template_path'], [ - 'cache' => $settings['cache_path'] - ]); - $view->addExtension(new \Slim\Views\TwigExtension( - $container['router'], - $container['request']->getUri() - )); - - return $view; -}; - -// monolog -$container['devices'] = function ($container) { - - $settings = $container->get('settings')['devices']; - - $dateFormat = "[Y/m/d H:i:s]"; - $output = "%datetime% %message%\n"; - $formatter = new Monolog\Formatter\LineFormatter($output, $dateFormat); - $stream = new Monolog\Handler\StreamHandler($settings['path'], Monolog\Logger::INFO); - $stream->setFormatter($formatter); - - $logger = new Monolog\Logger($settings['name']); - $logger->pushHandler($stream); - - return $logger; - -}; - -// version database -$container['data'] = function($container) { - $settings = $container->get('settings')['database']; - $json_data = file_get_contents($settings['path']); - $data = json_decode($json_data, true); - return $data; -}; diff --git a/server/src/middleware.php b/server/src/middleware.php deleted file mode 100644 index f4fbcdd5..00000000 --- a/server/src/middleware.php +++ /dev/null @@ -1,10 +0,0 @@ -getContainer(); - -$settings = $container->get('settings'); - -$app->add(new RKA\Middleware\IpAddress( - $settings['rka']['check_proxy_headers'], - $settings['rka']['trusted_proxies'] -)); diff --git a/server/src/routes.php b/server/src/routes.php deleted file mode 100644 index 7ec55209..00000000 --- a/server/src/routes.php +++ /dev/null @@ -1,36 +0,0 @@ -get('/{model}/{current}', function($request, $response, $args) { - - $found = false; - $model = $request->getAttribute('model'); - $current = $request->getAttribute('current'); - - foreach ($this->get('data') as $version) { - - if (($model == $version['origin']['model']) - && (($version['origin']['min'] == '*' || version_compare($version['origin']['min'], $current, '<='))) - && (($version['origin']['max'] == '*' || version_compare($version['origin']['max'], $current, '>=')))) { - - $response->getBody()->write(stripslashes(json_encode($version['target']))); - $found = true; - break; - - } - }; - - if (!$found) { - $response->getBody()->write("{}"); - } - - $this->get('devices')->info( - "from:" - . $request->getAttribute('ip_address') - . " model:$model version:$current update:" - . ($found ? $version['target']['version'] : "none") - ); - - return $response; - -}); diff --git a/server/src/settings.php b/server/src/settings.php deleted file mode 100644 index 8e4e168d..00000000 --- a/server/src/settings.php +++ /dev/null @@ -1,27 +0,0 @@ - [ - - 'displayErrorDetails' => true, // set to false in production - 'addContentLengthHeader' => false, // Allow the web server to send the content-length header - - // RKA IP Address middleware - 'rka' => [ - 'check_proxy_headers' => false, - 'trusted_proxies' => [], - ], - - // Monolog settings - 'devices' => [ - 'name' => 'espurna-update-server-devices', - 'path' => __DIR__ . '/../logs/devices.log', - ], - - // Database - 'database' => [ - 'type' => 'json', - 'path' => __DIR__ . '/../data/versions.json', - ], - - ], -];