Comments and cleanup
authorjweigele <jweigele@local>
Mon, 11 Mar 2024 16:17:29 +0000 (09:17 -0700)
committerjweigele <jweigele@local>
Mon, 11 Mar 2024 16:17:29 +0000 (09:17 -0700)
aqi/CMakeLists.txt
aqi/main/aqi.c
aqi/main/aqi.h

index 7a069db4670525ac1d3dc4bad8973483a86ede1b..79fb737f10e24d11029966527ac0bc7af9048865 100644 (file)
@@ -1,11 +1,13 @@
 # The following lines of boilerplate have to be in your project's CMakeLists
 # in this exact order for cmake to work correctly
 cmake_minimum_required(VERSION 3.16)
+
 if (CONFIG_WIFI_ENABLED)
 set(EXTRA_COMPONENT_DIRS components/esp32-wifi-manager
     )
 else()
 set(EXTRA_COMPONENT_DIRS )
 endif()
+
 include($ENV{IDF_PATH}/tools/cmake/project.cmake)
 project(aqi)
index 148f0689f14f9c8b08347bc66284c79b381ab858..35a88a1b995852b4354a89f65ad5df62c5941d25 100644 (file)
@@ -1,17 +1,3 @@
-/*
- * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
- *
- * SPDX-License-Identifier: CC0-1.0
- *
- * Zigbee HA_color_dimmable_light Example
- *
- * This example code is in the Public Domain (or CC0 licensed, at your option.)
- *
- * Unless required by applicable law or agreed to in writing, this
- * software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, either express or implied.
- */
-
 #include "nvs_flash.h"
 #include "esp_log.h"
 #include "freertos/FreeRTOS.h"
