From a1236a39e7842ed24b3a9c986dba177d02be5114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Wed, 6 Mar 2019 22:36:22 +0100 Subject: Implement gui and fix rainbow selection For some reason when I use " in payload it is not send. I have no idea why but it is just probably some bug in bigclown. --- bigclown-leds | 12 +++++-- control/application.c | 96 ++++++--------------------------------------------- control/gui.c | 58 +++++++++++++++++++++++++++++++ control/gui.h | 11 ++++++ control/ledctl.c | 34 +++++------------- control/ledctl.h | 5 --- control/sensors.c | 68 ++++++++++++++++++++++++++++++++++++ control/sensors.h | 8 +++++ control/state.c | 11 ++++++ control/state.h | 29 ++++++++++++++++ 10 files changed, 213 insertions(+), 119 deletions(-) create mode 100644 control/gui.c create mode 100644 control/gui.h create mode 100644 control/sensors.c create mode 100644 control/sensors.h create mode 100644 control/state.c create mode 100644 control/state.h diff --git a/bigclown-leds b/bigclown-leds index 9bb3b0b..29d2e31 100755 --- a/bigclown-leds +++ b/bigclown-leds @@ -10,9 +10,15 @@ def on_connect(client, userdata, flags, rc): # The callback for when a PUBLISH message is received from the server. def on_message(client, userdata, msg): topic = msg.topic[26:] - client.publish( - 'node/power-controller:0/led-strip/-/' + topic, - payload=msg.payload) + if topic == 'effect/set': + # Well for now just this way + client.publish( + 'node/power-controller:0/led-strip/-/effect/set', + '{"type": "rainbow", "wait":50}') + else: + client.publish( + 'node/power-controller:0/led-strip/-/' + topic, + payload=msg.payload) #def on_log(mqttc, obj, level, string): diff --git a/control/application.c b/control/application.c index c304a84..06d6ada 100644 --- a/control/application.c +++ b/control/application.c @@ -3,61 +3,21 @@ #include #include #include "ledctl.h" - -#define SERVICE_INTERVAL_INTERVAL (60 * 60 * 1000) -#define BATTERY_UPDATE_INTERVAL (60 * 60 * 1000) - -#define TEMPERATURE_TAG_PUB_NO_CHANGE_INTEVAL (15 * 60 * 1000) -#define TEMPERATURE_TAG_PUB_VALUE_CHANGE 0.2f -#define TEMPERATURE_UPDATE_SERVICE_INTERVAL (5 * 1000) -#define TEMPERATURE_UPDATE_NORMAL_INTERVAL (10 * 1000) - -#define APPLICATION_TASK_ID 0 - -#define COLOR_BLACK true - - -typedef struct { - uint8_t number; - float value; - bc_tick_t next_pub; -} event_param_t; +#include "sensors.h" +#include "gui.h" bc_led_t led; bc_led_t led_lcd_red; bc_led_t led_lcd_blue; -// Thermometer instance -bc_tmp112_t tmp112; -event_param_t temperature_event_param = { .next_pub = 0, .value = NAN }; -float temperature_on_display = NAN; - -void tmp112_event_handler(bc_tmp112_t *self, bc_tmp112_event_t event, void *event_param) { - float value; - event_param_t *param = (event_param_t *)event_param; - - if (event != BC_TMP112_EVENT_UPDATE) - return; - - if (bc_tmp112_get_temperature_celsius(self, &value)) { - if ((fabsf(value - param->value) >= TEMPERATURE_TAG_PUB_VALUE_CHANGE) || (param->next_pub < bc_scheduler_get_spin_tick())) { - bc_radio_pub_temperature(BC_RADIO_PUB_CHANNEL_R1_I2C0_ADDRESS_ALTERNATE, &value); - param->value = value; - param->next_pub = bc_scheduler_get_spin_tick() + TEMPERATURE_TAG_PUB_NO_CHANGE_INTEVAL; - } - } else - param->value = NAN; - - if ((fabsf(param->value - temperature_on_display) >= 0.1) || isnan(temperature_on_display)) - bc_scheduler_plan_now(APPLICATION_TASK_ID); -} - void lcd_button_left_event_handler(bc_button_t *self, bc_button_event_t event, void *event_param) { if (event == BC_BUTTON_EVENT_CLICK) { click_left(); + update_gui(); bc_led_pulse(&led_lcd_blue, 30); } else if (event == BC_BUTTON_EVENT_HOLD) { hold_left(); + update_gui(); bc_led_pulse(&led_lcd_blue, 500); } } @@ -65,27 +25,18 @@ void lcd_button_left_event_handler(bc_button_t *self, bc_button_event_t event, v void lcd_button_right_event_handler(bc_button_t *self, bc_button_event_t event, void *event_param) { if (event == BC_BUTTON_EVENT_CLICK) { click_right(); + update_gui(); bc_led_pulse(&led_lcd_red, 30); } else if (event == BC_BUTTON_EVENT_HOLD) { hold_right(); + update_gui(); bc_led_pulse(&led_lcd_red, 500); } } -void battery_event_handler(bc_module_battery_event_t event, void *event_param) { - if (event != BC_MODULE_BATTERY_EVENT_UPDATE) - return; - float voltage; - if (bc_module_battery_get_voltage(&voltage)) - bc_radio_pub_battery(&voltage); -} - -void switch_to_normal_mode_task(void *param) { - bc_tmp112_set_update_interval(&tmp112, TEMPERATURE_UPDATE_NORMAL_INTERVAL); - bc_scheduler_unregister(bc_scheduler_get_current_task_id()); -} - void application_init(void) { + bc_log_init(BC_LOG_LEVEL_DEBUG, BC_LOG_TIMESTAMP_ABS); + // Initialize LED on core module bc_led_init(&led, BC_GPIO_LED, false, false); bc_led_set_mode(&led, BC_LED_MODE_OFF); @@ -94,14 +45,10 @@ void application_init(void) { bc_radio_init(BC_RADIO_MODE_NODE_SLEEPING); // Initialize battery - bc_module_battery_init(); - bc_module_battery_set_event_handler(battery_event_handler, NULL); - bc_module_battery_set_update_interval(BATTERY_UPDATE_INTERVAL); + init_battery(); // Initialize thermometer sensor on core module - bc_tmp112_init(&tmp112, BC_I2C_I2C0, 0x49); - bc_tmp112_set_event_handler(&tmp112, tmp112_event_handler, &temperature_event_param); - bc_tmp112_set_update_interval(&tmp112, TEMPERATURE_UPDATE_SERVICE_INTERVAL); + init_temperature(); // Initialize LCD bc_module_lcd_init(); @@ -122,28 +69,7 @@ void application_init(void) { bc_radio_pairing_request("lcd-thermostat", VERSION); - bc_scheduler_register(switch_to_normal_mode_task, NULL, SERVICE_INTERVAL_INTERVAL); - bc_led_pulse(&led, 2000); -} - -void application_task(void) { - static char str_temperature[10]; - if (!bc_module_lcd_is_ready()) - return; - - bc_system_pll_enable(); - bc_module_lcd_clear(); - - bc_module_lcd_set_font(&bc_font_ubuntu_33); - snprintf(str_temperature, sizeof(str_temperature), "%.1f ", temperature_event_param.value); - int x = bc_module_lcd_draw_string(20, 20, str_temperature, COLOR_BLACK); - temperature_on_display = temperature_event_param.value; - - bc_module_lcd_set_font(&bc_font_ubuntu_24); - bc_module_lcd_draw_string(x - 20, 25, "\xb0" "C ", COLOR_BLACK); - - bc_module_lcd_update(); - bc_system_pll_disable(); + update_gui(); } diff --git a/control/gui.c b/control/gui.c new file mode 100644 index 0000000..e70ff87 --- /dev/null +++ b/control/gui.c @@ -0,0 +1,58 @@ +#include "gui.h" +#include +#include "state.h" + +void update_gui() { + if (!bc_module_lcd_is_ready()) + return; + bc_system_pll_enable(); + bc_module_lcd_clear(); + + bc_module_lcd_set_font(&bc_font_ubuntu_24); + + int i; + for (i = 0; i < 24; i++) + bc_module_lcd_draw_line(0, i, 128, i, true); + if (enabled) + bc_module_lcd_draw_string(46, 2, "ON", false); + else + bc_module_lcd_draw_string(43, 2, "OFF", false); + + switch (mode) { + case MODE_SOLID_RED: + bc_module_lcd_draw_string(46, 26, "red", true); + break; + case MODE_SOLID_GREEN: + bc_module_lcd_draw_string(32, 26, "green", true); + break; + case MODE_SOLID_BLUE: + bc_module_lcd_draw_string(40, 26, "blue", true); + break; + case MODE_SOLID_YELLOW: + bc_module_lcd_draw_string(28, 26, "yellow", true); + break; + case MODE_RAINBOW: + bc_module_lcd_draw_string(19, 26, "rainbow", true); + break; + } + + for (i = 0; i < (7*brightness); i++) + bc_module_lcd_draw_line(0, 108-i, 128, 108-i, true); + + bc_module_lcd_set_font(&bc_font_ubuntu_15); + switch (state) { + case STATE_COLOR_SELECT: + bc_module_lcd_draw_string(48, 110, "color", true); + break; + case STATE_BRIGHTNESS_SELECT: + bc_module_lcd_draw_string(31, 110, "brightness", true); + break; + case STATE_DEFAULT: + default: + // pass + break; + } + + bc_module_lcd_update(); + bc_system_pll_disable(); +} diff --git a/control/gui.h b/control/gui.h new file mode 100644 index 0000000..ebf29b7 --- /dev/null +++ b/control/gui.h @@ -0,0 +1,11 @@ +#include +#include +#include +#include + +#ifndef _GUI_H_ +#define _GUI_H_ + +void update_gui(); + +#endif diff --git a/control/ledctl.c b/control/ledctl.c index d6fdd1e..76bdc67 100644 --- a/control/ledctl.c +++ b/control/ledctl.c @@ -1,37 +1,25 @@ #include "ledctl.h" +#include +#include "state.h" +#include "gui.h" -enum { - MODE_SOLID_RED, - MODE_SOLID_GREEN, - MODE_SOLID_BLUE, - MODE_SOLID_YELLOW, - MODE_RAINBOW, -} mode; -int brightness = 7; -int enabled = 0; -int current_brightness = 0; const char *mode_string[] = { [MODE_SOLID_RED] = "#FF0000", [MODE_SOLID_GREEN] = "#00FF00", [MODE_SOLID_BLUE] = "#0000FF", [MODE_SOLID_YELLOW] = "#FFFF00", - [MODE_RAINBOW] = "{\"type\":\"rainbow\", \"wait\":50}", + [MODE_RAINBOW] = "rainbow", }; -enum { - STATE_DEFAULT, - STATE_COLOR_SELECT, - STATE_BRIGHTNESS_SELECT, -} state = STATE_DEFAULT; - +int current_brightness = 0; void update_brightness() { if (!enabled) current_brightness = 0; else - current_brightness = brightness > 7 ? 100 : (1 << (brightness - 1)); + current_brightness = brightness >= brightness_max ? 100 : (1 << (brightness - 1)); bc_radio_pub_int("led/brightness/set", ¤t_brightness); } @@ -49,7 +37,7 @@ void click_left() { update_brightness(); break; case STATE_BRIGHTNESS_SELECT: - if (brightness <= 8) + if (brightness < brightness_max) brightness++; update_brightness(); break; @@ -72,7 +60,7 @@ void click_right() { update_brightness(); break; case STATE_BRIGHTNESS_SELECT: - if (brightness >= 1) + if (brightness > 1) brightness--; update_brightness(); break; @@ -92,15 +80,12 @@ void hold_left() { switch (state) { case STATE_DEFAULT: state = STATE_BRIGHTNESS_SELECT; - // TODO update image break; case STATE_COLOR_SELECT: state = STATE_COLOR_SELECT; - // TODO break; case STATE_BRIGHTNESS_SELECT: state = STATE_DEFAULT; - // TODO break; default: break; @@ -111,15 +96,12 @@ void hold_right() { switch (state) { case STATE_DEFAULT: state = STATE_COLOR_SELECT; - // TODO update image break; case STATE_COLOR_SELECT: state = STATE_DEFAULT; - // TODO break; case STATE_BRIGHTNESS_SELECT: state = STATE_BRIGHTNESS_SELECT; - // TODO break; default: break; diff --git a/control/ledctl.h b/control/ledctl.h index d7706c4..117d18d 100644 --- a/control/ledctl.h +++ b/control/ledctl.h @@ -1,8 +1,3 @@ -#include -#include -#include -#include - #ifndef _LEDCTL_H_ #define _LEDCTL_H_ diff --git a/control/sensors.c b/control/sensors.c new file mode 100644 index 0000000..0e7d9f8 --- /dev/null +++ b/control/sensors.c @@ -0,0 +1,68 @@ +#include "sensors.h" +#include + +#define SERVICE_INTERVAL_INTERVAL (60 * 60 * 1000) +#define BATTERY_UPDATE_INTERVAL (60 * 60 * 1000) + +#define TEMPERATURE_TAG_PUB_NO_CHANGE_INTEVAL (15 * 60 * 1000) +#define TEMPERATURE_TAG_PUB_VALUE_CHANGE 0.2f +#define TEMPERATURE_UPDATE_SERVICE_INTERVAL (5 * 1000) +#define TEMPERATURE_UPDATE_NORMAL_INTERVAL (10 * 1000) + +#define APPLICATION_TASK_ID 0 + + +typedef struct { + uint8_t number; + float value; + bc_tick_t next_pub; +} event_param_t; + +// Thermometer instance +bc_tmp112_t tmp112; +event_param_t temperature_event_param = { .next_pub = 0, .value = NAN }; + +void tmp112_event_handler(bc_tmp112_t *self, bc_tmp112_event_t event, void *event_param) { + float value; + event_param_t *param = (event_param_t *)event_param; + + if (event != BC_TMP112_EVENT_UPDATE) + return; + + if (bc_tmp112_get_temperature_celsius(self, &value)) { + if ((fabsf(value - param->value) >= TEMPERATURE_TAG_PUB_VALUE_CHANGE) || (param->next_pub < bc_scheduler_get_spin_tick())) { + bc_radio_pub_temperature(BC_RADIO_PUB_CHANNEL_R1_I2C0_ADDRESS_ALTERNATE, &value); + param->value = value; + param->next_pub = bc_scheduler_get_spin_tick() + TEMPERATURE_TAG_PUB_NO_CHANGE_INTEVAL; + } + } else + param->value = NAN; +} + +void switch_to_normal_mode_task(void *param) { + bc_tmp112_set_update_interval(&tmp112, TEMPERATURE_UPDATE_NORMAL_INTERVAL); + bc_scheduler_unregister(bc_scheduler_get_current_task_id()); +} + +void init_temperature() { + bc_tmp112_init(&tmp112, BC_I2C_I2C0, 0x49); + bc_tmp112_set_event_handler(&tmp112, tmp112_event_handler, &temperature_event_param); + bc_tmp112_set_update_interval(&tmp112, TEMPERATURE_UPDATE_SERVICE_INTERVAL); + + bc_scheduler_register(switch_to_normal_mode_task, NULL, SERVICE_INTERVAL_INTERVAL); +} + + +void battery_event_handler(bc_module_battery_event_t event, void *event_param) { + if (event != BC_MODULE_BATTERY_EVENT_UPDATE) + return; + float voltage; + if (bc_module_battery_get_voltage(&voltage)) + bc_radio_pub_battery(&voltage); +} + +void init_battery() { + bc_module_battery_init(); + bc_module_battery_set_event_handler(battery_event_handler, NULL); + bc_module_battery_set_update_interval(BATTERY_UPDATE_INTERVAL); +} diff --git a/control/sensors.h b/control/sensors.h new file mode 100644 index 0000000..b64f9a9 --- /dev/null +++ b/control/sensors.h @@ -0,0 +1,8 @@ + +#ifndef _SENSORS_H_ +#define _SENSORS_H_ + +void init_temperature(); +void init_battery(); + +#endif diff --git a/control/state.c b/control/state.c new file mode 100644 index 0000000..fece172 --- /dev/null +++ b/control/state.c @@ -0,0 +1,11 @@ +#include "state.h" + +enum led_mode mode; + +const unsigned brightness_max = 8; +unsigned brightness = 8; + +int enabled = 0; + + +enum state state = STATE_DEFAULT; diff --git a/control/state.h b/control/state.h new file mode 100644 index 0000000..5f9525f --- /dev/null +++ b/control/state.h @@ -0,0 +1,29 @@ +#ifndef _STATE_H_ +#define _STATE_H_ + +enum led_mode { + MODE_SOLID_RED, + MODE_SOLID_GREEN, + MODE_SOLID_BLUE, + MODE_SOLID_YELLOW, + MODE_RAINBOW, +}; + +extern enum led_mode mode; + +extern const unsigned brightness_max; +extern unsigned brightness; + +extern int enabled; + +enum state { + STATE_DEFAULT, + STATE_COLOR_SELECT, + STATE_BRIGHTNESS_SELECT, +}; + +extern enum state state; + + + +#endif -- cgit v1.2.3