-/*
- * 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"
#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
#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;
#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;
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};
static int tempbufferindex = 0;
static OW ow;
-//= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
#endif
#ifdef CONFIG_LED_ENABLED
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;
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;
}
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;
}
}
+// helper functions for parsing hex from menuconfig
int hex_digit_to_int(char hex) {
if ('A' <= hex && hex <= 'F') {
return 10 + hex - 'A';
}
-/**
- * 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;
}
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;
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",
/* 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();
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]);
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
#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);
}
}
+// 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) {
}
}
+// hardcoded given the aqi device we expect to find
void init_uart(void) {
const uart_config_t uart_config = {
.baud_rate = 9600,
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) );
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
}
+// handles the basic reporting of both version and sensor information over mqtt
static void send_task(void* discard){
char* mqtt_string = ""; //NULL;
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);
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 {
}
#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);
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
#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;
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;
#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
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);
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,
};
+ // 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;
- //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");
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;
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);
+ // 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);
}
-
-
// 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));
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){
ESP_LOGE(TAG, "failed to parse json successfully!");
}
+ // free json object
cJSON_Delete(current_pwm);
}
}
#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
}
+// 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);
//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
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];
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
#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();
}
// 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)
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
}
}
+#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,
#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;
ESP_LOGI(TAG, "I have a connection and my IP is %s!", str_ip);
- //xQueueSend(tx_task_queue, &tx_action, portMAX_DELAY);
init_mqtt();
}
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)
//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
#ifdef CONFIG_LED_ENABLED
init_led();
- //i2c_init();
- //runit();
#endif
#ifdef CONFIG_PWM_ENABLED
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,
};
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);