First start of MQTT buttons
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "One",
|
"name": "Heli",
|
||||||
"widgets": [
|
"widgets": [
|
||||||
{
|
{
|
||||||
"name": "back",
|
"name": "back",
|
||||||
@ -12,13 +12,34 @@
|
|||||||
"screen": "/screen_main.json"
|
"screen": "/screen_main.json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "one",
|
"name": "heli_led_on",
|
||||||
"x": 256,
|
"x": 240,
|
||||||
"y": 36,
|
"y": 36,
|
||||||
"w": 48,
|
"w": 64,
|
||||||
"h": 48,
|
"h": 56,
|
||||||
"label": "One",
|
"label": "On",
|
||||||
"type": 0
|
"type": 1,
|
||||||
|
"mqtt": [ "/s/cmnd/60:01:94:80:85:01/power3 On" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "heli_led_off",
|
||||||
|
"x": 240,
|
||||||
|
"y": 108,
|
||||||
|
"w": 64,
|
||||||
|
"h": 56,
|
||||||
|
"label": "Off",
|
||||||
|
"type": 1,
|
||||||
|
"mqtt": [ "/s/cmnd/60:01:94:80:85:01/power3 Off" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "heli_led_toggle",
|
||||||
|
"x": 240,
|
||||||
|
"y": 180,
|
||||||
|
"w": 64,
|
||||||
|
"h": 56,
|
||||||
|
"label": "Toggle",
|
||||||
|
"type": 1,
|
||||||
|
"mqtt": [ "/s/cmnd/60:01:94:80:85:01/power3 Toggle", "test", "foo", "bar" ]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
18
src/widget.c
18
src/widget.c
@ -81,6 +81,8 @@ struct widget_t *widget_create_from_json(const char *json) {
|
|||||||
widget->type=type;
|
widget->type=type;
|
||||||
widget->label=label;
|
widget->label=label;
|
||||||
widget->img=img;
|
widget->img=img;
|
||||||
|
|
||||||
|
// Load widget-specific attributes
|
||||||
if (type == WIDGET_TYPE_LOADSCREEN) {
|
if (type == WIDGET_TYPE_LOADSCREEN) {
|
||||||
if (json_scanf(json, strlen(json), "{screen:%Q}", &screen) != 1) {
|
if (json_scanf(json, strlen(json), "{screen:%Q}", &screen) != 1) {
|
||||||
LOG(LL_WARN, ("Widget '%s' is of type LOADSCREEN but does not have attribute 'screen'", widget->name));
|
LOG(LL_WARN, ("Widget '%s' is of type LOADSCREEN but does not have attribute 'screen'", widget->name));
|
||||||
@ -88,6 +90,22 @@ struct widget_t *widget_create_from_json(const char *json) {
|
|||||||
if (widget->user_data) free(widget->user_data);
|
if (widget->user_data) free(widget->user_data);
|
||||||
widget->user_data = screen;
|
widget->user_data = screen;
|
||||||
}
|
}
|
||||||
|
} else if (type == WIDGET_TYPE_MQTT_BUTTON) {
|
||||||
|
void *h = NULL;
|
||||||
|
char *mqtt = NULL;
|
||||||
|
struct json_token val;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
if (json_scanf(json, strlen(json), "{mqtt:%Q}", &mqtt) != 1) {
|
||||||
|
LOG(LL_WARN, ("Widget '%s' is of type MQTT_BUTTON but does not have attribute 'mqtt'", widget->name));
|
||||||
|
} else {
|
||||||
|
while ((h = json_next_elem(json, strlen(json), h, ".mqtt", &idx, &val)) != NULL) {
|
||||||
|
LOG(LL_INFO, ("[%d]: [%.*s]", idx, val.len, val.ptr));
|
||||||
|
if (val.len>0 && val.ptr) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(mqtt) free(mqtt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return widget;
|
return widget;
|
||||||
|
@ -78,6 +78,7 @@ void screen_add_default_widgets(struct screen_t *screen) {
|
|||||||
|
|
||||||
static void widget_default_loadscreen(struct widget_t *w, void *ev_data) {
|
static void widget_default_loadscreen(struct widget_t *w, void *ev_data) {
|
||||||
struct screen_t *new_screen;
|
struct screen_t *new_screen;
|
||||||
|
char *new_screen_fn;
|
||||||
|
|
||||||
if (!w)
|
if (!w)
|
||||||
return;
|
return;
|
||||||
@ -86,8 +87,12 @@ static void widget_default_loadscreen(struct widget_t *w, void *ev_data) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new_screen_fn=strdup(w->user_data);
|
||||||
|
|
||||||
|
screen_destroy(&s_screen);
|
||||||
|
new_screen = screen_create_from_file(new_screen_fn, widget_default_ev, NULL);
|
||||||
|
free(new_screen_fn);
|
||||||
|
|
||||||
new_screen = screen_create_from_file(w->user_data, widget_default_ev, NULL);
|
|
||||||
if (!new_screen) {
|
if (!new_screen) {
|
||||||
LOG(LL_ERROR, ("Could not load screen"));
|
LOG(LL_ERROR, ("Could not load screen"));
|
||||||
return;
|
return;
|
||||||
@ -95,7 +100,6 @@ static void widget_default_loadscreen(struct widget_t *w, void *ev_data) {
|
|||||||
screen_add_default_widgets(new_screen);
|
screen_add_default_widgets(new_screen);
|
||||||
|
|
||||||
LOG(LL_INFO, ("Navigating to new screen '%s' which has %d widgets", new_screen->name, screen_get_num_widgets(new_screen)));
|
LOG(LL_INFO, ("Navigating to new screen '%s' which has %d widgets", new_screen->name, screen_get_num_widgets(new_screen)));
|
||||||
screen_destroy(&s_screen);
|
|
||||||
s_screen = new_screen;
|
s_screen = new_screen;
|
||||||
screen_widget_broadcast(s_screen, EV_WIDGET_DRAW, NULL);
|
screen_widget_broadcast(s_screen, EV_WIDGET_DRAW, NULL);
|
||||||
|
|
||||||
@ -109,7 +113,7 @@ void widget_default_ev(int ev, struct widget_t *w, void *ev_data) {
|
|||||||
return;
|
return;
|
||||||
widget_ev_to_str(ev, evname, sizeof(evname)-1);
|
widget_ev_to_str(ev, evname, sizeof(evname)-1);
|
||||||
|
|
||||||
LOG(LL_INFO, ("Event %s received for widget '%s'", evname, w->name));
|
LOG(LL_DEBUG, ("Event %s received for widget '%s'", evname, w->name));
|
||||||
|
|
||||||
switch(ev) {
|
switch(ev) {
|
||||||
case EV_WIDGET_CREATE:
|
case EV_WIDGET_CREATE:
|
||||||
|
@ -7,6 +7,9 @@ static mgos_timer_id recv_timer = 0;
|
|||||||
static struct widget_t *widget_network = NULL;
|
static struct widget_t *widget_network = NULL;
|
||||||
|
|
||||||
static void widget_network_render(struct widget_t *w, void *ev_data) {
|
static void widget_network_render(struct widget_t *w, void *ev_data) {
|
||||||
|
if (!w)
|
||||||
|
return;
|
||||||
|
|
||||||
mgos_ili9341_set_window(w->x, w->y, w->x+w->w-1, w->y+w->h-1);
|
mgos_ili9341_set_window(w->x, w->y, w->x+w->w-1, w->y+w->h-1);
|
||||||
// Send
|
// Send
|
||||||
mgos_ili9341_set_fgcolor565(send_timer?ILI9341_YELLOW:ILI9341_DARKGREY);
|
mgos_ili9341_set_fgcolor565(send_timer?ILI9341_YELLOW:ILI9341_DARKGREY);
|
||||||
@ -34,8 +37,10 @@ static void widget_network_recv_clear(void *arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void widget_network_send() {
|
void widget_network_send() {
|
||||||
if (!widget_network)
|
if (!widget_network) {
|
||||||
|
LOG(LL_ERROR, ("called without widget_network set"));
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!send_timer)
|
if (!send_timer)
|
||||||
send_timer=mgos_set_timer(100, 0, widget_network_send_clear, NULL);
|
send_timer=mgos_set_timer(100, 0, widget_network_send_clear, NULL);
|
||||||
@ -43,8 +48,10 @@ void widget_network_send() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void widget_network_recv() {
|
void widget_network_recv() {
|
||||||
if (!widget_network)
|
if (!widget_network) {
|
||||||
|
LOG(LL_ERROR, ("called without widget_network set"));
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!recv_timer)
|
if (!recv_timer)
|
||||||
recv_timer=mgos_set_timer(100, 0, widget_network_recv_clear, NULL);
|
recv_timer=mgos_set_timer(100, 0, widget_network_recv_clear, NULL);
|
||||||
@ -52,12 +59,18 @@ void widget_network_recv() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void widget_network_ev(int ev, struct widget_t *w, void *ev_data) {
|
void widget_network_ev(int ev, struct widget_t *w, void *ev_data) {
|
||||||
|
char evname[15];
|
||||||
if (!w)
|
if (!w)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
widget_ev_to_str(ev, evname, sizeof(evname)-1);
|
||||||
|
LOG(LL_DEBUG, ("Event %s received for widget '%s'", evname, w->name));
|
||||||
|
|
||||||
switch(ev) {
|
switch(ev) {
|
||||||
case EV_WIDGET_CREATE:
|
case EV_WIDGET_CREATE:
|
||||||
widget_network=w;
|
widget_network=w;
|
||||||
|
send_timer=0;
|
||||||
|
recv_timer=0;
|
||||||
break;
|
break;
|
||||||
case EV_WIDGET_DRAW:
|
case EV_WIDGET_DRAW:
|
||||||
case EV_WIDGET_REDRAW:
|
case EV_WIDGET_REDRAW:
|
||||||
@ -65,7 +78,11 @@ void widget_network_ev(int ev, struct widget_t *w, void *ev_data) {
|
|||||||
break;
|
break;
|
||||||
case EV_WIDGET_DESTROY:
|
case EV_WIDGET_DESTROY:
|
||||||
widget_network=NULL;
|
widget_network=NULL;
|
||||||
|
if (send_timer)
|
||||||
|
mgos_clear_timer(send_timer);
|
||||||
send_timer=0;
|
send_timer=0;
|
||||||
|
if (recv_timer)
|
||||||
|
mgos_clear_timer(recv_timer);
|
||||||
recv_timer=0;
|
recv_timer=0;
|
||||||
break;
|
break;
|
||||||
case EV_WIDGET_TIMER:
|
case EV_WIDGET_TIMER:
|
||||||
|
10
unittest/data/TestWidget-MQTT.json
Normal file
10
unittest/data/TestWidget-MQTT.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"name": "heli_led_on",
|
||||||
|
"x": 240,
|
||||||
|
"y": 36,
|
||||||
|
"w": 64,
|
||||||
|
"h": 56,
|
||||||
|
"label": "On",
|
||||||
|
"type": 1,
|
||||||
|
"mqtt": [ "/topic1 Hello", "/topic2 World" ]
|
||||||
|
}
|
@ -5,6 +5,6 @@
|
|||||||
"w": 48,
|
"w": 48,
|
||||||
"h": 48,
|
"h": 48,
|
||||||
"label": "One",
|
"label": "One",
|
||||||
"type": 0
|
"type": 0,
|
||||||
"img": "/some/file.ext"
|
"img": "/some/file.ext"
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ int assert_count=0;
|
|||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
test_widget();
|
test_widget();
|
||||||
|
test_widget_mqtt();
|
||||||
test_screen();
|
test_screen();
|
||||||
|
|
||||||
if (test_failures) {
|
if (test_failures) {
|
||||||
|
@ -21,6 +21,7 @@ extern int assert_count;
|
|||||||
|
|
||||||
|
|
||||||
int test_widget(void);
|
int test_widget(void);
|
||||||
|
int test_widget_mqtt(void);
|
||||||
int test_screen(void);
|
int test_screen(void);
|
||||||
|
|
||||||
#endif // __TEST_H
|
#endif // __TEST_H
|
||||||
|
@ -71,3 +71,15 @@ int test_widget() {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int test_widget_mqtt() {
|
||||||
|
struct widget_t *w;
|
||||||
|
|
||||||
|
char *fn = "data/TestWidget-MQTT.json";
|
||||||
|
LOG(LL_INFO, ("widget_create_from_file(%s)", fn));
|
||||||
|
w = widget_create_from_file(fn);
|
||||||
|
ASSERT(w, "widget_create_from_file()");
|
||||||
|
ASSERT(w->x == 240, "'x' field is invalid");
|
||||||
|
ASSERT(w->type == WIDGET_TYPE_MQTT_BUTTON, "'type' field is not WIDGET_TYPE_MQTT_BUTTON");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user