diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 4ecb703..e9bfc3f 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -5,9 +5,15 @@ "includePath": [ "${workspaceRoot}", "${workspaceRoot}/src", + "${workspaceRoot}/build/gen", "${workspaceRoot}/../modules/mongoose-os/fw/include", "${workspaceRoot}/../modules/mongoose-os/common", - "${workspaceRoot}/../modules/mjs" + "${workspaceRoot}/../modules/mongoose-os/src", + "${workspaceRoot}/../modules/mjs", + "${workspaceRoot}/../modules/libs/http-server/include", + "${workspaceRoot}/../modules/libs/http-i2c/include", + "${workspaceRoot}/../modules/libs/mqtt/include", + "${workspaceRoot}/../modules/libs/cron/include" ], "defines": [], "intelliSenseMode": "clang-x64", diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..9ffe609 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,13 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "type": "mos", + "problemMatcher": [ + "$mosBuildMatcher" + ] + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md index 13cfeb2..ae5bf7f 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,29 @@ # 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 `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 +- if STA is configured and gets access, the AP is disabled ~120 seconds after boot `Sonoff`. Switch your workstation to that WiFi network + +## Setup via Web and in AP-mode + +- Point your browser to [http://192.168.4.1]http://192.168.4.1 - 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 host with port + - MQTT Client ID + - MQTT Password - MQTT topic to send current switch status changes (published) - MQTT topic to subscribe to receive commands ![Screenshot](shot.png) -## How to install this app +## How to build and install this app - Install and start [mos tool](https://mongoose-os.com/software.html) - Switch to the Project page, find and import this app, build and flash it:
-
+ \ No newline at end of file diff --git a/fs/mqtt.json b/fs/mqtt.json new file mode 100644 index 0000000..ca78109 --- /dev/null +++ b/fs/mqtt.json @@ -0,0 +1,30 @@ +{ + "comment": "From QIoT MQTT Server", + "username": "758cb1b5-d631-4cee-9b20-9e8d5029606d", + "myqnapcloudHost": "Not Available", + "clientId": "SONOFFSwitch_1516965632", + "host": [ + "192.168.89.12" + ], + "password": "r:fa6d6a2834aaabaa88529444c9564ffd", + "port": 21883, + "resources": [ + { + "description": "Power on/off switch", + "datatype": "Boolean", + "resourceid": "switch", + "topic": "qiot/things/admin/SONOFFSwitch/switch", + "resourcename": "switch", + "resourcetypename": "Button", + "unit": "" + } + ], + "example-payload": { + "deviceId": "dsjhjshsdjkjsdkdsjsdjdsksdjd", + "sensorId": "QIoTDevice", + "value": 18, + "metadata": {"unit": "C", "datatype": "Float"} + }, + "pub-topic": "sonoff/sonoff_D927D7/switch", + "sub-topic": "sonoff/sonoff_D927D7/command" +} \ No newline at end of file diff --git a/mos.yml b/mos.yml index dc0e1b1..cc2ee86 100644 --- a/mos.yml +++ b/mos.yml @@ -14,15 +14,21 @@ arch: esp8266 filesystem: - fs +sources: + - src + 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/cron + - origin: https://github.com/mongoose-os-libs/crontab + # - 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-service-cron + - 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 @@ -34,21 +40,27 @@ cdefs: MGOS_ENABLE_TUNNEL: 0 config_schema: - - ["http.enable", true] + - ["debug.level", 3] + - ["device.id", "sonoff_??????"] # - ["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] + # - ["wifi.ap.enable", true] + # - ["wifi.ap.ssid", "SONOFF_??????"] + # - ["wifi.ap.pass", "MySonoff"] + - ["wifi.sta.enable", true] + - ["wifi.sta.ssid", "Pinguin"] + - ["wifi.sta.pass", "PaulchenAufmKlo34"] + - ["mqtt.server", "192.168.89.12:21883"] + - ["mqtt.client_id", "SONOFFSwitch_1516965632"] + - ["mqtt.pass", "r:fa6d6a2834aaabaa88529444c9564ffd"] - ["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 + # FLASH_SIZE: 1048576 tags: - c diff --git a/src/buttonHandler.c b/src/buttonHandler.c new file mode 100644 index 0000000..4d18032 --- /dev/null +++ b/src/buttonHandler.c @@ -0,0 +1,61 @@ +#include "mgos.h" +#include "mgos_gpio.h" +#include "mgos_timers.h" +#include "buttonHandler.h" + +#define ON_BOARD_BUTTON_PIN 5 +#define MAX_TIME_BETWEEN_MULTIPLE_BUTTON_PRESS_EVENTS 200 + +static double lastButtonPressTime = 0; +static uint8_t buttonPressCounter = 0; +static mgos_timer_id multiPressTimerId = 0; +static uint8_t callbacksRegistered = 0; +#define MAX_CALLBACKS 10 + +struct callbackReg_s { + int numberPressed; + button_press_callback callback; +}; + +static struct callbackReg_s callbacks[MAX_CALLBACKS]; + +void add_button_press_callback(int numberPressed, button_press_callback cb) { + if (callbacksRegistered < MAX_CALLBACKS) { + callbacks[callbacksRegistered].callback = cb; + callbacks[callbacksRegistered].numberPressed = numberPressed; + ++callbacksRegistered; + } else { + LOG(LL_ERROR, ("ERROR: Too many callbacks for button press! -- ignored this on for %d presses", numberPressed)); + } +} + +static void multiPressButtonHandler(void *arg) { + (void) arg; + LOG(LL_DEBUG, ("multiPressButtonHandler called after %d presses", buttonPressCounter)); + multiPressTimerId = 0; // timer used only once, thus we clear it + for (int i=0; i