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;
+}