Rewrite statusled implementation.
- Read it now from app.config JSON file. - Allow for inverted status leds (Sonoff et al) - Clean up unit tests.
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "Sonoff 4CH v1.1",
|
||||
"status_led": 13,
|
||||
"statusled": 13,
|
||||
"statusled_invert": true,
|
||||
"channels": [
|
||||
{ "led": -1, "relay": 15, "button": 14 },
|
||||
{ "led": -1, "relay": 4, "button": 10 },
|
||||
|
@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "Sonoff Basic, S20, SV, RF, TH, Touch",
|
||||
"status_led": 13,
|
||||
"statusled": 13,
|
||||
"statusled_invert": true,
|
||||
"channels": [
|
||||
{ "led": -1, "relay": 12, "button": 0 }
|
||||
]
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
#define CHANNEL_CHANGE_COOLDOWN_SECONDS 0.250
|
||||
#define CHANNEL_MAX 16
|
||||
#define GREEN_LED_GPIO 0
|
||||
#define GPIO_INVALID 255
|
||||
#define GPIO_MIN 0
|
||||
#define GPIO_MAX 16
|
||||
@ -19,7 +18,8 @@ struct channel_t {
|
||||
double button_last_change;
|
||||
};
|
||||
|
||||
void led_status_blink();
|
||||
void statusled_blink();
|
||||
void statusled_init(uint8_t gpio, bool state_off);
|
||||
|
||||
bool channel_init(const char *fn);
|
||||
uint8_t channel_gpio_by_idx(int idx);
|
||||
|
@ -24,7 +24,8 @@ bool channel_init(const char *fn) {
|
||||
bool ret = false;
|
||||
|
||||
char *name = NULL;
|
||||
int status_led = -1;
|
||||
int statusled = -1;
|
||||
bool statusled_invert = false;
|
||||
|
||||
int idx;
|
||||
|
||||
@ -37,15 +38,19 @@ bool channel_init(const char *fn) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (json_scanf(json, strlen(json), "{name:%Q, status_led:%d}", &name, &status_led) != 2) {
|
||||
LOG(LL_ERROR, ("Incomplete JSON: require 'name' and 'status_led' fields"));
|
||||
if (json_scanf(json, strlen(json), "{name:%Q, statusled:%d}", &name, &statusled) != 2) {
|
||||
LOG(LL_ERROR, ("Incomplete JSON: require 'name' and 'statusled' fields"));
|
||||
goto exit;
|
||||
}
|
||||
LOG(LL_INFO, ("Configuration: name='%s', status_led=%d", name, status_led));
|
||||
if (!valid_gpio(status_led)) {
|
||||
LOG(LL_ERROR, ("Status LED GPIO (%d) out of bounds [%d,%d]", status_led, GPIO_MIN, GPIO_MAX));
|
||||
LOG(LL_INFO, ("Configuration: name='%s', statusled=%d", name, statusled));
|
||||
if (!valid_gpio(statusled)) {
|
||||
LOG(LL_ERROR, ("Status LED GPIO (%d) out of bounds [%d,%d]", statusled, GPIO_MIN, GPIO_MAX));
|
||||
goto exit;
|
||||
}
|
||||
json_scanf(json, strlen(json), "{statusled_invert:%B}", &statusled_invert);
|
||||
if (statusled_invert) {
|
||||
LOG(LL_INFO, ("Inverting statusled GPIO (%d)", statusled));
|
||||
}
|
||||
|
||||
// Traverse Array
|
||||
while ((h = json_next_elem(json, strlen(json), h, ".channels", &idx, &val)) != NULL) {
|
||||
@ -83,10 +88,8 @@ bool channel_init(const char *fn) {
|
||||
ret=true;
|
||||
exit:
|
||||
if (ret) {
|
||||
if (status_led!=-1) {
|
||||
mgos_gpio_set_mode(status_led, MGOS_GPIO_MODE_OUTPUT);
|
||||
mgos_gpio_write(status_led, 0);
|
||||
}
|
||||
if (statusled!=-1)
|
||||
statusled_init(statusled,statusled_invert);
|
||||
|
||||
s_num_channels=idx+1;
|
||||
LOG(LL_INFO, ("Configuring %d channels", s_num_channels));
|
||||
|
20
src/led.c
20
src/led.c
@ -1,20 +0,0 @@
|
||||
#include "main.h"
|
||||
|
||||
static mgos_timer_id led_status_timer_id = 0;
|
||||
|
||||
static void led_status_off_cb(void *arg) {
|
||||
mgos_gpio_write(GREEN_LED_GPIO, 0);
|
||||
led_status_timer_id=0;
|
||||
(void) arg;
|
||||
}
|
||||
|
||||
void led_status_blink() {
|
||||
mgos_gpio_write(GREEN_LED_GPIO, 1);
|
||||
if (led_status_timer_id) {
|
||||
mgos_clear_timer(led_status_timer_id);
|
||||
led_status_timer_id=0;
|
||||
}
|
||||
led_status_timer_id = mgos_set_timer(100, false, led_status_off_cb, NULL);
|
||||
}
|
||||
|
||||
|
@ -4,9 +4,6 @@
|
||||
#include "rpc.h"
|
||||
|
||||
enum mgos_app_init_result mgos_app_init(void) {
|
||||
mgos_gpio_set_mode(GREEN_LED_GPIO, MGOS_GPIO_MODE_OUTPUT);
|
||||
mgos_gpio_write(GREEN_LED_GPIO, 0);
|
||||
|
||||
channel_init(mgos_sys_config_get_app_config());
|
||||
mqtt_init();
|
||||
rpc_init();
|
||||
|
@ -7,7 +7,7 @@
|
||||
static void mqtt_publish_broadcast_stat(const char *stat, const char *msg) {
|
||||
char topic[80];
|
||||
|
||||
led_status_blink();
|
||||
statusled_blink();
|
||||
|
||||
snprintf(topic, sizeof(topic)-1, "%s/%s", MQTT_TOPIC_BROADCAST_STAT, stat);
|
||||
mgos_mqtt_pub((char*)topic, (char*)msg, strlen(msg), 0, false);
|
||||
@ -62,7 +62,7 @@ static void mqtt_ev(struct mg_connection *nc, int ev, void *ev_data, void *user_
|
||||
void mqtt_publish_stat(const char *stat, const char *msg) {
|
||||
char topic[80];
|
||||
|
||||
led_status_blink();
|
||||
statusled_blink();
|
||||
|
||||
snprintf(topic, sizeof(topic)-1, "%s%s/stat/%s", MQTT_TOPIC_PREFIX, mgos_sys_config_get_device_id(), stat);
|
||||
mgos_mqtt_pub((char*)topic, (char*)msg, strlen(msg), 0, false);
|
||||
|
30
src/statusled.c
Normal file
30
src/statusled.c
Normal file
@ -0,0 +1,30 @@
|
||||
#include "main.h"
|
||||
|
||||
static mgos_timer_id statusled_timer_id = 0;
|
||||
static uint8_t statusled_gpio = 0;
|
||||
static bool statusled_off_state = 0;
|
||||
|
||||
static void statusled_off_cb(void *arg) {
|
||||
mgos_gpio_write(statusled_gpio, statusled_off_state);
|
||||
statusled_timer_id=0;
|
||||
(void) arg;
|
||||
}
|
||||
|
||||
void statusled_blink() {
|
||||
if (statusled_gpio == GPIO_INVALID)
|
||||
return;
|
||||
|
||||
mgos_gpio_write(statusled_gpio, !statusled_off_state);
|
||||
if (statusled_timer_id) {
|
||||
mgos_clear_timer(statusled_timer_id);
|
||||
statusled_timer_id=0;
|
||||
}
|
||||
statusled_timer_id = mgos_set_timer(100, false, statusled_off_cb, NULL);
|
||||
}
|
||||
|
||||
void statusled_init(uint8_t gpio, bool off_state) {
|
||||
statusled_gpio = gpio;
|
||||
statusled_off_state = off_state;
|
||||
mgos_gpio_set_mode(statusled_gpio, MGOS_GPIO_MODE_OUTPUT);
|
||||
mgos_gpio_write(statusled_gpio, statusled_off_state);
|
||||
}
|
@ -9,7 +9,7 @@ default: $(TARGET)
|
||||
all: default
|
||||
|
||||
OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
|
||||
SRCS = frozen/frozen.c ../src/channel.c ../src/mqtt.c ../src/led.c
|
||||
SRCS = frozen/frozen.c ../src/channel.c ../src/mqtt.c ../src/statusled.c
|
||||
HEADERS = $(wildcard *.h)
|
||||
|
||||
%.o: %.c $(HEADERS)
|
||||
|
5
unittest/testdata/testconfig0.json
vendored
5
unittest/testdata/testconfig0.json
vendored
@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "3 Gang",
|
||||
"status_led": 0,
|
||||
"name": "3 Gang, inverted statusled",
|
||||
"statusled": 9,
|
||||
"statusled_invert": true,
|
||||
"channels": [
|
||||
{ "led": 2, "relay": 15, "button": 5 },
|
||||
{ "led": 14, "relay": 4, "button": 3 },
|
||||
|
2
unittest/testdata/testconfig1.json
vendored
2
unittest/testdata/testconfig1.json
vendored
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "3 Gang, No LEDs",
|
||||
"status_led": -1,
|
||||
"statusled": -1,
|
||||
"channels": [
|
||||
{ "led": -1, "relay": 15, "button": 5 },
|
||||
{ "led": -1, "relay": 4, "button": 3 },
|
||||
|
Reference in New Issue
Block a user