Added button handler
This commit is contained in:
parent
649b9e0729
commit
85cdbbf42d
|
@ -5,9 +5,15 @@
|
||||||
"includePath": [
|
"includePath": [
|
||||||
"${workspaceRoot}",
|
"${workspaceRoot}",
|
||||||
"${workspaceRoot}/src",
|
"${workspaceRoot}/src",
|
||||||
|
"${workspaceRoot}/build/gen",
|
||||||
"${workspaceRoot}/../modules/mongoose-os/fw/include",
|
"${workspaceRoot}/../modules/mongoose-os/fw/include",
|
||||||
"${workspaceRoot}/../modules/mongoose-os/common",
|
"${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": [],
|
"defines": [],
|
||||||
"intelliSenseMode": "clang-x64",
|
"intelliSenseMode": "clang-x64",
|
||||||
|
|
|
@ -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"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
18
README.md
18
README.md
|
@ -1,27 +1,29 @@
|
||||||
# SonOff module based on Mongoose-OS and using MQTT to integrate to some home automation
|
# SonOff module based on Mongoose-OS and using MQTT to integrate to some home automation
|
||||||
# Setup via Web and in AP-mode
|
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
- Do not configure WiFi - leave the module in AP (Access Point mode).
|
- Do not configure WiFi - leave the module in AP (Access Point mode).
|
||||||
- Mongoose OS starts a WiFi network called `SONOFF_XXXXXX` with password
|
- 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
|
- if STA is configured and gets access, the AP is disabled ~120 seconds after boot `Sonoff`. Switch your workstation to that WiFi network
|
||||||
`Sonoff`. Switch your workstation to that WiFi network
|
|
||||||
- Point your browser to http://192.168.4.1
|
## 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
|
- 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
|
- Integration into your home automation system based on MQTT, please configure
|
||||||
- MQTT host
|
- MQTT host with port
|
||||||
- MQTT port
|
- MQTT Client ID
|
||||||
|
- MQTT Password
|
||||||
- MQTT topic to send current switch status changes (published)
|
- MQTT topic to send current switch status changes (published)
|
||||||
- MQTT topic to subscribe to receive commands
|
- MQTT topic to subscribe to receive commands
|
||||||
|
|
||||||
![Screenshot](shot.png)
|
![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)
|
- 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:
|
- Switch to the Project page, find and import this app, build and flash it:
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="https://mongoose-os.com/images/app1.gif" width="75%">
|
<img src="https://mongoose-os.com/images/app1.gif" width="75%">
|
||||||
</p>
|
</p>
|
|
@ -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"
|
||||||
|
}
|
28
mos.yml
28
mos.yml
|
@ -14,15 +14,21 @@ arch: esp8266
|
||||||
filesystem:
|
filesystem:
|
||||||
- fs
|
- fs
|
||||||
|
|
||||||
|
sources:
|
||||||
|
- src
|
||||||
|
|
||||||
libs:
|
libs:
|
||||||
- origin: https://github.com/mongoose-os-libs/ca-bundle
|
- 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/http-server
|
||||||
- origin: https://github.com/mongoose-os-libs/ota-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/mqtt
|
||||||
- origin: https://github.com/mongoose-os-libs/rpc-service-config
|
- 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-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/rpc-mqtt
|
||||||
- origin: https://github.com/mongoose-os-libs/wifi
|
- origin: https://github.com/mongoose-os-libs/wifi
|
||||||
# - origin: https://github.com/mongoose-os-libs/mjs
|
# - origin: https://github.com/mongoose-os-libs/mjs
|
||||||
|
@ -34,21 +40,27 @@ cdefs:
|
||||||
MGOS_ENABLE_TUNNEL: 0
|
MGOS_ENABLE_TUNNEL: 0
|
||||||
|
|
||||||
config_schema:
|
config_schema:
|
||||||
- ["http.enable", true]
|
- ["debug.level", 3]
|
||||||
|
- ["device.id", "sonoff_??????"]
|
||||||
# - ["http.document_root", "/"]
|
# - ["http.document_root", "/"]
|
||||||
# - ["http.hidden_files", "s_*"]
|
# - ["http.hidden_files", "s_*"]
|
||||||
# - ["http.auth_file", "s_pass"]
|
# - ["http.auth_file", "s_pass"]
|
||||||
- ["wifi.ap.enable", true]
|
# - ["wifi.ap.enable", true]
|
||||||
- ["wifi.ap.ssid", "SONOFF_??????"]
|
# - ["wifi.ap.ssid", "SONOFF_??????"]
|
||||||
- ["wifi.ap.pass", "MySonoff"]
|
# - ["wifi.ap.pass", "MySonoff"]
|
||||||
# - ["wifi.sta.enable", false]
|
- ["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", "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.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"}]
|
- ["sonoff.command_sub_topic", "s", "sonoff/??????/command", {title: "Topic to subscribe to receive commands for this device"}]
|
||||||
|
|
||||||
build_vars:
|
build_vars:
|
||||||
# sonoff basic has 1MBytes flash only
|
# sonoff basic has 1MBytes flash only
|
||||||
FLASH_SIZE: 1048576
|
# FLASH_SIZE: 1048576
|
||||||
|
|
||||||
tags:
|
tags:
|
||||||
- c
|
- 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<callbacksRegistered; ++i) {
|
||||||
|
if (callbacks[i].numberPressed == buttonPressCounter) {
|
||||||
|
LOG(LL_DEBUG, ("Calling button press callback for %d presses, index %d", buttonPressCounter, i));
|
||||||
|
callbacks[i].callback(buttonPressCounter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void buttonHandler(int pin, void *arg) {
|
||||||
|
(void) pin;
|
||||||
|
(void) arg;
|
||||||
|
// button release event occured
|
||||||
|
if (mgos_uptime() - lastButtonPressTime < MAX_TIME_BETWEEN_MULTIPLE_BUTTON_PRESS_EVENTS) {
|
||||||
|
++buttonPressCounter;
|
||||||
|
} else {
|
||||||
|
buttonPressCounter = 0;
|
||||||
|
}
|
||||||
|
lastButtonPressTime = mgos_uptime();
|
||||||
|
// at this point we do not know if more press events will come that we need to count, therefore we wait before we act
|
||||||
|
if (multiPressTimerId != 0) mgos_clear_timer(multiPressTimerId);
|
||||||
|
multiPressTimerId = mgos_set_timer(MAX_TIME_BETWEEN_MULTIPLE_BUTTON_PRESS_EVENTS + 1, 0, multiPressButtonHandler, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_button_handler() {
|
||||||
|
mgos_gpio_set_button_handler(ON_BOARD_BUTTON_PIN, MGOS_GPIO_PULL_UP, MGOS_GPIO_INT_EDGE_POS, 50, buttonHandler, NULL);
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef buttonHandler_h_included
|
||||||
|
#define buttonHandler_h_included
|
||||||
|
|
||||||
|
typedef void (*button_press_callback)(int numberPressed);
|
||||||
|
|
||||||
|
extern void init_button_handler();
|
||||||
|
extern void add_button_press_callback(int numberPressed, button_press_callback cb);
|
||||||
|
|
||||||
|
#endif
|
|
@ -15,17 +15,15 @@
|
||||||
|
|
||||||
static int ON_BOARD_LED = 13; /* sonoff basic LED pin */
|
static int ON_BOARD_LED = 13; /* sonoff basic LED pin */
|
||||||
|
|
||||||
static LEDStatus currentStatus = LED_OFF;
|
static enum LEDStatus currentStatus = LED_OFF;
|
||||||
static int numTicksLedHasThisState = 0;
|
static int numTicksLedHasThisState = 0;
|
||||||
|
|
||||||
void set_led_status(LEDStatus newStatus) {
|
void set_led_status(enum LEDStatus newStatus) {
|
||||||
numTicksLedHasThisState = 0;
|
numTicksLedHasThisState = 0;
|
||||||
currentStatus = newStatus;
|
currentStatus = newStatus;
|
||||||
LOG(LL_DEBUG, ("set_led_status to %d", newStatus));
|
LOG(LL_INFO, ("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) {
|
static void blink_on_board_led_cb(void *arg) {
|
||||||
switch (currentStatus) {
|
switch (currentStatus) {
|
||||||
case LED_OFF:
|
case LED_OFF:
|
||||||
|
@ -35,7 +33,7 @@ static void blink_on_board_led_cb(void *arg) {
|
||||||
mgos_gpio_write(ON_BOARD_LED, 0); // on
|
mgos_gpio_write(ON_BOARD_LED, 0); // on
|
||||||
break;
|
break;
|
||||||
case LED_BLINK_SLOW:
|
case LED_BLINK_SLOW:
|
||||||
++numTicksLedHasThisState = 0;
|
++numTicksLedHasThisState;
|
||||||
if (numTicksLedHasThisState >= 4) {
|
if (numTicksLedHasThisState >= 4) {
|
||||||
numTicksLedHasThisState = 0;
|
numTicksLedHasThisState = 0;
|
||||||
mgos_gpio_toggle(ON_BOARD_LED);
|
mgos_gpio_toggle(ON_BOARD_LED);
|
||||||
|
@ -55,5 +53,5 @@ static void blink_on_board_led_cb(void *arg) {
|
||||||
void init_led_handler() {
|
void init_led_handler() {
|
||||||
mgos_gpio_set_mode(ON_BOARD_LED, MGOS_GPIO_MODE_OUTPUT);
|
mgos_gpio_set_mode(ON_BOARD_LED, MGOS_GPIO_MODE_OUTPUT);
|
||||||
mgos_set_timer(250, MGOS_TIMER_REPEAT, blink_on_board_led_cb, NULL);
|
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"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ enum LEDStatus {
|
||||||
LED_BLINK_FAST = 3 // on 2x / second (250ms on, 250ms off)
|
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();
|
extern void init_led_handler();
|
||||||
|
|
||||||
#endif
|
#endif
|
31
src/main.c
31
src/main.c
|
@ -1,19 +1,19 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "common/platform.h"
|
#include "mgos.h"
|
||||||
#include "common/cs_file.h"
|
|
||||||
#include "mgos_app.h"
|
#include "mgos_app.h"
|
||||||
#include "mgos_gpio.h"
|
#include "mgos_gpio.h"
|
||||||
#include "mgos_sys_config.h"
|
#include "mgos_sys_config.h"
|
||||||
#include "mgos_timers.h"
|
#include "mgos_timers.h"
|
||||||
#include "mgos_hal.h"
|
|
||||||
#include "mgos_dlsym.h"
|
|
||||||
#include "mgos_mqtt.h"
|
#include "mgos_mqtt.h"
|
||||||
#include "mjs.h"
|
#include "common/platform.h"
|
||||||
|
#include "common/cs_file.h"
|
||||||
|
|
||||||
|
#include "buttonHandler.h"
|
||||||
#include "ledHandler.h"
|
#include "ledHandler.h"
|
||||||
|
|
||||||
|
#define RELAY_PIN 12
|
||||||
|
|
||||||
bool mqtt_conn_flag = false;
|
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) {
|
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;
|
struct mg_mqtt_message *msg = (struct mg_mqtt_message *) p;
|
||||||
if (ev == MG_EV_MQTT_CONNACK) {
|
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;
|
mqtt_conn_flag = true;
|
||||||
//if (get_cfg()->mqtt.pub == NULL) {
|
//if (get_cfg()->mqtt.pub == NULL) {
|
||||||
//LOG(LL_ERROR, ("Run 'mos config-set mqtt.pub=... '"));
|
//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;
|
(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) {
|
enum mgos_app_init_result mgos_app_init(void) {
|
||||||
init_led_handler();
|
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);
|
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;
|
return MGOS_APP_INIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue