|
@ -61,6 +61,69 @@ struct cron_t { |
|
|
|
|
|
|
|
|
static struct cron_t cron_specs[MAX_CRON_SPECS]; |
|
|
static struct cron_t cron_specs[MAX_CRON_SPECS]; |
|
|
|
|
|
|
|
|
|
|
|
static cJSON* |
|
|
|
|
|
serialize_cron_data(struct cron_t cron_spec) { |
|
|
|
|
|
cJSON *result = cJSON_CreateObject(); |
|
|
|
|
|
cJSON_AddNumberToObject(result, "pump_num", cron_spec.pump_num); |
|
|
|
|
|
cJSON_AddNumberToObject(result, "state", cron_spec.state); |
|
|
|
|
|
cJSON_AddNumberToObject(result, "hour", cron_spec.hour); |
|
|
|
|
|
cJSON_AddNumberToObject(result, "minute", cron_spec.minute); |
|
|
|
|
|
cJSON_AddNumberToObject(result, "pump_on_time", cron_spec.pump_on_time); |
|
|
|
|
|
cJSON_AddNumberToObject(result, "last_ran_day", cron_spec.last_ran_day); |
|
|
|
|
|
cJSON_AddNumberToObject(result, "last_ran_hour", cron_spec.last_ran_hour); |
|
|
|
|
|
cJSON_AddNumberToObject(result, "last_ran_minute", cron_spec.last_ran_minute); |
|
|
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static cJSON* |
|
|
|
|
|
serialize_cron_specs(struct cron_t cron_specs[MAX_CRON_SPECS]) { |
|
|
|
|
|
cJSON *cron_spec_arr = cJSON_CreateArray(); |
|
|
|
|
|
for(int i = 0; i < MAX_CRON_SPECS; i++) { |
|
|
|
|
|
cJSON_AddItemToArray(cron_spec_arr, serialize_cron_data(cron_specs[i])); |
|
|
|
|
|
} |
|
|
|
|
|
return cron_spec_arr; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static struct cron_t |
|
|
|
|
|
parse_cron_data(cJSON *json) { |
|
|
|
|
|
|
|
|
|
|
|
cJSON *pump_num; |
|
|
|
|
|
cJSON *state; |
|
|
|
|
|
cJSON *pump_on_time; // time it will be on for
|
|
|
|
|
|
cJSON *hour; // hour to trigger in
|
|
|
|
|
|
cJSON *minute; // minute on the hour to trigger on
|
|
|
|
|
|
|
|
|
|
|
|
struct cron_t cron_spec = {0}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (cJSON_IsObject(json)) { |
|
|
|
|
|
pump_num = cJSON_GetObjectItemCaseSensitive(json, "pump_num"); |
|
|
|
|
|
state = cJSON_GetObjectItemCaseSensitive(json, "state"); |
|
|
|
|
|
pump_on_time = cJSON_GetObjectItemCaseSensitive(json, "pump_on_time"); |
|
|
|
|
|
hour = cJSON_GetObjectItemCaseSensitive(json, "hour"); |
|
|
|
|
|
minute = cJSON_GetObjectItemCaseSensitive(json, "minute"); |
|
|
|
|
|
|
|
|
|
|
|
if (cJSON_IsNumber(pump_num) && |
|
|
|
|
|
cJSON_IsNumber(state) && |
|
|
|
|
|
cJSON_IsNumber(pump_on_time) && |
|
|
|
|
|
cJSON_IsNumber(hour) && |
|
|
|
|
|
cJSON_IsNumber(minute)) { |
|
|
|
|
|
printf("Creating cron spec\n"); |
|
|
|
|
|
cron_spec.pump_num = pump_num->valueint; |
|
|
|
|
|
cron_spec.state = state->valueint; |
|
|
|
|
|
cron_spec.pump_on_time = pump_on_time->valueint; |
|
|
|
|
|
cron_spec.hour = hour->valueint; |
|
|
|
|
|
cron_spec.minute = minute->valueint; |
|
|
|
|
|
cron_spec.last_ran_day = -1; |
|
|
|
|
|
cron_spec.last_ran_hour = -1; |
|
|
|
|
|
cron_spec.last_ran_minute = -1; |
|
|
|
|
|
printf("Parsed: hour = %d, minute = %d\n", cron_spec.hour, cron_spec.minute); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return cron_spec; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
static TickType_t |
|
|
static TickType_t |
|
|
make_delay(int seconds) { |
|
|
make_delay(int seconds) { |
|
|
return (1000*seconds) / portTICK_PERIOD_MS; |
|
|
return (1000*seconds) / portTICK_PERIOD_MS; |
|
@ -172,7 +235,7 @@ pumpTimerCb(TimerHandle_t pumpTimer) { |
|
|
continue; |
|
|
continue; |
|
|
} |
|
|
} |
|
|
printf("running, hour = %d, minute = %d\n", cron_specs[i].hour, cron_specs[i].minute); |
|
|
printf("running, hour = %d, minute = %d\n", cron_specs[i].hour, cron_specs[i].minute); |
|
|
// refactor this bit...
|
|
|
// TODO refactor this bit, what if there are more pumps in the future?
|
|
|
struct event_t message = {0}; |
|
|
struct event_t message = {0}; |
|
|
switch (cron_specs[i].pump_num) { |
|
|
switch (cron_specs[i].pump_num) { |
|
|
case 0: |
|
|
case 0: |
|
@ -195,7 +258,7 @@ pumpTimerCb(TimerHandle_t pumpTimer) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
esp_err_t |
|
|
esp_err_t |
|
|
get_sensor_data(httpd_req_t *req) { |
|
|
get_sensor_data_handler(httpd_req_t *req) { |
|
|
time_t now; |
|
|
time_t now; |
|
|
struct tm timeinfo; |
|
|
struct tm timeinfo; |
|
|
time(&now); |
|
|
time(&now); |
|
@ -253,7 +316,7 @@ pumps_on_handler(httpd_req_t *req) { |
|
|
cJSON *pump_two_time_j = NULL; |
|
|
cJSON *pump_two_time_j = NULL; |
|
|
|
|
|
|
|
|
if (json != NULL) { |
|
|
if (json != NULL) { |
|
|
printf("%s\n", cJSON_Print(json)); |
|
|
//printf("%s\n", cJSON_Print(json));
|
|
|
if (cJSON_IsObject(json)) { |
|
|
if (cJSON_IsObject(json)) { |
|
|
pump_one_time_j = cJSON_GetObjectItemCaseSensitive(json, "pump_1"); |
|
|
pump_one_time_j = cJSON_GetObjectItemCaseSensitive(json, "pump_1"); |
|
|
pump_two_time_j = cJSON_GetObjectItemCaseSensitive(json, "pump_2"); |
|
|
pump_two_time_j = cJSON_GetObjectItemCaseSensitive(json, "pump_2"); |
|
@ -273,14 +336,13 @@ pumps_on_handler(httpd_req_t *req) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* URI handler structure for GET /uri */ |
|
|
/* URI handler structure for GET /uri */ |
|
|
httpd_uri_t uri_get = { |
|
|
httpd_uri_t get_sensor_data = { |
|
|
.uri = "/sensor", |
|
|
.uri = "/sensor", |
|
|
.method = HTTP_GET, |
|
|
.method = HTTP_GET, |
|
|
.handler = get_sensor_data, |
|
|
.handler = get_sensor_data_handler, |
|
|
.user_ctx = NULL |
|
|
.user_ctx = NULL |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* URI handler structure for POST /pumps_on */ |
|
|
/* URI handler structure for POST /pumps_on */ |
|
|
httpd_uri_t pumps_on = { |
|
|
httpd_uri_t pumps_on = { |
|
|
.uri = "/pumps_on", |
|
|
.uri = "/pumps_on", |
|
@ -311,42 +373,13 @@ add_cron_handler(httpd_req_t *req) { |
|
|
|
|
|
|
|
|
cJSON *json = cJSON_ParseWithLength(req_body, HTTPD_RESP_SIZE); |
|
|
cJSON *json = cJSON_ParseWithLength(req_body, HTTPD_RESP_SIZE); |
|
|
|
|
|
|
|
|
cJSON *pump_num; |
|
|
|
|
|
cJSON *state; |
|
|
|
|
|
cJSON *pump_on_time; // time it will be on for
|
|
|
|
|
|
cJSON *hour; // hour to trigger in
|
|
|
|
|
|
cJSON *minute; // minute on the hour to trigger on
|
|
|
|
|
|
|
|
|
|
|
|
struct cron_t cron_spec = {0}; |
|
|
struct cron_t cron_spec = {0}; |
|
|
|
|
|
|
|
|
if (json != NULL) { |
|
|
if (json != NULL) { |
|
|
printf("%s\n", cJSON_Print(json)); |
|
|
//printf("%s\n", cJSON_Print(json));
|
|
|
if (cJSON_IsObject(json)) { |
|
|
cron_spec = parse_cron_data(json); |
|
|
pump_num = cJSON_GetObjectItemCaseSensitive(json, "pump_num"); |
|
|
|
|
|
state = cJSON_GetObjectItemCaseSensitive(json, "state"); |
|
|
|
|
|
pump_on_time = cJSON_GetObjectItemCaseSensitive(json, "pump_on_time"); |
|
|
|
|
|
hour = cJSON_GetObjectItemCaseSensitive(json, "hour"); |
|
|
|
|
|
minute = cJSON_GetObjectItemCaseSensitive(json, "minute"); |
|
|
|
|
|
|
|
|
|
|
|
if (cJSON_IsNumber(pump_num) && |
|
|
|
|
|
cJSON_IsNumber(state) && |
|
|
|
|
|
cJSON_IsNumber(pump_on_time) && |
|
|
|
|
|
cJSON_IsNumber(hour) && |
|
|
|
|
|
cJSON_IsNumber(minute)) { |
|
|
|
|
|
printf("Creating cron spec\n"); |
|
|
|
|
|
cron_spec.pump_num = pump_num->valueint; |
|
|
|
|
|
cron_spec.state = state->valueint; |
|
|
|
|
|
cron_spec.pump_on_time = pump_on_time->valueint; |
|
|
|
|
|
cron_spec.hour = hour->valueint; |
|
|
|
|
|
cron_spec.minute = minute->valueint; |
|
|
|
|
|
cron_spec.last_ran_day = -1; |
|
|
|
|
|
cron_spec.last_ran_hour = -1; |
|
|
|
|
|
cron_spec.last_ran_minute = -1; |
|
|
|
|
|
printf("Parsed: hour = %d, minute = %d\n", cron_spec.hour, cron_spec.minute); |
|
|
|
|
|
xQueueSend(timerEventsHandle, (void*)&cron_spec, (TickType_t)0); |
|
|
xQueueSend(timerEventsHandle, (void*)&cron_spec, (TickType_t)0); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
httpd_resp_send(req, resp, HTTPD_RESP_USE_STRLEN); |
|
|
httpd_resp_send(req, resp, HTTPD_RESP_USE_STRLEN); |
|
|
|
|
|
|
|
@ -362,6 +395,38 @@ httpd_uri_t add_cron = { |
|
|
.user_ctx = NULL |
|
|
.user_ctx = NULL |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
esp_err_t |
|
|
|
|
|
get_cron_data_handler(httpd_req_t *req) { |
|
|
|
|
|
// TODO, figure out how large it actually is
|
|
|
|
|
|
char resp[HTTPD_RESP_SIZE*10] = {0}; |
|
|
|
|
|
|
|
|
|
|
|
cJSON *resp_object_j = cJSON_CreateObject(); |
|
|
|
|
|
|
|
|
|
|
|
if (resp_object_j != NULL) { cJSON_Delete(resp_object_j); } |
|
|
|
|
|
|
|
|
|
|
|
httpd_resp_set_type(req, "application/json"); |
|
|
|
|
|
httpd_resp_set_status(req, HTTPD_200); |
|
|
|
|
|
|
|
|
|
|
|
cJSON *cron_specs_j = serialize_cron_specs(cron_specs); |
|
|
|
|
|
|
|
|
|
|
|
// TODO, figure out how large it actually is
|
|
|
|
|
|
cJSON_PrintPreallocated(cron_specs_j, resp, HTTPD_RESP_SIZE*10, false); |
|
|
|
|
|
|
|
|
|
|
|
if (cron_specs_j != NULL) { cJSON_Delete(cron_specs_j); } |
|
|
|
|
|
|
|
|
|
|
|
httpd_resp_send(req, resp, HTTPD_RESP_USE_STRLEN); |
|
|
|
|
|
|
|
|
|
|
|
return ESP_OK; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
httpd_uri_t get_cron_data = { |
|
|
|
|
|
.uri = "/cron_data", |
|
|
|
|
|
.method = HTTP_GET, |
|
|
|
|
|
.handler = get_cron_data_handler, |
|
|
|
|
|
.user_ctx = NULL |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
/* Function for starting the webserver */ |
|
|
/* Function for starting the webserver */ |
|
|
httpd_handle_t |
|
|
httpd_handle_t |
|
|
start_webserver(void) { |
|
|
start_webserver(void) { |
|
@ -374,9 +439,10 @@ start_webserver(void) { |
|
|
/* Start the httpd server */ |
|
|
/* Start the httpd server */ |
|
|
if (httpd_start(&server, &config) == ESP_OK) { |
|
|
if (httpd_start(&server, &config) == ESP_OK) { |
|
|
/* Register URI handlers */ |
|
|
/* Register URI handlers */ |
|
|
httpd_register_uri_handler(server, &uri_get); |
|
|
httpd_register_uri_handler(server, &get_sensor_data); |
|
|
httpd_register_uri_handler(server, &pumps_on); |
|
|
httpd_register_uri_handler(server, &pumps_on); |
|
|
httpd_register_uri_handler(server, &add_cron); |
|
|
httpd_register_uri_handler(server, &add_cron); |
|
|
|
|
|
httpd_register_uri_handler(server, &get_cron_data); |
|
|
} |
|
|
} |
|
|
/* If server failed to start, handle will be NULL */ |
|
|
/* If server failed to start, handle will be NULL */ |
|
|
ESP_LOGI(TAG, "webserver started"); |
|
|
ESP_LOGI(TAG, "webserver started"); |
|
@ -628,48 +694,6 @@ ledc_init(int gpio_num, |
|
|
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel)); |
|
|
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void user_task (void *pvParameters) |
|
|
|
|
|
{ |
|
|
|
|
|
float temperature; |
|
|
|
|
|
float humidity; |
|
|
|
|
|
|
|
|
|
|
|
TickType_t last_wakeup = xTaskGetTickCount(); |
|
|
|
|
|
|
|
|
|
|
|
while (1) |
|
|
|
|
|
{ |
|
|
|
|
|
// perform one measurement and do something with the results
|
|
|
|
|
|
if (sht3x_measure (sensor, &temperature, &humidity)) |
|
|
|
|
|
printf("%.3f SHT3x Sensor: %.2f °C, %.2f %%\n", |
|
|
|
|
|
(double)sdk_system_get_time()*1e-3, temperature, humidity); |
|
|
|
|
|
|
|
|
|
|
|
// wait until 5 seconds are over
|
|
|
|
|
|
vTaskDelayUntil(&last_wakeup, 5000 / portTICK_PERIOD_MS); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* -- main program ------------------------------------------------- */ |
|
|
|
|
|
|
|
|
|
|
|
void user_init(void) |
|
|
|
|
|
{ |
|
|
|
|
|
// Set UART Parameter.
|
|
|
|
|
|
uart_set_baud(0, 115200); |
|
|
|
|
|
// Give the UART some time to settle
|
|
|
|
|
|
vTaskDelay(1); |
|
|
|
|
|
|
|
|
|
|
|
// Init I2C bus interfaces at which SHT3x sensors are connected
|
|
|
|
|
|
// (different busses are possible).
|
|
|
|
|
|
i2c_init(I2C_BUS, I2C_SCL_PIN, I2C_SDA_PIN, I2C_FREQ_100K); |
|
|
|
|
|
|
|
|
|
|
|
// Create the sensors, multiple sensors are possible.
|
|
|
|
|
|
if ((sensor = sht3x_init_sensor (I2C_BUS, SHT3x_ADDR_1))) |
|
|
|
|
|
{ |
|
|
|
|
|
// Create a user task that uses the sensors.
|
|
|
|
|
|
xTaskCreate(user_task, "user_task", TASK_STACK_SIZE, NULL, 2, 0); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// That's it.
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
void |
|
|
app_main(void) { |
|
|
app_main(void) { |
|
|
++boot_count; |
|
|
++boot_count; |
|
|