Formatting
This commit is contained in:
@ -3,13 +3,15 @@
|
||||
#include "frozen/frozen.h"
|
||||
|
||||
static struct channel_t s_channels[CHANNEL_MAX];
|
||||
static int s_num_channels=0;
|
||||
static int s_num_channels = 0;
|
||||
|
||||
static bool valid_gpio(const int gpio) {
|
||||
if (gpio == -1)
|
||||
if (gpio == -1) {
|
||||
return true;
|
||||
if (gpio < GPIO_MIN || gpio > GPIO_MAX)
|
||||
}
|
||||
if (gpio < GPIO_MIN || gpio > GPIO_MAX) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -18,19 +20,19 @@ int channel_get_total() {
|
||||
}
|
||||
|
||||
bool channel_init(const char *fn) {
|
||||
char *json;
|
||||
void *h = NULL;
|
||||
char * json;
|
||||
void * h = NULL;
|
||||
struct json_token val;
|
||||
bool ret = false;
|
||||
|
||||
char *name = NULL;
|
||||
int statusled = -1;
|
||||
bool statusled_invert = false;
|
||||
char *name = NULL;
|
||||
int statusled = -1;
|
||||
bool statusled_invert = false;
|
||||
|
||||
int idx;
|
||||
|
||||
memset(s_channels, -1, sizeof(s_channels));
|
||||
s_num_channels=0;
|
||||
s_num_channels = 0;
|
||||
|
||||
json = json_fread(fn);
|
||||
if (!json) {
|
||||
@ -54,11 +56,12 @@ bool channel_init(const char *fn) {
|
||||
|
||||
// Traverse Array
|
||||
while ((h = json_next_elem(json, strlen(json), h, ".channels", &idx, &val)) != NULL) {
|
||||
int led=-1, relay=-1, button=-1;
|
||||
int led = -1, relay = -1, button = -1;
|
||||
|
||||
LOG(LL_DEBUG, ("[%d]: [%.*s]", idx, val.len, val.ptr));
|
||||
if (val.len==0 || !val.ptr)
|
||||
if (val.len == 0 || !val.ptr) {
|
||||
continue;
|
||||
}
|
||||
if (json_scanf(val.ptr, val.len, "{led:%d, relay:%d, button:%d}", &led, &relay, &button) != 3) {
|
||||
LOG(LL_ERROR, ("Incomplete Channel JSON: require 'led' and 'relay' and 'button' fields"));
|
||||
goto exit;
|
||||
@ -76,60 +79,67 @@ bool channel_init(const char *fn) {
|
||||
LOG(LL_ERROR, ("Button GPIO (%d) out of bounds [%d,%d]", button, GPIO_MIN, GPIO_MAX));
|
||||
goto exit;
|
||||
}
|
||||
if (idx==CHANNEL_MAX) {
|
||||
if (idx == CHANNEL_MAX) {
|
||||
LOG(LL_ERROR, ("Too many channels (max is %d)", CHANNEL_MAX));
|
||||
goto exit;
|
||||
}
|
||||
s_channels[idx].button_gpio=button;
|
||||
s_channels[idx].relay_gpio=relay;
|
||||
s_channels[idx].led_gpio=led;
|
||||
s_channels[idx].button_gpio = button;
|
||||
s_channels[idx].relay_gpio = relay;
|
||||
s_channels[idx].led_gpio = led;
|
||||
}
|
||||
|
||||
ret=true;
|
||||
ret = true;
|
||||
exit:
|
||||
if (ret) {
|
||||
if (statusled!=-1)
|
||||
statusled_init(statusled,statusled_invert);
|
||||
if (statusled != -1) {
|
||||
statusled_init(statusled, statusled_invert);
|
||||
}
|
||||
|
||||
s_num_channels=idx+1;
|
||||
s_num_channels = idx + 1;
|
||||
LOG(LL_INFO, ("Configuring %d channels", s_num_channels));
|
||||
|
||||
for (; idx>=0; idx--) {
|
||||
for (; idx >= 0; idx--) {
|
||||
s_channels[idx].relay_state = 0;
|
||||
|
||||
if (s_channels[idx].relay_gpio!=GPIO_INVALID) {
|
||||
if (s_channels[idx].relay_gpio != GPIO_INVALID) {
|
||||
mgos_gpio_set_mode(s_channels[idx].relay_gpio, MGOS_GPIO_MODE_OUTPUT);
|
||||
mgos_gpio_write(s_channels[idx].relay_gpio, s_channels[idx].relay_state);
|
||||
}
|
||||
|
||||
if (s_channels[idx].led_gpio!=GPIO_INVALID) {
|
||||
if (s_channels[idx].led_gpio != GPIO_INVALID) {
|
||||
mgos_gpio_set_mode(s_channels[idx].led_gpio, MGOS_GPIO_MODE_OUTPUT);
|
||||
mgos_gpio_write(s_channels[idx].led_gpio, s_channels[idx].relay_state);
|
||||
}
|
||||
|
||||
if (s_channels[idx].button_gpio!=GPIO_INVALID) {
|
||||
if (s_channels[idx].button_gpio != GPIO_INVALID) {
|
||||
mgos_gpio_set_mode(s_channels[idx].button_gpio, MGOS_GPIO_MODE_INPUT);
|
||||
mgos_gpio_set_button_handler(s_channels[idx].button_gpio, MGOS_GPIO_PULL_UP, MGOS_GPIO_INT_EDGE_POS, 200, channel_handler, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (name) free(name);
|
||||
if (json) free(json);
|
||||
if (name) {
|
||||
free(name);
|
||||
}
|
||||
if (json) {
|
||||
free(json);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t channel_gpio_by_idx(int idx) {
|
||||
if (idx<0 || idx>=s_num_channels)
|
||||
if (idx < 0 || idx >= s_num_channels) {
|
||||
return GPIO_INVALID;
|
||||
}
|
||||
return s_channels[idx].button_gpio;
|
||||
}
|
||||
|
||||
uint8_t channel_idx_by_gpio(int gpio) {
|
||||
uint8_t i;
|
||||
|
||||
for(i=0; i<channel_get_total(); i++) {
|
||||
if (gpio == s_channels[i].button_gpio)
|
||||
for (i = 0; i < channel_get_total(); i++) {
|
||||
if (gpio == s_channels[i].button_gpio) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return GPIO_INVALID;
|
||||
}
|
||||
@ -137,30 +147,34 @@ uint8_t channel_idx_by_gpio(int gpio) {
|
||||
void channel_set(int idx, bool state) {
|
||||
double now = mg_time();
|
||||
|
||||
if (idx<0 || idx>=channel_get_total())
|
||||
if (idx < 0 || idx >= channel_get_total()) {
|
||||
return;
|
||||
}
|
||||
|
||||
s_channels[idx].button_last_change = now;
|
||||
s_channels[idx].relay_state = state;
|
||||
if (s_channels[idx].relay_gpio!=GPIO_INVALID)
|
||||
s_channels[idx].relay_state = state;
|
||||
if (s_channels[idx].relay_gpio != GPIO_INVALID) {
|
||||
mgos_gpio_write(s_channels[idx].relay_gpio, state);
|
||||
if (s_channels[idx].led_gpio!=GPIO_INVALID)
|
||||
}
|
||||
if (s_channels[idx].led_gpio != GPIO_INVALID) {
|
||||
mgos_gpio_write(s_channels[idx].led_gpio, state);
|
||||
}
|
||||
|
||||
mqtt_publish_stat("channel", "{idx: %d, relay_state: %d}", idx, channel_get(idx));
|
||||
}
|
||||
|
||||
bool channel_get(int idx) {
|
||||
if (idx<0 || idx>=channel_get_total())
|
||||
if (idx < 0 || idx >= channel_get_total()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return s_channels[idx].relay_state == 1;
|
||||
}
|
||||
|
||||
void channel_handler(int gpio, void *arg) {
|
||||
uint8_t idx;
|
||||
double now = mg_time();
|
||||
bool state;
|
||||
double now = mg_time();
|
||||
bool state;
|
||||
|
||||
idx = channel_idx_by_gpio(gpio);
|
||||
if (idx == GPIO_INVALID) {
|
||||
@ -168,7 +182,7 @@ void channel_handler(int gpio, void *arg) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (now<s_channels[idx].button_last_change+CHANNEL_CHANGE_COOLDOWN_SECONDS) {
|
||||
if (now < s_channels[idx].button_last_change + CHANNEL_CHANGE_COOLDOWN_SECONDS) {
|
||||
LOG(LL_INFO, ("GPIO %d is cooling down -- skipping", gpio));
|
||||
return;
|
||||
}
|
||||
@ -177,5 +191,5 @@ void channel_handler(int gpio, void *arg) {
|
||||
state = channel_get(idx);
|
||||
channel_set(idx, !state);
|
||||
|
||||
(void) arg;
|
||||
(void)arg;
|
||||
}
|
||||
|
56
src/mqtt.c
56
src/mqtt.c
@ -10,9 +10,9 @@ static void mqtt_publish_broadcast_stat(const char *stat, const char *msg) {
|
||||
char topic[80];
|
||||
|
||||
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);
|
||||
|
||||
snprintf(topic, sizeof(topic) - 1, "%s/%s", MQTT_TOPIC_BROADCAST_STAT, stat);
|
||||
mgos_mqtt_pub((char *)topic, (char *)msg, strlen(msg), 0, false);
|
||||
LOG(LL_INFO, ("Sent topic='%s' msg='%s'", topic, msg));
|
||||
statusled_blink();
|
||||
}
|
||||
@ -25,18 +25,20 @@ static void mqtt_broadcast_cmd_id() {
|
||||
memset(sta_ip, 0, sizeof(sta_ip));
|
||||
memset(ap_ip, 0, sizeof(ap_ip));
|
||||
|
||||
if (mgos_net_get_ip_info(MGOS_NET_IF_TYPE_WIFI, MGOS_NET_IF_WIFI_STA, &ip_info))
|
||||
if (mgos_net_get_ip_info(MGOS_NET_IF_TYPE_WIFI, MGOS_NET_IF_WIFI_STA, &ip_info)) {
|
||||
mgos_net_ip_to_str(&ip_info.ip, sta_ip);
|
||||
if (mgos_net_get_ip_info(MGOS_NET_IF_TYPE_WIFI, MGOS_NET_IF_WIFI_AP, &ip_info))
|
||||
}
|
||||
if (mgos_net_get_ip_info(MGOS_NET_IF_TYPE_WIFI, MGOS_NET_IF_WIFI_AP, &ip_info)) {
|
||||
mgos_net_ip_to_str(&ip_info.ip, ap_ip);
|
||||
}
|
||||
|
||||
snprintf(resp, sizeof(resp)-1, "{\"deviceid\": \"%s\", \"macaddress\": \"%s\", \"sta_ip\": \"%s\", \"ap_ip\": \"%s\", \"app\": \"%s\", \"arch\": \"%s\", \"uptime\": %lu}",
|
||||
mgos_sys_config_get_device_id(),
|
||||
mgos_sys_ro_vars_get_mac_address(),
|
||||
sta_ip,
|
||||
ap_ip,
|
||||
MGOS_APP,
|
||||
mgos_sys_ro_vars_get_arch(), (unsigned long) mgos_uptime());
|
||||
snprintf(resp, sizeof(resp) - 1, "{\"deviceid\": \"%s\", \"macaddress\": \"%s\", \"sta_ip\": \"%s\", \"ap_ip\": \"%s\", \"app\": \"%s\", \"arch\": \"%s\", \"uptime\": %lu}",
|
||||
mgos_sys_config_get_device_id(),
|
||||
mgos_sys_ro_vars_get_mac_address(),
|
||||
sta_ip,
|
||||
ap_ip,
|
||||
MGOS_APP,
|
||||
mgos_sys_ro_vars_get_arch(), (unsigned long)mgos_uptime());
|
||||
|
||||
mqtt_publish_broadcast_stat("id", resp);
|
||||
}
|
||||
@ -45,38 +47,38 @@ static void mqtt_cb(struct mg_connection *nc, const char *topic, int topic_len,
|
||||
LOG(LL_INFO, ("Received topic='%.*s' msg='%.*s'", topic_len, topic, msg_len, msg));
|
||||
statusled_blink();
|
||||
|
||||
if (topic_len >= (int) strlen(MQTT_TOPIC_BROADCAST_CMD) && 0 == strncmp(MQTT_TOPIC_BROADCAST_CMD, topic, strlen(MQTT_TOPIC_BROADCAST_CMD)))
|
||||
if (topic_len >= (int)strlen(MQTT_TOPIC_BROADCAST_CMD) && 0 == strncmp(MQTT_TOPIC_BROADCAST_CMD, topic, strlen(MQTT_TOPIC_BROADCAST_CMD))) {
|
||||
mqtt_broadcast_cmd_id();
|
||||
(void) nc;
|
||||
(void) ud;
|
||||
}
|
||||
(void)nc;
|
||||
(void)ud;
|
||||
}
|
||||
|
||||
static void mqtt_ev(struct mg_connection *nc, int ev, void *ev_data, void *user_data) {
|
||||
switch (ev) {
|
||||
case MG_EV_MQTT_CONNACK:
|
||||
mqtt_broadcast_cmd_id();
|
||||
case MG_EV_MQTT_CONNACK:
|
||||
mqtt_broadcast_cmd_id();
|
||||
break;
|
||||
}
|
||||
(void) nc;
|
||||
(void) ev_data;
|
||||
(void) user_data;
|
||||
(void)nc;
|
||||
(void)ev_data;
|
||||
(void)user_data;
|
||||
}
|
||||
|
||||
|
||||
void mqtt_publish_stat(const char *stat, const char *fmt, ...) {
|
||||
char topic[80];
|
||||
char msg[200];
|
||||
char topic[80];
|
||||
char msg[200];
|
||||
struct json_out out = JSON_OUT_BUF(msg, 200);
|
||||
va_list ap;
|
||||
va_list ap;
|
||||
|
||||
|
||||
snprintf(topic, sizeof(topic)-1, "%s%s/stat/%s", MQTT_TOPIC_PREFIX, mgos_sys_config_get_device_id(), stat);
|
||||
snprintf(topic, sizeof(topic) - 1, "%s%s/stat/%s", MQTT_TOPIC_PREFIX, mgos_sys_config_get_device_id(), stat);
|
||||
|
||||
va_start(ap, fmt);
|
||||
json_vprintf(&out, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
mgos_mqtt_pub((char*)topic, (char*)msg, strlen(msg), 0, false);
|
||||
mgos_mqtt_pub((char *)topic, (char *)msg, strlen(msg), 0, false);
|
||||
LOG(LL_INFO, ("Sent topic='%s' msg='%s'", topic, msg));
|
||||
statusled_blink();
|
||||
}
|
||||
@ -90,7 +92,7 @@ void mqtt_init() {
|
||||
mgos_mqtt_sub(MQTT_TOPIC_BROADCAST_CMD, mqtt_cb, NULL);
|
||||
|
||||
// Subscribe to broadcast/appname
|
||||
snprintf(topic, sizeof(topic)-1, "%s/%s", MQTT_TOPIC_BROADCAST_CMD, MGOS_APP);
|
||||
snprintf(topic, sizeof(topic) - 1, "%s/%s", MQTT_TOPIC_BROADCAST_CMD, MGOS_APP);
|
||||
mgos_mqtt_sub(topic, mqtt_cb, NULL);
|
||||
|
||||
return;
|
||||
|
51
src/rpc.c
51
src/rpc.c
@ -21,8 +21,8 @@ static bool rpc_args_to_idx_and_gpio(struct mg_rpc_request_info *ri, struct mg_s
|
||||
return false;
|
||||
}
|
||||
|
||||
if (idx<0 || idx>=channel_get_total()) {
|
||||
mg_rpc_send_errorf(ri, 400, "idx must be between 0 and %d", channel_get_total()-1);
|
||||
if (idx < 0 || idx >= channel_get_total()) {
|
||||
mg_rpc_send_errorf(ri, 400, "idx must be between 0 and %d", channel_get_total() - 1);
|
||||
ri = NULL;
|
||||
return false;
|
||||
}
|
||||
@ -35,51 +35,53 @@ static bool rpc_args_to_idx_and_gpio(struct mg_rpc_request_info *ri, struct mg_s
|
||||
}
|
||||
|
||||
*return_gpio = gpio;
|
||||
*return_idx = idx;
|
||||
*return_idx = idx;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void rpc_channel_toggle_handler(struct mg_rpc_request_info *ri, void *cb_arg, struct mg_rpc_frame_info *fi, struct mg_str args) {
|
||||
uint8_t gpio;
|
||||
int idx;
|
||||
int idx;
|
||||
|
||||
rpc_log(ri, args);
|
||||
|
||||
if (!rpc_args_to_idx_and_gpio(ri, args, &idx, &gpio))
|
||||
if (!rpc_args_to_idx_and_gpio(ri, args, &idx, &gpio)) {
|
||||
return;
|
||||
}
|
||||
|
||||
channel_handler(gpio, NULL);
|
||||
mg_rpc_send_responsef(ri, "{idx: %d, relay_state: %d}", idx, channel_get(idx));
|
||||
ri = NULL;
|
||||
|
||||
(void) ri;
|
||||
(void) cb_arg;
|
||||
(void) fi;
|
||||
(void) args;
|
||||
(void)ri;
|
||||
(void)cb_arg;
|
||||
(void)fi;
|
||||
(void)args;
|
||||
}
|
||||
|
||||
static void rpc_channel_get_handler(struct mg_rpc_request_info *ri, void *cb_arg, struct mg_rpc_frame_info *fi, struct mg_str args) {
|
||||
uint8_t gpio;
|
||||
int idx;
|
||||
int idx;
|
||||
|
||||
rpc_log(ri, args);
|
||||
|
||||
if (!rpc_args_to_idx_and_gpio(ri, args, &idx, &gpio))
|
||||
if (!rpc_args_to_idx_and_gpio(ri, args, &idx, &gpio)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mg_rpc_send_responsef(ri, "{idx: %d, relay_state: %d}", idx, channel_get(idx));
|
||||
ri = NULL;
|
||||
|
||||
(void) ri;
|
||||
(void) cb_arg;
|
||||
(void) fi;
|
||||
(void) args;
|
||||
(void)ri;
|
||||
(void)cb_arg;
|
||||
(void)fi;
|
||||
(void)args;
|
||||
}
|
||||
|
||||
static void rpc_channel_set_handler(struct mg_rpc_request_info *ri, void *cb_arg, struct mg_rpc_frame_info *fi, struct mg_str args) {
|
||||
uint8_t gpio;
|
||||
int idx;
|
||||
int value;
|
||||
int idx;
|
||||
int value;
|
||||
|
||||
rpc_log(ri, args);
|
||||
|
||||
@ -89,8 +91,8 @@ static void rpc_channel_set_handler(struct mg_rpc_request_info *ri, void *cb_arg
|
||||
return;
|
||||
}
|
||||
|
||||
if (idx<0 || idx>=channel_get_total()) {
|
||||
mg_rpc_send_errorf(ri, 400, "idx must be between 0 and %d", channel_get_total()-1);
|
||||
if (idx < 0 || idx >= channel_get_total()) {
|
||||
mg_rpc_send_errorf(ri, 400, "idx must be between 0 and %d", channel_get_total() - 1);
|
||||
ri = NULL;
|
||||
return;
|
||||
}
|
||||
@ -102,18 +104,19 @@ static void rpc_channel_set_handler(struct mg_rpc_request_info *ri, void *cb_arg
|
||||
return;
|
||||
}
|
||||
|
||||
channel_set(idx, (bool) value);
|
||||
channel_set(idx, (bool)value);
|
||||
mg_rpc_send_responsef(ri, "{idx: %d, relay_state: %d}", idx, channel_get(idx));
|
||||
ri = NULL;
|
||||
|
||||
(void) ri;
|
||||
(void) cb_arg;
|
||||
(void) fi;
|
||||
(void) args;
|
||||
(void)ri;
|
||||
(void)cb_arg;
|
||||
(void)fi;
|
||||
(void)args;
|
||||
}
|
||||
|
||||
void rpc_init() {
|
||||
struct mg_rpc *c = mgos_rpc_get_global();
|
||||
|
||||
mg_rpc_add_handler(c, "Channel.Toggle", "{idx: %d}", rpc_channel_toggle_handler, NULL);
|
||||
mg_rpc_add_handler(c, "Channel.Get", "{idx: %d}", rpc_channel_get_handler, NULL);
|
||||
mg_rpc_add_handler(c, "Channel.Set", "{idx: %d, value: %d}", rpc_channel_set_handler, NULL);
|
||||
|
@ -1,29 +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 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;
|
||||
statusled_timer_id = 0;
|
||||
(void)arg;
|
||||
}
|
||||
|
||||
void statusled_blink() {
|
||||
if (statusled_gpio == GPIO_INVALID)
|
||||
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 = 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_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);
|
||||
|
Reference in New Issue
Block a user