@@ -30,6 +16,7 @@ typedef struct aqi_data_s {
 
 #ifdef CONFIG_PWM_ENABLED
 #include "driver/ledc.h"
+// everything uses the same timer, just with diff duty cycles
 #define LEDC_TIMER              LEDC_TIMER_0
 #define LEDC_MODE               LEDC_LOW_SPEED_MODE
 #define R1_CHANNEL LEDC_CHANNEL_0
@@ -38,10 +25,13 @@ typedef struct aqi_data_s {
 #define G2_CHANNEL LEDC_CHANNEL_3
 #define B1_CHANNEL LEDC_CHANNEL_4
 #define B2_CHANNEL LEDC_CHANNEL_5
-#define LEDC_FREQUENCY          (1250) // Frequency in Hertz. Set frequency at 20 kHz
+// initial PWM frequency in hz
+#define LEDC_FREQUENCY          (1250)
 
+// scales the brightness to match so that the total duty % is roughly == the target
 double pwm_target = CONFIG_PWM_TARGET_PERCENT/100.0;
 
+// this is a buffer with length that we'll reuse to ship PWM values between tasks
 typedef struct pwm_data_s {
     uint8_t msg[1024];
     int len;
@@ -49,8 +39,9 @@ typedef struct pwm_data_s {
 #endif
 
 
+// overall report data structure, contains all the variables we'll parse and send to mqtt
 typedef struct report_data_s {
-#ifdef CONFIG_UART_ENABLED    
+#ifdef CONFIG_UART_ENABLED
   uint16_t pm10;
   uint16_t pm25;
   float aqi;
@@ -66,20 +57,23 @@ typedef struct report_data_s {
   uint32_t uptime;
   SemaphoreHandle_t mutex;
 } report_data_t;
+// end report data
+
 
 static temperature_sensor_handle_t temp_handle;
 static QueueHandle_t event_queue;
 static QueueHandle_t send_queue;
 static QueueHandle_t version_queue;
 
+// holds version information
 static esp_app_desc_t app_desc;
+
+// mac address and ext address identification
 static char mac_string[12 + 1];
 static char ext_string[16 + 1];
 
 #if defined(CONFIG_MOTION_FIRST_ENABLED) || defined(CONFIG_MOTION_SECOND_ENABLED)
-static uint32_t squelch_time = 0;
 static QueueHandle_t motion_queue;
-static QueueHandle_t off_queue;
 static QueueHandle_t check_queue;
 
 static int prev_motion[2] = {0, 0};
@@ -100,8 +94,6 @@ static int tempbuffer[TEMPBUFFERSIZE];
 static int tempbufferindex = 0;
 static OW ow;
 
-//= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
 #endif
 
 #ifdef CONFIG_LED_ENABLED
@@ -134,10 +126,12 @@ static uint8_t ot_mac[6];
 static uint8_t otExt[8];
 #endif
 #endif
+#ifdef CONFIG_UART_ENABLED
 static aqi_data_t cur_pm = {
     .pm10 = 0,
     .pm25 = 0
 };
+#endif
 
 
 static report_data_t report_data;
@@ -159,11 +153,14 @@ void handleNetifStateChanged(uint32_t aFlags, void *aContext)
 
        switch (changedRole)
        {
+       // we've attached to the openthread network, either becoming a leader, router, or child
        case OT_DEVICE_ROLE_LEADER:
        case OT_DEVICE_ROLE_ROUTER:
        case OT_DEVICE_ROLE_CHILD:
            ESP_LOGI(TAG, "valid role, setting netif_connected");
            netif_connected = true;
+           // we may have transitioned from e.g. child -> router so it's quite possible
+           // our connection is already up, don't reconnect if we already have once
            if (mqtt_connected == false ){
                ESP_LOGI(TAG, "CONNECTING to mqtt here!");
                init_connected = true;
@@ -172,6 +169,7 @@ void handleNetifStateChanged(uint32_t aFlags, void *aContext)
            }
            break;
 
+       // detached from openthread, set everything off so we don't keep trying to send
        case OT_DEVICE_ROLE_DETACHED:
        case OT_DEVICE_ROLE_DISABLED:
            netif_connected = false;
@@ -182,6 +180,7 @@ void handleNetifStateChanged(uint32_t aFlags, void *aContext)
     }
 }
 
+// helper functions for parsing hex from menuconfig
 int hex_digit_to_int(char hex) {
     if ('A' <= hex && hex <= 'F') {
         return 10 + hex - 'A'; 
@@ -215,25 +214,17 @@ size_t hex_string_to_binary(const char *hex_string, uint8_t *buf, size_t buf_siz
 }
 
 
-/**
- * Override default network settings, such as panid, so the devices can join a
- network
- */
+// take all openthread information set in menuconfig and configure the interface appropriately
+// this is pretty much boilerplate variable setting
 void setNetworkConfiguration(otInstance *instance)
 {
     otOperationalDataset dataset;
 
     memset(&dataset, 0, sizeof(otOperationalDataset));
 
-
-
     uint16_t network_name_len = strlen(CONFIG_OPENTHREAD_NETWORK_NAME);
     assert(network_name_len <= OT_NETWORK_NAME_MAX_SIZE);
 
-    /*if (otDatasetCreateNewNetwork(instance, &dataset) != OT_ERROR_NONE) {
-        ESP_LOGE(TAG, "Failed to create OpenThread network dataset.");
-        abort();
-    }*/
     dataset.mChannel = CONFIG_OPENTHREAD_NETWORK_CHANNEL;
     dataset.mComponents.mIsChannelPresent = true;
     dataset.mPanId = CONFIG_OPENTHREAD_NETWORK_PANID;
@@ -259,6 +250,7 @@ void setNetworkConfiguration(otInstance *instance)
     }
     dataset.mComponents.mIsPskcPresent = true;
     otIp6Address prefix;
+    // uses helper functions above to parse the binary from hex string given in menuconfig
     otIp6AddressFromString(CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX, &prefix);
     memcpy(dataset.mMeshLocalPrefix.m8, prefix.mFields.m8, sizeof(prefix.mFields.m8));
     dataset.mComponents.mIsMeshLocalPrefixPresent = true;
@@ -299,14 +291,12 @@ static void create_config_network(otInstance *instance)
         abort();
     }
 
-    /* Register Thread state change handler */
+    // register state change handler (attached to network, became router, etc.)
     otSetStateChangedCallback(instance, handleNetifStateChanged, instance);
 
-    //ESP_ERROR_CHECK(esp_openthread_auto_start(NULL));
-
-    /* Override default network credentials */
     setNetworkConfiguration(instance);
 
+    // save the ext address for later usage
     memcpy(otExt, otLinkGetExtendedAddress(instance), 8);
 
     sprintf(ext_string, "%02x%02x%02x%02x%02x%02x%02x%02x",
@@ -318,6 +308,8 @@ static void create_config_network(otInstance *instance)
     /* Start the Thread stack (CLI cmd > thread start) */
     otThreadSetEnabled(instance, true);
 }
+
+// setup openthread netif and attach to it 
 static esp_netif_t *init_openthread_netif(const esp_openthread_platform_config_t *config)
 {
     esp_netif_config_t cfg = ESP_NETIF_DEFAULT_OPENTHREAD();
@@ -372,7 +364,7 @@ static void ot_task_worker(void *aContext)
     threadInstance = esp_openthread_get_instance();
     create_config_network(threadInstance);
 
-    //esp_err_t err_netif = esp_netif_get_mac(openthread_netif, ot_mac);
+    // save mac addy for later usage
     esp_err_t err_netif = esp_base_mac_addr_get(ot_mac);
     sprintf(mac_string, "%02x%02x%02x%02x%02x%02x", 
             ot_mac[0], ot_mac[1], ot_mac[2], ot_mac[3], ot_mac[4], ot_mac[5]);
@@ -382,6 +374,8 @@ static void ot_task_worker(void *aContext)
     esp_openthread_lock_release();
 
     esp_err_t err = esp_openthread_launch_mainloop();
+
+    // should not reach here in normal operation
     ESP_LOGE(TAG, "Error somewhere in openthread loop %s.", esp_err_to_name(err));
 
     // Clean up
@@ -431,7 +425,7 @@ void erase_data_hook(void){
 #endif
         ESP_LOGW(TAG, "would erase flash here!!!");
         ESP_ERROR_CHECK(nvs_flash_erase_partition(CONFIG_NVS_OT_PARTITION));
-#ifdef CONFIG_WIFI_ENABLED        
+#ifdef CONFIG_WIFI_ENABLED
         // we don't want to erase a factory partition since it also contains the apps
         if (strcmp(CONFIG_NVS_WIFI_PARTITION, "factory") != 0){
             ESP_LOGW(TAG, "erasing wifi partition at %s", CONFIG_NVS_WIFI_PARTITION);
@@ -513,18 +507,14 @@ void init_tempbuffer(){
     }
 }
 
+// fetches temperature from any attached ds18b20 devices
+// returns as value * 100 (so that we can get 2 decimal places by later /100
+// without dealing with float nonsense now)
 static short get_temp(){
     if (ow_reset (&ow)) {
-        //puts ("slave(s) present");
-
-        // scan bus for slaves
+        // scan bus for devices
         uint64_t romcode[MAXDEVS];
         int num_devs = ow_romsearch (&ow, romcode, MAXDEVS, OW_SEARCH_ROM);
-        /*printf("Found %d devices\n", num_devs);      
-        for (int i = 0; i < num_devs; i += 1) {
-            printf("\t%d: 0x%llx\n", i, romcode[i]);
-        }
-        putchar ('\n');*/
 
         // get temperature readings
         if (num_devs > 0) {
@@ -613,6 +603,7 @@ void init_pmbuffer(){
     }
 }
 
+// hardcoded given the aqi device we expect to find
 void init_uart(void) {
     const uart_config_t uart_config = {
         .baud_rate = 9600,
@@ -628,6 +619,9 @@ void init_uart(void) {
     uart_set_pin(UART_NUM_1, UART_TX_GPIO, UART_RX_GPIO, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
 }
 
+// this task sends identifying information over mqtt, sleeps an hour, then repeats
+//
+// if it doesn't go out for some reason it's just stored in a queue until it is fetched
 static void version_task(void* discard){
     // give 5 seconds before starting, just to allow all network vars to be populated
     vTaskDelay( pdMS_TO_TICKS(5000) );
@@ -644,6 +638,7 @@ static void version_task(void* discard){
         cJSON_AddStringToObject(root, "location", CONFIG_LOCATION);
         char *mqtt_string = cJSON_Print(root);
         xQueueSend(version_queue, &mqtt_string, portMAX_DELAY);
+        // reclaim memory on json object here, assumed that other side handles string
         cJSON_Delete(root);
 
         // wait an hour, then send again
@@ -652,6 +647,7 @@ static void version_task(void* discard){
 }
 
 
+// handles the basic reporting of both version and sensor information over mqtt
 static void send_task(void* discard){
 
     char* mqtt_string = ""; //NULL;
@@ -666,11 +662,11 @@ static void send_task(void* discard){
                 free(mqtt_string);
             }                
         }
-        // receive an event we need to deal with from elsewhere, right now just reconnect related
+        // sensor information queue -> send on mqtt 
         if (xQueueReceive(send_queue, &mqtt_string, portMAX_DELAY )){
             last_sent = true;
-            //ESP_LOGW(TAG, "received a string in send loop! %s", mqtt_string);
             ESP_LOGI(TAG, "sending mqtt_string:\n%s",mqtt_string);
+            // need to be both connected to a network and also connected to mqtt to send successfully
             if (netif_connected == true && mqtt_connected == true){
                 int msg_id = esp_mqtt_client_publish(mqtt_client, "esp32/sensor_info", mqtt_string, 0, 1, 0);
                 ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
@@ -680,6 +676,8 @@ static void send_task(void* discard){
             free(mqtt_string);
         }
         // and loop around immediately if we just sent something, otherwise sleep a bit
+        //
+        // helps when the queue has backed up faster than our delay loop accounts for
         if (last_sent == true) {
             last_sent = false;
         } else {
@@ -710,10 +708,13 @@ static void send_report_motion(bool motion){
 }
 #endif // CONFIG_MOTION_ENABLED
 
-static void send_report_wifi(report_data_t report_data){
+// this parses all currently enabled sensor data and puts it in a json object,
+// converts to string, and dumps it on the mqtt queue for sending on sensor_info
+static void send_report_summary(report_data_t report_data){
+    // enforce access while making changes
     xSemaphoreTake(report_data.mutex, portMAX_DELAY);
 
-    ESP_LOGI(TAG, "send_report_wifi was called!");
+    ESP_LOGI(TAG, "send_report_summary was called!");
     cJSON *root;
     root = cJSON_CreateObject();
     cJSON_AddStringToObject(root, "location", CONFIG_LOCATION);
@@ -722,6 +723,7 @@ static void send_report_wifi(report_data_t report_data){
     cJSON_AddNumberToObject(root, "pm25", ((float)report_data.pm25/100));
     cJSON_AddNumberToObject(root, "aqi", report_data.aqi);
 #endif    
+    // both set as we go through the normal loop, "nice to have" information on device operation
     cJSON_AddNumberToObject(root, "uptime", report_data.uptime);
     cJSON_AddNumberToObject(root, "internal", report_data.internal_temperature);
 #ifdef CONFIG_TEMP_ENABLED
@@ -737,15 +739,19 @@ static void send_report_wifi(report_data_t report_data){
 #endif
 
     char *mqtt_string = cJSON_Print(root);
+    // drop on the send queue
     xQueueSend(send_queue, &mqtt_string, portMAX_DELAY);
+    // free memory from json object, assume other end of the queue frees the string
     cJSON_Delete(root);    
 
+    // done making modifications
     xSemaphoreGive(report_data.mutex);
 
 }
 
 #endif // wifi or ot enabled
 
+// defined by AQI device, simply adhering to that spec here
 bool verify_checksum(uint8_t* data){
     int total = 0;
 
@@ -758,6 +764,7 @@ bool verify_checksum(uint8_t* data){
     return data[30] == check_high && data[31] == check_low;
 }
 
+// again, this protocol is defined by aqi device
 aqi_data_t get_average_pm25(uint8_t* data, int data_size){
     int pm10_total = 0;
     int pm25_total = 0;
@@ -807,6 +814,7 @@ aqi_data_t get_average_pm25(uint8_t* data, int data_size){
 
 #ifdef CONFIG_PWM_ENABLED
 
+// correct brightness levels so that colors remain roughly in proportion
 double gamma_correct(double led_value){
     // just took this from the pico python script
     // believe it came from a website formula
@@ -819,6 +827,7 @@ double gamma_correct(double led_value){
     return retval;
 }
 
+// not called in normal operation, useful for debugging PWM though
 int change_pwm_freq(int freq){
     int duty_res = ledc_find_suitable_duty_resolution(32000000, freq);    
     ESP_LOGI(TAG, "changing freq to %d", freq);
@@ -853,19 +862,18 @@ static void pwm_task(void* discard){
     int duty_res = ledc_find_suitable_duty_resolution(32000000, LEDC_FREQUENCY);
     ESP_LOGI(TAG, "max duty res for PWM is %d", duty_res);
 
-    // initialize PWM hardware
-    // Prepare and then apply the LEDC PWM timer configuration
+    // initialize PWM timer 
     ledc_timer_config_t ledc_timer = {
         .speed_mode       = LEDC_MODE,
         .timer_num        = LEDC_TIMER,
         .duty_resolution  = duty_res,
-        .freq_hz          = LEDC_FREQUENCY,  // Set output frequency at 5 kHz
+        .freq_hz          = LEDC_FREQUENCY,
         .clk_cfg          = LEDC_SLOW_CLK_XTAL 
     };
     ESP_LOGI(TAG, "configuring ledc timer");
     ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
 
-    // Prepare and then apply the LEDC PWM channel configuration
+    // Prepare and then apply the base LEDC PWM channel configuration
     ledc_channel_config_t ledc_channel = {
         .speed_mode     = LEDC_MODE,
         .channel        = LEDC_CHANNEL_0,
@@ -877,6 +885,7 @@ static void pwm_task(void* discard){
     };
 
 
+    // for all channels, if GPIO pin is defined (!= -1) set params appropriately
     if (CONFIG_PWM_R1_GPIO != -1){
         ledc_channel.channel = R1_CHANNEL;
         ledc_channel.gpio_num = CONFIG_PWM_R1_GPIO;
@@ -922,8 +931,7 @@ static void pwm_task(void* discard){
 
 
 
-    //create a queue to handle gpio event from isr
-    // 1kb, should be enough for parsing?
+    //create a queue to handle pwm events, assuming 10 is enough to process from mqtt before it backs up too much 
     pwm_queue = xQueueCreate(10, sizeof(pwm_data_t));
     pwm_data_t recv;
     ESP_LOGI(TAG, "waiting for pwm events");
@@ -942,9 +950,13 @@ static void pwm_task(void* discard){
     int blue_duty_int;
     double total;
     for(;;) {
+        // just a JSON string hot off of mqtt, we need to parse the values from it
         if(xQueueReceive(pwm_queue, &recv, portMAX_DELAY)) {
             ESP_LOGI(TAG, "received PWM data string %s len %d", recv.msg, recv.len);
             current_pwm = cJSON_ParseWithLength(&recv.msg, recv.len);
+            // quick note: we don't free anything here because we're simply reusing the same pwm_data_t buffer to send ourselves
+            // data over and over. this might get messy if getting multiple values in a short period or something, but so far no issues
+            // with concurrency.
             if (cJSON_IsObject(current_pwm)){
                 // used to adjust scaling with pwm_target
                 total = 0.0;
@@ -952,12 +964,14 @@ static void pwm_task(void* discard){
                 red_duty_float = 0;
                 green_duty_float = 0;
                 blue_duty_float = 0;
+                // not changed in normal operation, used for debugging PWM brightness
                 target_json = cJSON_GetObjectItemCaseSensitive(current_pwm, "target");
                 if (cJSON_IsNumber(target_json)){
                     ESP_LOGI(TAG, "parsed target float %f", target_json->valuedouble);
                     pwm_target = target_json->valuedouble;
                 }
 
+                // not changed in normal operation, used for changing PWM frequency on the fly
                 freq_json = cJSON_GetObjectItemCaseSensitive(current_pwm, "freq");
                 if (cJSON_IsNumber(freq_json)){
                     ESP_LOGI(TAG, "parsed target int %d", freq_json->valueint);
@@ -966,18 +980,23 @@ static void pwm_task(void* discard){
 
                 
 
+                // red duty cycle as a float
                 red_json = cJSON_GetObjectItemCaseSensitive(current_pwm, "red");
                 if (cJSON_IsNumber(red_json)){
                     ESP_LOGI(TAG, "parsed red float %f", red_json->valuedouble);
                     red_duty_float = red_json->valuedouble;
                     total += red_duty_float;
                 }
+
+                // green duty cycle as a float
                 green_json = cJSON_GetObjectItemCaseSensitive(current_pwm, "green");
                 if (cJSON_IsNumber(green_json)){
                     ESP_LOGI(TAG, "parsed green float %f", green_json->valuedouble);
                     green_duty_float = green_json->valuedouble;
                     total += green_duty_float;
                 }
+
+                // blue duty cycle as a float
                 blue_json = cJSON_GetObjectItemCaseSensitive(current_pwm, "blue");
                 if (cJSON_IsNumber(blue_json)){
                     ESP_LOGI(TAG, "parsed blue float %f", blue_json->valuedouble);
@@ -986,8 +1005,6 @@ static void pwm_task(void* discard){
                 }
 
 
-
-
                 // gamma correct and scale if needed (i.e. if any color is active) 
                 if (total > 0){
                     red_duty_float = gamma_correct(red_duty_float*(pwm_target/total));
@@ -995,11 +1012,14 @@ static void pwm_task(void* discard){
                     blue_duty_float = gamma_correct(blue_duty_float*(pwm_target/total));
                 }
 
+                // scale the float to the appropriate duty resolution we're using locally
                 red_duty_int = (int)(red_duty_float*(pow(2,duty_res)));
                 green_duty_int = (int)(green_duty_float*(pow(2,duty_res)));
                 blue_duty_int = (int)(blue_duty_float*(pow(2,duty_res)));
 
 
+                // set all active PWM channels appropriately
+
                 ESP_LOGI(TAG, "red duty float calculated as %02f, int %d", red_duty_float, red_duty_int);
 
                 if (CONFIG_PWM_R1_GPIO != -1){
@@ -1049,6 +1069,7 @@ static void pwm_task(void* discard){
                 ESP_LOGE(TAG, "failed to parse json successfully!");
             }
 
+            // free json object
             cJSON_Delete(current_pwm);
         }
     }
@@ -1058,15 +1079,20 @@ static void pwm_task(void* discard){
 #endif
 
 #if defined(CONFIG_MOTION_FIRST_ENABLED) || defined(CONFIG_MOTION_SECOND_ENABLED)
+// this is the interrupt handler so it needs to be _FAST_ and not blocking
+// we just make it dump a thing on the queue and return, do the processing elsewhere
 static void IRAM_ATTR gpio_isr_handler(void* arg)
 {
     uint32_t gpio_num = (uint32_t) arg;
     xQueueSendFromISR(motion_queue, &gpio_num, NULL);
 }
 
+// this rechecks to verify that our GPIO has been set for at least some time (to rule out blips)
+// if not enabled, just a pass-through "true" 
 static void check_motion(void* discard){
     uint32_t io_num;
     for(;;) {
+        // block until something changes
         if(xQueueReceive(check_queue, &io_num, portMAX_DELAY)) {
 #ifdef CONFIG_MOTION_RECHECK
             // check after this much time
@@ -1092,15 +1118,21 @@ static void check_motion(void* discard){
 
 }
 
+// we do all our motion GPIO interrupt processing in this loop,
+// to the point where we've enqueued motion events for mqtt to send
 static void motion_task(void* discard){
+    //create queues to handle motion events 
+    motion_queue = xQueueCreate(100, sizeof(uint32_t));
+    check_queue = xQueueCreate(100, sizeof(uint32_t));
 
     //zero-initialize the config structure.
     gpio_config_t io_conf = {};
 
-    //interrupt of rising edge
+    // GPIO interrupt on either rising or falling edge
     io_conf.intr_type = GPIO_INTR_ANYEDGE;
-    //bit mask of the pins, use GPIO4/5 here
+    // bit mask of the pins, set to nothing at the start
     io_conf.pin_bit_mask = 0;
+    // now, bring in any enabled pins (<< # according to esp32 mask definitions)
 #ifdef CONFIG_MOTION_FIRST_ENABLED
     io_conf.pin_bit_mask |= (1ULL << CONFIG_MOTION_FIRST_PIN);
     ESP_LOGI(TAG, "first motion bitmask now %"PRIu64, io_conf.pin_bit_mask);
@@ -1112,36 +1144,30 @@ static void motion_task(void* discard){
 
     //set as input mode
     io_conf.mode = GPIO_MODE_INPUT;
-    //enable pull-down mode
+    // enable pull-down mode (we are using "big" PIR sensors which require pull-down)
     io_conf.pull_down_en = 1;
     io_conf.pull_up_en = 0;
+    // hysteresis separates the thresholds for high/low so we don't have a lot of toggling in between
     io_conf.hys_ctrl_mode = GPIO_HYS_SOFT_ENABLE;
     gpio_config(&io_conf);
 
-    //change gpio interrupt type for one pin
-#ifdef CONFIG_MOTION_FIRST_ENABLED    
+    //change gpio interrupt type for enabled pins
+#ifdef CONFIG_MOTION_FIRST_ENABLED
     ESP_ERROR_CHECK(gpio_set_intr_type(CONFIG_MOTION_FIRST_PIN, GPIO_INTR_ANYEDGE));
-#endif    
-#ifdef CONFIG_MOTION_SECOND_ENABLED    
+#endif
+#ifdef CONFIG_MOTION_SECOND_ENABLED
     ESP_ERROR_CHECK(gpio_set_intr_type(CONFIG_MOTION_SECOND_PIN, GPIO_INTR_ANYEDGE));
 #endif
 
 
-    //create a queue to handle gpio event from isr
-    motion_queue = xQueueCreate(100, sizeof(uint32_t));
-    off_queue = xQueueCreate(100, sizeof(uint32_t));
-    check_queue = xQueueCreate(100, sizeof(uint32_t));
-    
-    
-
     //install gpio isr service
     ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_LOWMED));
     //hook isr handler for specific gpio pin
-#ifdef CONFIG_MOTION_FIRST_ENABLED    
+#ifdef CONFIG_MOTION_FIRST_ENABLED
     esp_err_t firstret = gpio_isr_handler_add(CONFIG_MOTION_FIRST_PIN, gpio_isr_handler, (void*) CONFIG_MOTION_FIRST_PIN);
     ESP_LOGE(TAG, "return for isr handler add (first) is %s", esp_err_to_name(firstret));
 #endif
-#ifdef CONFIG_MOTION_SECOND_ENABLED    
+#ifdef CONFIG_MOTION_SECOND_ENABLED
     esp_err_t secondret = gpio_isr_handler_add(CONFIG_MOTION_SECOND_PIN, gpio_isr_handler, (void*) CONFIG_MOTION_SECOND_PIN);
     ESP_LOGE(TAG, "return for isr handler add (second) is %s", esp_err_to_name(secondret));    
 #endif
@@ -1151,10 +1177,16 @@ static void motion_task(void* discard){
     uint32_t io_num;
     ESP_LOGI(TAG, "waiting for motion events");
     for(;;) {
+        // block forever on interrupt GPIO events
         if(xQueueReceive(motion_queue, &io_num, portMAX_DELAY)) {
+            // if we got here, something changed, fetch the current level of the given pin
             int pin_value = gpio_get_level(io_num);
             ESP_LOGI(TAG, "GPIO[%"PRIu32"] intr, val: %d\n", io_num, pin_value);
-            uint32_t squelch_uptime;
+            // prev_motion is just an attempt to filter out "events" where the pin value doesn't change
+            //
+            // sending on queue with portMAX_DELAY is a choice - if we've somehow filled things up with quick toggles this WILL
+            // block, but probably better than dropping events on the floor?? really don't want to be in that situation
+            // to begin with
             switch (io_num) {
                 case CONFIG_MOTION_FIRST_PIN:
                     prev_motion[0] = motion_pins[0];
@@ -1191,15 +1223,17 @@ short temp_avg = 0;
     init_temp();
 #endif
 
+#ifdef CONFIG_UART_ENABLED
     uint16_t set_pm10;
     uint16_t set_pm25;
+    float cur_aqi_pm25 = 0.0;
+    float cur_aqi_pm10 = 0.0;
+    int length = 0;
+    uint8_t* data = (uint8_t*) malloc(RX_BUF_SIZE+1);
+#endif    
     int64_t cur_uptime = 0;
     int64_t next_sleep_uptime = 0;
     int64_t remaining_time = 0;
-    uint8_t* data = (uint8_t*) malloc(RX_BUF_SIZE+1);
-    int length = 0;
-    float cur_aqi_pm25 = 0.0;
-    float cur_aqi_pm10 = 0.0;
 #if defined(CONFIG_WIFI_ENABLED) || defined(CONFIG_OT_ENABLED)
     esp_mqtt_client_handle_t queue_item;
 #endif
@@ -1292,8 +1326,8 @@ short temp_avg = 0;
 
 
 #if defined(CONFIG_WIFI_ENABLED) || defined(CONFIG_OT_ENABLED)
-        // one BIG report for wifi
-        send_report_wifi(report_data);
+        // one BIG report
+        send_report_summary(report_data);
 #endif
             
         cur_uptime = esp_timer_get_time();
@@ -1343,7 +1377,9 @@ short temp_avg = 0;
 
     }
     // only called if we break out of the loop somehow (right now, never)
+#ifdef CONFIG_UART_ENABLED
     free(data);
+#endif
 }
 
 #if defined(CONFIG_WIFI_ENABLED) || defined(CONFIG_OT_ENABLED)
@@ -1415,12 +1451,15 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
         ESP_LOGI(TAG, "MQTT_EVENT_DATA");
         printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
 #ifdef CONFIG_PWM_ENABLED
+        // the only topic we're subscribed to is for PWM so send the buffer along for processing I guess
         pwm_data_t sendpwm;
-        pwm_data_t* sendpwm_ptr = &sendpwm; //malloc(sizeof(pwm_data_t));
+        pwm_data_t* sendpwm_ptr = &sendpwm;
+        // clear buffer
         memset(sendpwm_ptr, 0, 1024);
+        // copy from mqtt
         memcpy(sendpwm_ptr->msg, event->data, event->data_len);
         sendpwm_ptr->len = event->data_len;
-        printf("sendpwm msg: %s\nlen: %d\n", sendpwm_ptr->msg, sendpwm_ptr->len);
+        // dump on the queue for further processing (parse JSON and set PWM hardware)
         xQueueSend(pwm_queue, sendpwm_ptr, portMAX_DELAY);
 #endif
 
@@ -1450,18 +1489,44 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
     }
 }
 
+#ifdef CONFIG_OT_ENABLED
+void print_addresses(){
+
+    esp_openthread_lock_acquire(portMAX_DELAY);
+
+    const otNetifAddress *address;
+    char string[OT_IP6_ADDRESS_STRING_SIZE];
+
+    address = otIp6GetUnicastAddresses(threadInstance);
+
+    while (address){
+        otIp6AddressToString(&address->mAddress, string, sizeof(string));
+
+        ESP_LOGI(TAG, "IP6 addr: %s", string);
+        address = address->mNext;
+    }
+    esp_openthread_lock_release();
+
+}
+#endif
+
 void init_mqtt(){
     ESP_LOGI(TAG, "attempting to connect to MQTT");
     mqtt_client = NULL;
     char mqtt_id[64];
 #ifdef CONFIG_OT_ENABLED
+    // print ipv6 addresses if we're using openthread
+    print_addresses();
+    // includes the ext address in the id
     sprintf(mqtt_id, "ESP32_%02x%02x%02x%02x%02x%02x_%02x%02x%02x%02x%02x%02x%02x%02x",
             ot_mac[0], ot_mac[1], ot_mac[2], ot_mac[3], ot_mac[4], ot_mac[5],
             otExt[0], otExt[1], otExt[2], otExt[3], otExt[4], otExt[5], otExt[6], otExt[7]);
 //    sprintf(mqtt_id, "ESP32_%012x", ot_mac[0]);
 #else
+    // just uses something generic until I figure out the api for more
     sprintf(mqtt_id, "ESP32_wifi");
 #endif
+    // verification is assumed to be disabled in menuconfig if needed (which I do lol)
     esp_mqtt_client_config_t mqtt_cfg = {
         .broker = {
             .address.uri  = CONFIG_BROKER_URL,
@@ -1486,9 +1551,7 @@ void init_mqtt(){
 
 #ifdef CONFIG_WIFI_ENABLED
 // wifi connection nuked callbak
-// wifi connection ok callback
 void wifi_connection_bad(void* pvParameter){
-    //ip_event_got_ip_t* param = (ip_event_got_ip_t*)pvParameter;
     ESP_LOGW(TAG, "wifi connection got dropped! just gonna set stuff down and hope for the best");
     netif_connected = false;
     init_connected = false;
@@ -1508,7 +1571,6 @@ void wifi_connection_ok(void* pvParameter){
 
     ESP_LOGI(TAG, "I have a connection and my IP is %s!", str_ip);
 
-    //xQueueSend(tx_task_queue, &tx_action, portMAX_DELAY);
     init_mqtt();
 }
 
@@ -1531,24 +1593,15 @@ void app_main(void)
 
     ESP_LOGI(TAG, "Built from commit %s", app_desc.version);
 
-/*#ifdef CONFIG_LIGHT_SLEEP_ENABLED
-    ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON));
-#endif*/
-
     ESP_ERROR_CHECK(nvs_flash_init());
 
     // temp monitoring
     temp_handle = NULL;
+    // this gives us the smallest error of all ranges per esp32 docs (<1C)
     temperature_sensor_config_t temp_sensor = TEMPERATURE_SENSOR_CONFIG_DEFAULT(-10, 80);
-  /*  {
-        .range_min = 20,
-        .range_max = 100,
-        .temperature_sensor_clk_src_t = 
-    };*/
     ESP_ERROR_CHECK(temperature_sensor_install(&temp_sensor, &temp_handle));    // 
     ESP_ERROR_CHECK(temperature_sensor_enable(temp_handle));
 
-
     // Create mutex before starting tasks
     report_data.mutex = xSemaphoreCreateMutex();
 #if defined(CONFIG_WIFI_ENABLED) || defined(CONFIG_OT_ENABLED)
@@ -1557,10 +1610,6 @@ void app_main(void)
     //indicator light
 #ifdef CONFIG_INDICATOR_ENABLED
     light_driver_init(LIGHT_DEFAULT_OFF);
-#endif
-
-
-#ifdef CONFIG_INDICATOR_ENABLED
     adjust_color_lookup_brightness(AQI_INDICATOR_BRIGHTNESS);
 #endif
 #ifdef CONFIG_UART_ENABLED
@@ -1573,8 +1622,6 @@ void app_main(void)
 
 #ifdef CONFIG_LED_ENABLED
     init_led();
-    //i2c_init();
-    //runit();
 #endif
 
 #ifdef CONFIG_PWM_ENABLED
@@ -1582,6 +1629,8 @@ void app_main(void)
     xTaskCreate(pwm_task, "pwm_task", 4096, NULL, 2, NULL);
 #endif
 #ifdef CONFIG_OT_ENABLED
+    // not sure we really need 4, it was 3 before and seemed to work
+    // but doesn't hurt really
     esp_vfs_eventfd_config_t eventfd_config = {
         .max_fds = 4,
     };
@@ -1594,8 +1643,7 @@ void app_main(void)
     xTaskCreate(ot_task_worker, "ot_power_save_main", 4096, NULL, 5, NULL);
 #endif
 #ifdef CONFIG_WIFI_ENABLED
-//    ESP_ERROR_CHECK(esp_tls_set_global_ca_store(ca_cert, strlen((char*)ca_cert)));
-    /* start the wifi manager */
+    // start the wifi manager
     wifi_manager_start();
 
     wifi_manager_set_callback(WM_EVENT_STA_GOT_IP, &wifi_connection_ok);    
index 9998152a3e57dcb119d71cae8866a9ced56191b4..207030905e4d4d52e1ce11513485552554aac2c5 100644 (file)
@@ -29,6 +29,7 @@
 #include "openthread/thread.h"
 #include "openthread/thread_ftd.h"
 
+#include "openthread/ip6.h"
 
 #define CONFIG_OPENTHREAD_NETWORK_POLLPERIOD_TIME 3000
 // okay this isn't really defined here, you need to find it in the openthread source :(