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= 4) { numTicksLedHasThisState = 0; mgos_gpio_toggle(ON_BOARD_LED); @@ -55,5 +53,5 @@ static void blink_on_board_led_cb(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")); + LOG(LL_INFO, ("LED handler initialized")); } diff --git a/src/ledHandler.h b/src/ledHandler.h index 969f338..e9bdcd0 100644 --- a/src/ledHandler.h +++ b/src/ledHandler.h @@ -13,7 +13,7 @@ enum LEDStatus { LED_BLINK_FAST = 3 // on 2x / second (250ms on, 250ms off) }; -extern void set_led_status(LEDStatus newStatus); +extern void set_led_status(enum LEDStatus newStatus); extern void init_led_handler(); #endif \ No newline at end of file diff --git a/src/main.c b/src/main.c index 032db67..d0fab74 100644 --- a/src/main.c +++ b/src/main.c @@ -1,19 +1,19 @@ #include #include -#include "common/platform.h" -#include "common/cs_file.h" +#include "mgos.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 "common/platform.h" +#include "common/cs_file.h" +#include "buttonHandler.h" #include "ledHandler.h" +#define RELAY_PIN 12 bool mqtt_conn_flag = false; @@ -36,7 +36,7 @@ int mqtt_connected(void) { 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)); + LOG(LL_INFO, ("SonoffApp: 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=... '")); @@ -50,9 +50,26 @@ static void mqtt_ev_handler(struct mg_connection *c, int ev, void *p, void *user (void) c; } +static void buttonPressOne(int pressCount) { + LOG(LL_DEBUG, ("buttonPressOne called with pressCount=%d", pressCount)); +} + +static void buttonPressTwo(int pressCount) { + LOG(LL_DEBUG, ("buttonPressTwo called with pressCount=%d", pressCount)); +} + +static void buttonPressThree(int pressCount) { + LOG(LL_DEBUG, ("buttonPressThree called with pressCount=%d", pressCount)); +} + enum mgos_app_init_result mgos_app_init(void) { init_led_handler(); + set_led_status(LED_BLINK_FAST); + init_button_handler(); + add_button_press_callback(1, buttonPressOne); + add_button_press_callback(2, buttonPressTwo); + add_button_press_callback(3, buttonPressThree); mgos_mqtt_add_global_handler(mqtt_ev_handler, NULL); - LOG(LL_DEBUG, ("SONOFF app initialized")); + LOG(LL_INFO, ("SONOFF app initialized")); return MGOS_APP_INIT_SUCCESS; }