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:
Pim van Pelt
2018-01-24 13:33:13 +01:00
parent f0fa04dc26
commit 118eb14447
11 changed files with 56 additions and 43 deletions

View File

@ -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 },

View File

@ -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 }
]

View File

@ -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);

View File

@ -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));

View File

@ -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);
}

View File

@ -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();

View File

@ -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
View 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);
}

View File

@ -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)

View File

@ -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 },

View File

@ -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 },