From 649b9e0729088f793726fc4eea2c25055cb5eb0c Mon Sep 17 00:00:00 2001 From: Dirk Jahnke Date: Fri, 26 Jan 2018 11:22:47 +0100 Subject: [PATCH] Initial commit --- .gitignore | 5 ++ .vscode/c_cpp_properties.json | 64 +++++++++++++++++ README.md | 15 ++-- fs/index.html | 106 +++++++++++++++++++--------- fs/{zepto.min.js => s_zepto.min.js} | 0 mos.yml | 39 +++++++++- src/ledHandler.c | 59 ++++++++++++++++ src/ledHandler.h | 19 +++++ src/main.c | 58 +++++++++++++++ 9 files changed, 324 insertions(+), 41 deletions(-) create mode 100644 .gitignore create mode 100644 .vscode/c_cpp_properties.json rename fs/{zepto.min.js => s_zepto.min.js} (100%) create mode 100644 src/ledHandler.c create mode 100644 src/ledHandler.h create mode 100644 src/main.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a41eb9c --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +build +deps +*.tmp +*.bak + diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..4ecb703 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,64 @@ +{ + "configurations": [ + { + "name": "Mac", + "includePath": [ + "${workspaceRoot}", + "${workspaceRoot}/src", + "${workspaceRoot}/../modules/mongoose-os/fw/include", + "${workspaceRoot}/../modules/mongoose-os/common", + "${workspaceRoot}/../modules/mjs" + ], + "defines": [], + "intelliSenseMode": "clang-x64", + "browse": { + "path": [ + "${workspaceRoot}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + }, + "macFrameworkPath": [] + }, + { + "name": "Linux", + "includePath": [ + "/usr/include", + "/usr/local/include", + "${workspaceRoot}" + ], + "defines": [], + "intelliSenseMode": "clang-x64", + "browse": { + "path": [ + "/usr/include", + "/usr/local/include", + "${workspaceRoot}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + } + }, + { + "name": "Win32", + "includePath": [ + "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include", + "${workspaceRoot}" + ], + "defines": [ + "_DEBUG", + "UNICODE" + ], + "intelliSenseMode": "msvc-x64", + "browse": { + "path": [ + "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include/*", + "${workspaceRoot}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + } + } + ], + "version": 3 +} \ No newline at end of file diff --git a/README.md b/README.md index c7d5e03..13cfeb2 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,19 @@ -# Setup WiFi via Web UI +# SonOff module based on Mongoose-OS and using MQTT to integrate to some home automation +# Setup via Web and in AP-mode ## Overview - Do not configure WiFi - leave the module in AP (Access Point mode). -- Mongoose OS starts a WiFi network called `Mongoose_XXXXXX` with password -`Mongoose`. Switch your workstation to that WiFi network +- Mongoose OS starts a WiFi network called `SONOFF_XXXXXX` with password +- if STA is configured and gets access, the AP is disabled ~120 seconds after boot +`Sonoff`. Switch your workstation to that WiFi network - Point your browser to http://192.168.4.1 -- You'll see a simple form to configure WiFi network & password +- You'll see a simple form to configure WiFi network & password and some sonoff parameters +- Integration into your home automation system based on MQTT, please configure + - MQTT host + - MQTT port + - MQTT topic to send current switch status changes (published) + - MQTT topic to subscribe to receive commands ![Screenshot](shot.png) diff --git a/fs/index.html b/fs/index.html index 4ed5e9d..2ac084c 100644 --- a/fs/index.html +++ b/fs/index.html @@ -15,51 +15,32 @@ min-height: 7em; white-space: pre; padding: 0.5em; overflow: auto; } - +
-

WiFi setup via Web UI

-

This Mongoose OS app shows - how to start a device in Access Point mode (AP) and configure Station mode - via simple Web UI.

-

This page communicates with the device via - Mongoose OS RPC mechanism - using HTTP/RESTful as a transport protocol. A small JavaScript library, +

WiFi setup

+

Configure your SONOFF device to communicate with your home automation without having this device + connect to some unknown servers on the internet. We want you to keep you under control of your + home! +

+

This product is based on the Sonoff devices sold by iTead. + The firmware has been replaced by a software based on Mongoose OS. + This setup is developed by Dirk Jahnke and can be found + in a private gitea repository at https://gitea.pmpark.de/dirk/mg_sonoff.git. + A small JavaScript library, zepto, is used as a drop-in replacement for jQuery, for making AJAX calls to the device.

- -

Open fs/index.html, or right-click on this page and - choose "view source".

- -

- First, this web page makes a call to the - http://DEVICE_IP/rpc/Config.Get RESTful endpoint, which - triggers Config.Get RPC service and returns a large JSON - object (click here to see) with full device configuration. From that object, we take - WiFi SSID and password, and stick them into the text inputs. -

- -

Second, we install a button click handler, which grabs values from the - text inputs, creates a JSON string with the device configuration subtree - that Config.Set RPC call expects, - and calls a /rpc/Config.Set endpoint. -

- -

Similarly, you can call any other RPC service that device has. Call - RPC.List to get a list of all RPC services available. -

-
@@ -69,15 +50,53 @@
-
+
-
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ +
+
+
+ +
+

Device Info

+
+ + +
+
+
+
diff --git a/fs/zepto.min.js b/fs/s_zepto.min.js similarity index 100% rename from fs/zepto.min.js rename to fs/s_zepto.min.js diff --git a/mos.yml b/mos.yml index d154755..dc0e1b1 100644 --- a/mos.yml +++ b/mos.yml @@ -1,21 +1,54 @@ -author: mongoose-os -description: Setup WiFi via Web UI +name: mg_sonoff +author: Dirk Jahnke +description: Control sonoff devices without having them communicate to their internet servers. Instead integrate them into you own home automation based on MQTT or RPC. version: 1.0 libs_version: ${mos.version} modules_version: ${mos.version} mongoose_os_version: ${mos.version} +platforms: [esp8266] + +arch: esp8266 + filesystem: - fs libs: - origin: https://github.com/mongoose-os-libs/ca-bundle + - origin: https://github.com/mongoose-os-libs/i2c - origin: https://github.com/mongoose-os-libs/http-server + - origin: https://github.com/mongoose-os-libs/ota-http-server + - origin: https://github.com/mongoose-os-libs/mqtt - origin: https://github.com/mongoose-os-libs/rpc-service-config - origin: https://github.com/mongoose-os-libs/rpc-service-fs - - origin: https://github.com/mongoose-os-libs/rpc-uart + # - origin: https://github.com/mongoose-os-libs/rpc-uart + - origin: https://github.com/mongoose-os-libs/rpc-mqtt - origin: https://github.com/mongoose-os-libs/wifi + # - origin: https://github.com/mongoose-os-libs/mjs + + +cdefs: + MGOS_ENABLE_WEB_CONFIG: 1 + MGOS_ENABLE_FILE_UPLOAD: 1 + MGOS_ENABLE_TUNNEL: 0 + +config_schema: + - ["http.enable", true] + # - ["http.document_root", "/"] + # - ["http.hidden_files", "s_*"] + # - ["http.auth_file", "s_pass"] + - ["wifi.ap.enable", true] + - ["wifi.ap.ssid", "SONOFF_??????"] + - ["wifi.ap.pass", "MySonoff"] + # - ["wifi.sta.enable", false] + - ["sonoff", "o", {title: "Sonoff specific parameters"}] + - ["sonoff.switch_status_pub_topic", "s", "sonoff/??????/switch", {title: "Topic to publish switch status, ?????? is the device ID of this device"}] + - ["sonoff.command_sub_topic", "s", "sonoff/??????/command", {title: "Topic to subscribe to receive commands for this device"}] + +build_vars: + # sonoff basic has 1MBytes flash only + FLASH_SIZE: 1048576 tags: - c diff --git a/src/ledHandler.c b/src/ledHandler.c new file mode 100644 index 0000000..37c4349 --- /dev/null +++ b/src/ledHandler.c @@ -0,0 +1,59 @@ +// Author: Dirk Jahnke +// January 24, 2018 +// +// Manage on board LED of SONOFF device +// +#include +#include + +#include "mgos.h" +#include "mgos_gpio.h" +#include "mgos_sys_config.h" +#include "mgos_timers.h" + +#include "ledHandler.h" + +static int ON_BOARD_LED = 13; /* sonoff basic LED pin */ + +static LEDStatus currentStatus = LED_OFF; +static int numTicksLedHasThisState = 0; + +void set_led_status(LEDStatus newStatus) { + numTicksLedHasThisState = 0; + currentStatus = newStatus; + LOG(LL_DEBUG, ("set_led_status to %d", newStatus)); +} + +static uint8_t led_timer_ticks = 0; /* for led blinker use */ + +static void blink_on_board_led_cb(void *arg) { + switch (currentStatus) { + case LED_OFF: + mgos_gpio_write(ON_BOARD_LED, 1); // off + break; + case LED_ON: + mgos_gpio_write(ON_BOARD_LED, 0); // on + break; + case LED_BLINK_SLOW: + ++numTicksLedHasThisState = 0; + if (numTicksLedHasThisState >= 4) { + numTicksLedHasThisState = 0; + mgos_gpio_toggle(ON_BOARD_LED); + } + break; + case LED_BLINK_FAST: + // toggle LED each tick + mgos_gpio_toggle(ON_BOARD_LED); + break; + default: + LOG(LL_ERROR, ("Invalid current LED status: %d -- ignored", currentStatus)); + break; + } + (void) arg; +} + +void init_led_handler() { + mgos_gpio_set_mode(ON_BOARD_LED, MGOS_GPIO_MODE_OUTPUT); + mgos_set_timer(250, MGOS_TIMER_REPEAT, blink_on_board_led_cb, NULL); + LOG(LL_DEBUG, ("LED handler initialized")); +} diff --git a/src/ledHandler.h b/src/ledHandler.h new file mode 100644 index 0000000..969f338 --- /dev/null +++ b/src/ledHandler.h @@ -0,0 +1,19 @@ +// Author: Dirk Jahnke +// January 24, 2018 +// +// Manage on board LED of SONOFF device +// +#ifndef ledHandler_h_included +#define ledHandler_h_included + +enum LEDStatus { + LED_OFF = 0, // permanently off + LED_ON = 1, // permanently on + LED_BLINK_SLOW = 2, // on 0,5x / second (1s on, 1s off) + LED_BLINK_FAST = 3 // on 2x / second (250ms on, 250ms off) +}; + +extern void set_led_status(LEDStatus newStatus); +extern void init_led_handler(); + +#endif \ No newline at end of file diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..032db67 --- /dev/null +++ b/src/main.c @@ -0,0 +1,58 @@ +#include +#include + +#include "common/platform.h" +#include "common/cs_file.h" +#include "mgos_app.h" +#include "mgos_gpio.h" +#include "mgos_sys_config.h" +#include "mgos_timers.h" +#include "mgos_hal.h" +#include "mgos_dlsym.h" +#include "mgos_mqtt.h" +#include "mjs.h" + +#include "ledHandler.h" + + +bool mqtt_conn_flag = false; + +int mqtt_connected(void) { + return (int) mqtt_conn_flag; +} + +//static void pub(struct mg_connection *c, const char *fmt, ...) { + //char msg[200]; + //struct json_out jmo = JSON_OUT_BUF(msg, sizeof(msg)); + //va_list ap; + //int n; + //va_start(ap, fmt); + //n = json_vprintf(&jmo, fmt, ap); + //va_end(ap); + //mg_mqtt_publish(c, get_cfg()->mqtt.pub, 0, MG_MQTT_QOS(0), msg, n); + //LOG(LL_INFO, ("%s -> %s", get_cfg()->mqtt.pub, msg)); +//} + +static void mqtt_ev_handler(struct mg_connection *c, int ev, void *p, void *user_data) { + struct mg_mqtt_message *msg = (struct mg_mqtt_message *) p; + if (ev == MG_EV_MQTT_CONNACK) { + LOG(LL_INFO, ("MQTT connected: %d", msg->connack_ret_code)); + mqtt_conn_flag = true; + //if (get_cfg()->mqtt.pub == NULL) { + //LOG(LL_ERROR, ("Run 'mos config-set mqtt.pub=... '")); + //} else { + //pub(c, "{timestamp:%.3lf, mem_free:%d}", mg_time(), mgos_get_free_heap_size() ); /* post uptime */ + //} + } else if (ev == MG_EV_CLOSE) { + mqtt_conn_flag = false; + } + (void) user_data; + (void) c; +} + +enum mgos_app_init_result mgos_app_init(void) { + init_led_handler(); + mgos_mqtt_add_global_handler(mqtt_ev_handler, NULL); + LOG(LL_DEBUG, ("SONOFF app initialized")); + return MGOS_APP_INIT_SUCCESS; +}