add: macro endpoint for execution
This commit is contained in:
		
							parent
							
								
									01ffb1d58d
								
							
						
					
					
						commit
						d3fd48b35a
					
				
					 9 changed files with 110 additions and 26 deletions
				
			
		| 
						 | 
				
			
			@ -18,4 +18,7 @@ api_v1_macros_STR_PUT(struct mg_connection *nc, struct http_message *hm, endpoin
 | 
			
		|||
void
 | 
			
		||||
api_v1_macros_STR_DELETE(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
api_v1_macros_STR_execute_PUT(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response);
 | 
			
		||||
 | 
			
		||||
#endif /* CORE_ENDPOINTS_API_V1_MACROS_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,6 @@
 | 
			
		|||
#include <cJSON.h>
 | 
			
		||||
 | 
			
		||||
#include <constants.h>
 | 
			
		||||
#include <models/period.h>
 | 
			
		||||
#include <models/macro_action.h>
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
| 
						 | 
				
			
			@ -43,4 +42,7 @@ macro_get_by_uid(uuid_t uid);
 | 
			
		|||
macro_t**
 | 
			
		||||
macro_get_all();
 | 
			
		||||
 | 
			
		||||
int*
 | 
			
		||||
macro_get_target_relay_ids(int macro_id);
 | 
			
		||||
 | 
			
		||||
#endif /* CORE_MACRO_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,9 @@ macro_action_delete_for_macro(int macro_id);
 | 
			
		|||
macro_action_t**
 | 
			
		||||
macro_action_get_for_macro(int macro_id);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
macro_action_execute(macro_action_t *macro_action);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
macro_action_free_list(macro_action_t **macro_actions);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -86,11 +86,11 @@ api_v1_macros_STR_PUT(struct mg_connection *nc, struct http_message *hm, endpoin
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    macro_action_delete_for_macro(macro->id);
 | 
			
		||||
 | 
			
		||||
    cJSON *json_actions = cJSON_GetObjectItemCaseSensitive(json, "actions");
 | 
			
		||||
    if(cJSON_IsArray(json_actions))
 | 
			
		||||
    {
 | 
			
		||||
        macro_action_delete_for_macro(macro->id);
 | 
			
		||||
 | 
			
		||||
        cJSON *json_action;
 | 
			
		||||
        cJSON_ArrayForEach(json_action, json_actions)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										64
									
								
								src/endpoints/api_v1_macros_STR_execute.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/endpoints/api_v1_macros_STR_execute.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,64 @@
 | 
			
		|||
#include <cJSON.h>
 | 
			
		||||
#include <macros.h>
 | 
			
		||||
#include <constants.h>
 | 
			
		||||
#include <endpoints/api_v1_macros.h>
 | 
			
		||||
#include <logger.h>
 | 
			
		||||
#include <command.h>
 | 
			
		||||
#include <models/macro_action.h>
 | 
			
		||||
#include <models/macro.h>
 | 
			
		||||
#include <models/relay.h>
 | 
			
		||||
#include <models/tag.h>
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
api_v1_macros_STR_execute_PUT(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response)
 | 
			
		||||
{
 | 
			
		||||
    (void)hm;
 | 
			
		||||
    (void)nc;
 | 
			
		||||
 | 
			
		||||
    uuid_t target_uid;
 | 
			
		||||
    if(uuid_parse(args[0].value.v_str, target_uid))
 | 
			
		||||
    {
 | 
			
		||||
        M_RESPONSE_400_NO_VALID_ID(response);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    macro_t* macro = macro_get_by_uid(target_uid);
 | 
			
		||||
 | 
			
		||||
    if(!macro)
 | 
			
		||||
    {
 | 
			
		||||
        M_RESPONSE_404_NO_MACRO_FOUND_FOR_ID(response);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    macro_action_t** macro_actions = macro_action_get_for_macro(macro->id);
 | 
			
		||||
 | 
			
		||||
    database_transaction_lock lock;
 | 
			
		||||
    database_transaction_begin(&lock);
 | 
			
		||||
 | 
			
		||||
    for(int i = 0; macro_actions[i] != NULL; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        macro_action_execute(macro_actions[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    database_transaction_commit(&lock);
 | 
			
		||||
 | 
			
		||||
    int *target_relay_ids = macro_get_target_relay_ids(macro->id);
 | 
			
		||||
    for(int i = 0; target_relay_ids[i] != 0; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        relay_t *target_relay = relay_get_by_id(target_relay_ids[i]);
 | 
			
		||||
        if(!target_relay)
 | 
			
		||||
        {
 | 
			
		||||
            LOGGER_ERR("failed to load target relay from database\n");
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        command_relay_schedules_set(target_relay);
 | 
			
		||||
 | 
			
		||||
        relay_free(target_relay);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    free(target_relay_ids);
 | 
			
		||||
    macro_action_free_list(macro_actions);
 | 
			
		||||
    macro_free(macro);
 | 
			
		||||
 | 
			
		||||
    M_RESPONSE_TEXT_STATIC(LOGGER_DEBUG, response, 200, "macro got executed");
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -95,7 +95,7 @@ junction_relay_schedule_get_relay_ids_with_schedule(int schedule_id)
 | 
			
		|||
{
 | 
			
		||||
    sqlite3_stmt *stmt;
 | 
			
		||||
 | 
			
		||||
    sqlite3_prepare_v2(global_database, "SELECT relay_id FROM junction_relay_schedule WHERE schedule_id=?1;", -1, &stmt, NULL);
 | 
			
		||||
    sqlite3_prepare_v2(global_database, "SELECT DISTINCT relay_id FROM junction_relay_schedule WHERE schedule_id=?1;", -1, &stmt, NULL);
 | 
			
		||||
    sqlite3_bind_int(stmt, 1, schedule_id);
 | 
			
		||||
 | 
			
		||||
    return database_helper_get_ids(stmt);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -160,28 +160,6 @@ macro_remove(macro_t *macro)
 | 
			
		|||
    return rc != SQLITE_DONE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
macro_is_protected(macro_t *macro)
 | 
			
		||||
{
 | 
			
		||||
    uuid_t tmp_uuid;
 | 
			
		||||
 | 
			
		||||
    memset(tmp_uuid, 0, sizeof(uuid_t));
 | 
			
		||||
    memcpy(tmp_uuid, "off", 3);
 | 
			
		||||
    if(uuid_compare(macro->uid, tmp_uuid) == 0)
 | 
			
		||||
    {
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    memset(tmp_uuid, 0, sizeof(uuid_t));
 | 
			
		||||
    memcpy(tmp_uuid, "on", 2);
 | 
			
		||||
    if(uuid_compare(macro->uid, tmp_uuid) == 0)
 | 
			
		||||
    {
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
macro_free(macro_t *macro)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -339,3 +317,14 @@ macro_get_all()
 | 
			
		|||
    return macro_db_select(stmt);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int*
 | 
			
		||||
macro_get_target_relay_ids(int macro_id)
 | 
			
		||||
{
 | 
			
		||||
    sqlite3_stmt *stmt;
 | 
			
		||||
 | 
			
		||||
    sqlite3_prepare_v2(global_database, "SELECT DISTINCT relay_id FROM macro_actions WHERE macro_id=?1;", -1, &stmt, NULL);
 | 
			
		||||
    sqlite3_bind_int(stmt, 1, macro_id);
 | 
			
		||||
 | 
			
		||||
    return database_helper_get_ids(stmt);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -123,6 +123,28 @@ macro_action_get_for_macro(int macro_id)
 | 
			
		|||
    return macro_action_db_select(stmt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
macro_action_execute(macro_action_t *macro_action)
 | 
			
		||||
{
 | 
			
		||||
    schedule_t *schedule = schedule_get_by_id(macro_action->schedule_id);
 | 
			
		||||
    if(!schedule)
 | 
			
		||||
    {
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    relay_t *relay = relay_get_by_id(macro_action->relay_id);
 | 
			
		||||
    if(!relay)
 | 
			
		||||
    {
 | 
			
		||||
        free(schedule);
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    schedule_free(relay->schedules[macro_action->weekday]);
 | 
			
		||||
    relay->schedules[macro_action->weekday] = schedule;
 | 
			
		||||
 | 
			
		||||
    return relay_save(relay);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
macro_action_free_list(macro_action_t **macro_actions)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -96,6 +96,7 @@ router_init()
 | 
			
		|||
    router_register_endpoint("/api/v1/macros/{str}", HTTP_METHOD_GET, api_v1_macros_STR_GET);
 | 
			
		||||
    router_register_endpoint("/api/v1/macros/{str}", HTTP_METHOD_PUT, api_v1_macros_STR_PUT);
 | 
			
		||||
    router_register_endpoint("/api/v1/macros/{str}", HTTP_METHOD_DELETE, api_v1_macros_STR_DELETE);
 | 
			
		||||
    router_register_endpoint("/api/v1/macros/{str}/execute", HTTP_METHOD_PUT, api_v1_macros_STR_execute_PUT);
 | 
			
		||||
 | 
			
		||||
    router_register_endpoint("/api/v1/ws/relays", HTTP_METHOD_WEBSOCKET, api_v1_ws_relays);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue