From 0f342b4aa8c0cee1e8dbc47fd112aeacff3d40b0 Mon Sep 17 00:00:00 2001 From: Tobias Reisinger Date: Sat, 27 Jun 2020 18:27:49 +0200 Subject: [PATCH] add: pulse mode add: editorconfig --- .editorconfig | 12 +++++ CMakeLists.txt | 2 +- controller.ini | 2 + include/config.h | 1 + include/enums.h | 2 + include/models/relay.h | 4 +- include/wiring_debug.h | 11 ++-- src/handlers/command.c | 104 +++++++++++++++++++++++--------------- src/handlers/loop.c | 48 +++++++++++++----- src/helpers/load_config.c | 10 +++- src/main.c | 17 ++++--- src/models/relay.c | 4 +- src/models/relay_load.c | 4 ++ 13 files changed, 151 insertions(+), 70 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..ab2168d --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# EditorConfig is awesome: +https://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 4 diff --git a/CMakeLists.txt b/CMakeLists.txt index 18e1934..ada0b47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 3.7) project(controller - VERSION 0.2.0 + VERSION 0.2.1 LANGUAGES C) add_executable(controller src/main.c) diff --git a/controller.ini b/controller.ini index da0bcae..a1165fd 100644 --- a/controller.ini +++ b/controller.ini @@ -54,8 +54,10 @@ inverted = 1 driver = gpio pin = 16 inverted = 1 +pulse-duration = 3 [relay-9] driver = gpio pin = 15 inverted = 1 +pulse-duration = 3 diff --git a/include/config.h b/include/config.h index 80d7bb1..19ce6de 100644 --- a/include/config.h +++ b/include/config.h @@ -11,6 +11,7 @@ typedef struct uint8_t pin; int inverted; relay_driver_t driver; + uint8_t pulse_duration; } config_relay_t; typedef struct diff --git a/include/enums.h b/include/enums.h index a2c0709..c9288d0 100644 --- a/include/enums.h +++ b/include/enums.h @@ -24,6 +24,7 @@ typedef enum COMMAND_MAPPING_SCHEDULE_ID = 4, COMMAND_MAPPING_PERIODS_COUNT = 5, COMMAND_MAPPING_PERIODS_BLOB = 6, + COMMAND_MAPPING_PULSE_DURATION = 7, } control_mapping_t; typedef enum @@ -36,6 +37,7 @@ typedef enum COMMAND_CODE_GET_SCHEDULE = 103, COMMAND_CODE_SET_RELAY_NAME = 104, COMMAND_CODE_GET_RELAY_NAME = 105, + COMMAND_CODE_PULSE = 200, } command_code_t; typedef enum diff --git a/include/models/relay.h b/include/models/relay.h index 224e7b4..c2efd58 100644 --- a/include/models/relay.h +++ b/include/models/relay.h @@ -12,6 +12,8 @@ typedef struct { uint8_t number; int is_on; + int is_on_schedule; + int pulse_timer; int sent_to_broker; char name[MAX_NAME_LENGTH + 1]; schedule_t *schedules[7]; @@ -53,7 +55,7 @@ int relay_save(relay_t *relay, MDB_env *mdb_env); int -relay_is_active(relay_t *relay, struct tm *time_struct); +relay_is_on_schedule(relay_t *relay, struct tm *time_struct); void relay_free(relay_t *relay); diff --git a/include/wiring_debug.h b/include/wiring_debug.h index ab77be0..d46d918 100644 --- a/include/wiring_debug.h +++ b/include/wiring_debug.h @@ -4,12 +4,13 @@ #include #ifdef WIRING_PI_DEBUG - #define wiringPiSetup() LOG_DEBUG("wiringPi wiringPiSetup()\n") - #define wiringPiSetupSys() LOG_DEBUG("wiringPi wiringPiSetupSys()\n") - #define pinMode(x,y) LOG_DEBUG("wiringPi pinMode(%d, %d)\n", x, y) - #define digitalWrite(x,y) LOG_DEBUG("wiringPi digitalWrite(%d, %d)\n", x, y) + #define LOG_WIRING_PI LOG_TRACE + #define wiringPiSetup() LOG_WIRING_PI("wiringPi wiringPiSetup()\n") + #define wiringPiSetupSys() LOG_WIRING_PI("wiringPi wiringPiSetupSys()\n") + #define pinMode(x,y) LOG_WIRING_PI("wiringPi pinMode(%d, %d)\n", x, y) + #define digitalWrite(x,y) LOG_WIRING_PI("wiringPi digitalWrite(%d, %d)\n", x, y) - #define piFaceSetup(x) LOG_DEBUG("wiringPi piFaceSetup(%d)\n", x) + #define piFaceSetup(x) LOG_WIRING_PI("wiringPi piFaceSetup(%d)\n", x) #endif #endif /* CONTROLLER_WIRING_DEBUG_H */ diff --git a/src/handlers/command.c b/src/handlers/command.c index 79fb145..2acb78c 100644 --- a/src/handlers/command.c +++ b/src/handlers/command.c @@ -18,6 +18,22 @@ #include #include +static void +handler_command_pulse(mpack_node_t map, controller_t *controller) +{ + uint8_t relay_num = mpack_node_u8(mpack_node_map_uint(map, COMMAND_MAPPING_RELAY_NUM)); + + relay_t *target_relay = controller->relays[relay_num]; + (void)target_relay; + + uint8_t duration = mpack_node_u8(mpack_node_map_uint(map, COMMAND_MAPPING_PULSE_DURATION)); + if(duration == 0) + { + duration = global_config.relay_configs[relay_num].pulse_duration; + } + target_relay->pulse_timer = duration; +} + static void handler_command_set_name(mpack_node_t map, controller_t *controller) { @@ -72,56 +88,60 @@ void handler_command(struct mg_connection *c, int ev, void *ev_data) { (void)ev_data; - if(ev == MG_EV_RECV) + if(ev != MG_EV_RECV) { - uint32_t payload_length = *((uint32_t*)c->recv_mbuf.buf); - LOG_DEBUG("payload_length %d\n", payload_length); + return; + } + uint32_t payload_length = *((uint32_t*)c->recv_mbuf.buf); + LOG_DEBUG("payload_length %d\n", payload_length); - if(c->recv_mbuf.len < payload_length + sizeof(payload_length)) - { - return; - } + if(c->recv_mbuf.len < payload_length + sizeof(payload_length)) + { + return; + } - char *payload = c->recv_mbuf.buf + sizeof(payload_length); + char *payload = c->recv_mbuf.buf + sizeof(payload_length); - mpack_tree_t tree; - mpack_tree_init_data(&tree, payload, payload_length); - mpack_tree_parse(&tree); - mpack_node_t root = mpack_tree_root(&tree); + mpack_tree_t tree; + mpack_tree_init_data(&tree, payload, payload_length); + mpack_tree_parse(&tree); + mpack_node_t root = mpack_tree_root(&tree); - uint8_t command_code = mpack_node_u8(mpack_node_map_uint(root, COMMAND_MAPPING_CODE)); + uint8_t command_code = mpack_node_u8(mpack_node_map_uint(root, COMMAND_MAPPING_CODE)); - LOG_INFO("received command %d\n", command_code); + LOG_INFO("received command %d\n", command_code); - switch(command_code) - { - case COMMAND_CODE_GET_TIME: - break; - case COMMAND_CODE_GET_ID: - break; - case COMMAND_CODE_SET_NAME: - handler_command_set_name(root, global_controller); - break; - case COMMAND_CODE_GET_NAME: - break; - case COMMAND_CODE_SET_SCHEDULE: - handler_command_set_schedule(root, global_controller); - break; - case COMMAND_CODE_GET_SCHEDULE: - break; - case COMMAND_CODE_SET_RELAY_NAME: - handler_command_set_relay_name(root, global_controller); - break; - case COMMAND_CODE_GET_RELAY_NAME: - break; - default: - LOG_ERROR("received invalid command\n"); - } + switch(command_code) + { + case COMMAND_CODE_GET_TIME: + break; + case COMMAND_CODE_GET_ID: + break; + case COMMAND_CODE_SET_NAME: + handler_command_set_name(root, global_controller); + break; + case COMMAND_CODE_GET_NAME: + break; + case COMMAND_CODE_SET_SCHEDULE: + handler_command_set_schedule(root, global_controller); + break; + case COMMAND_CODE_GET_SCHEDULE: + break; + case COMMAND_CODE_SET_RELAY_NAME: + handler_command_set_relay_name(root, global_controller); + break; + case COMMAND_CODE_GET_RELAY_NAME: + break; + case COMMAND_CODE_PULSE: + handler_command_pulse(root, global_controller); + break; + default: + LOG_ERROR("received invalid command\n"); + } - if(mpack_tree_destroy(&tree) != mpack_ok) - { - LOG_WARN("error when destroying mpack tree\n"); - } + if(mpack_tree_destroy(&tree) != mpack_ok) + { + LOG_WARN("error when destroying mpack tree\n"); } controller_save(global_controller, global_mdb_env); } diff --git a/src/handlers/loop.c b/src/handlers/loop.c index f0b6324..7c6bcc0 100644 --- a/src/handlers/loop.c +++ b/src/handlers/loop.c @@ -21,43 +21,65 @@ handler_loop(struct mg_connection *c_mqtt) char controller_uid[UUID_STR_LEN]; uuid_unparse(global_controller->id, controller_uid); - time_t timestamp = time(NULL); - struct tm *time_struct = localtime(×tamp); - LOG_DEBUG("===== IDLE LOOP START =====\n"); + struct tm time_last, time_now; + time_t timestamp; + + timestamp = time(NULL) - 1; + localtime_r(×tamp, &time_last); + timestamp = time(NULL); + localtime_r(×tamp, &time_now); + LOG_TRACE("===== IDLE LOOP START =====\n"); for(uint_fast8_t i = 0; i < global_controller->relay_count; ++i) { relay_t *relay = global_controller->relays[i]; - int is_active = 0; - if(relay_is_active(relay, time_struct)) + int is_on = 0; + + int is_on_schedule = relay_is_on_schedule(relay, &time_now); + + if(relay->is_on_schedule != is_on_schedule && relay->is_on_schedule != -1) { - LOG_DEBUG("relay %d is active\n", i); - is_active = 1; + relay->pulse_timer = global_config.relay_configs[i].pulse_duration; + } + if(is_on_schedule && !global_config.relay_configs[i].pulse_duration) + { + is_on = 1; + } + if(relay->pulse_timer > 0) + { + is_on = 1; + --relay->pulse_timer; } - if(relay->is_on != is_active) + if(is_on) + { + LOG_DEBUG("relay %d is active\n", i); + } + + if(relay->is_on != is_on) { relay->sent_to_broker = 0; } if(!relay->sent_to_broker && c_mqtt) { sprintf(topic_buf, "controller/%s/relay/%u", controller_uid, i); - sprintf(payload_buf, "%u", is_active); + sprintf(payload_buf, "%u", is_on); mg_mqtt_publish(c_mqtt, topic_buf, 0, MG_MQTT_QOS(0), payload_buf, strlen(payload_buf)); relay->sent_to_broker = 1; } - relay->is_on = is_active; + relay->is_on = is_on; + relay->is_on_schedule = is_on_schedule; if(global_config.relay_configs[i].inverted) { - is_active = !is_active; + is_on = !is_on; } switch(global_config.relay_configs[i].driver) { case RELAY_DRIVER_GPIO: - driver_gpio_set(global_config.relay_configs[i].pin, is_active); + driver_gpio_set(global_config.relay_configs[i].pin, is_on); break; case RELAY_DRIVER_PIFACE: - driver_piface_set(global_config.relay_configs[i].pin, is_active); + driver_piface_set(global_config.relay_configs[i].pin, is_on); break; default: LOG_WARN("relay %d is not using a driver\n", i); diff --git a/src/helpers/load_config.c b/src/helpers/load_config.c index 8c4af97..71c0be0 100644 --- a/src/helpers/load_config.c +++ b/src/helpers/load_config.c @@ -81,7 +81,10 @@ helper_load_config(IniDispatch *disp, void *config_void) config->relay_configs = malloc(sizeof(config_relay_t) * config->relay_count); for(uint8_t i = 0; i < config->relay_count; ++i) { - config->relay_configs[i].driver= RELAY_DRIVER_NONE; + config->relay_configs[i].driver = RELAY_DRIVER_NONE; + config->relay_configs[i].inverted = 0; + config->relay_configs[i].pin = 0; + config->relay_configs[i].pulse_duration = 0; } LOG_TRACE("config relay-count set to %u\n", config->relay_count); return 0; @@ -99,6 +102,11 @@ helper_load_config(IniDispatch *disp, void *config_void) config->relay_configs[i].inverted = atoi(disp->value); return 0; } + if(CONFINI_IS_KEY(relay_section_name, "pulse-duration")) + { + config->relay_configs[i].pulse_duration = atoi(disp->value); + return 0; + } if(CONFINI_IS_KEY(relay_section_name, "driver")) { if(strcasecmp(disp->value, "gpio") == 0) diff --git a/src/main.c b/src/main.c index fc5a249..1c64695 100644 --- a/src/main.c +++ b/src/main.c @@ -140,15 +140,20 @@ main(int argc, const char** argv) /******************** START MAIN LOOP ********************/ - for(;;) + time_t timer = time(NULL); + + for (;;) { - mg_mgr_poll(&mgr, 1000); - if(!global_connection_mqtt) + mg_mgr_poll(&mgr, 200); + if(time(NULL) - timer >= 1) { - LOG_DEBUG("mqtt connection is not open\n"); - connection_mqtt_connect(&mgr); + if(!global_connection_mqtt) + { + connection_mqtt_connect(&mgr); + } + handler_loop(global_connection_mqtt); + timer = time(NULL); } - handler_loop(global_connection_mqtt); } terminate(0); diff --git a/src/models/relay.c b/src/models/relay.c index 6667520..2ca7f34 100644 --- a/src/models/relay.c +++ b/src/models/relay.c @@ -15,6 +15,8 @@ relay_create(uint8_t number) new_relay->name[0] = '\0'; new_relay->is_on = -1; + new_relay->is_on_schedule = -1; + new_relay->pulse_timer = 0; new_relay->sent_to_broker = 0; uuid_t off_id; @@ -37,7 +39,7 @@ relay_set_name(relay_t *relay, const char *name) } int -relay_is_active(relay_t *relay, struct tm *time_struct) +relay_is_on_schedule(relay_t *relay, struct tm *time_struct) { schedule_t *schedule = relay->schedules[helper_get_weekday(time_struct)]; if(schedule->length == 0) diff --git a/src/models/relay_load.c b/src/models/relay_load.c index b6a8471..2c6c214 100644 --- a/src/models/relay_load.c +++ b/src/models/relay_load.c @@ -65,7 +65,11 @@ relay_load(MDB_env *mdb_env, uint8_t num) new_relay = malloc(sizeof(relay_t)); new_relay->number = num; + new_relay->is_on = -1; + new_relay->is_on_schedule = -1; + new_relay->pulse_timer = 0; + new_relay->sent_to_broker = 0; MDB_val value;