├── .gitignore ├── .gitmodules ├── FinalProject1.jpg ├── FinalProject2.jpg ├── LICENSE ├── MultiSensor_AC_bb.jpg ├── README.md ├── examples ├── multiple_sensors │ ├── Makefile │ └── multiple_sensors.c └── multiple_sensors_ac │ ├── Makefile │ ├── ac_commands.c │ ├── ac_commands.h │ ├── main.c │ ├── ota-api.c │ └── ota-api.h ├── lib ├── adv_button │ ├── Makefile │ ├── adv_button.c │ ├── adv_button.h │ ├── component.mk │ └── main.c └── led_codes │ ├── component.mk │ ├── led_codes.c │ └── led_codes.h └── wifi.h.sample /.gitignore: -------------------------------------------------------------------------------- 1 | /wifi.h 2 | /examples/*/wifi.h 3 | /examples/*/build 4 | /examples/*/firmware 5 | .DS_Store 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "components/esp-ir"] 2 | path = components/esp-ir 3 | url = https://github.com/maximkulkin/esp-ir 4 | [submodule "components/common/wolfssl"] 5 | path = components/common/wolfssl 6 | url = https://github.com/maximkulkin/esp-wolfssl 7 | [submodule "components/esp-8266/WS2812FX"] 8 | path = components/esp-8266/WS2812FX 9 | url = https://github.com/pcsaito/WS2812FX-rtos 10 | [submodule "components/esp-8266/wifi_config"] 11 | path = components/esp-8266/wifi_config 12 | url = https://github.com/maximkulkin/esp-wifi-config 13 | [submodule "components/esp-8266/cJSON"] 14 | path = components/esp-8266/cJSON 15 | url = https://github.com/maximkulkin/esp-cjson 16 | [submodule "components/UDPlogger"] 17 | path = components/UDPlogger 18 | url = https://github.com/HomeACcessoryKid/UDPlogger 19 | [submodule "components/common/homekit"] 20 | path = components/common/homekit 21 | url = https://github.com/maximkulkin/esp-homekit 22 | [submodule "components/esp-led-status"] 23 | path = components/esp-led-status 24 | url = https://github.com/maximkulkin/esp-led-status 25 | -------------------------------------------------------------------------------- /FinalProject1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peros550/esp-homekit-multiple-sensors/bfc1d97275cc41aa5ab18f900bd2c9e66691c790/FinalProject1.jpg -------------------------------------------------------------------------------- /FinalProject2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peros550/esp-homekit-multiple-sensors/bfc1d97275cc41aa5ab18f900bd2c9e66691c790/FinalProject2.jpg -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Maxim Kulkin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MultiSensor_AC_bb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peros550/esp-homekit-multiple-sensors/bfc1d97275cc41aa5ab18f900bd2c9e66691c790/MultiSensor_AC_bb.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # esp-homekit-multiple-sensors 2 | 3 | This repository is based on the code and the examples provided by Maxim Kulkin. 4 | 5 | https://github.com/maximkulkin/esp-homekit-demo 6 | 7 | Detailed instructions on how to use the code found here can be found on Maxim's [wiki](https://github.com/maximkulkin/esp-homekit-demo/wiki/Build-instructions). 8 | 9 | 10 | In this repo there are two new examples: 11 | 12 | a) multiple_sensors 13 | 14 | b) multiple_sensors_ac 15 | 16 | The first example creates a multi-sensor device in Homekit. It includes a Temperature, Humidity, Light and Motion sensor. The second example, is like the first example but it also adds a thermostat accessory. With thermostat accessory you can control an A/C through IR commands. Any new features will be added to the second example. 17 | 18 | The following hardware can be used: 19 | ![alt text](https://github.com/peros550/esp-homekit-multiple-sensors/blob/master/MultiSensor_AC_bb.jpg?raw=true) 20 | 21 | 22 | You may also use the following link to create a ready made shield for wemos D1 mini. 23 | https://easyeda.com/peros550/wemos-d1-dht22-ir-pir-lm393_copy 24 | 25 | Final project would look like this: 26 | ![alt text](https://github.com/peros550/esp-homekit-multiple-sensors/blob/master/FinalProject1.jpg?raw=true) 27 | ![alt text](https://github.com/peros550/esp-homekit-multiple-sensors/blob/master/FinalProject2.jpg?raw=true) 28 | 29 | 30 | Supported Features: 31 | *Dynamic Wifi configuration by creating a soft AP 32 | 33 | *OTA updates 34 | 35 | *ThingSpeak integration to save temperature & humidity values 36 | 37 | *Webserver to configure special features (expiremental) 38 | 39 | # IR commands 40 | If you are going to use IR, you need to supply your own set of RAW commands for your A/C in this [file](https://github.com/peros550/esp-homekit-multiple-sensors/blob/master/examples/multiple_sensors_ac/ac_commands.c). You may use Maxim's [esp-ir](https://github.com/maximkulkin/esp-ir) library to capture one by one each command for all modes (heating/cooling/auto/off). For AUTO mode there is only one command, I personally set there my A/C's FAN mode. 41 | 42 | # BOM 43 | * 1 wemos d1 mini 44 | * 1 DHT22 sensor 45 | * 1 AM312 PIR sensor 46 | * 1 LDR (i.e. a GL5528) 47 | * 3 Resistors (18 Ohm, 2.2K, 10K) 48 | * 1 NPN transistor 2N2222 49 | * 1 IR LED (Had good results with TSAL6200) 50 | * 1 push button (is used for homekit reset) 51 | 52 | -------------------------------------------------------------------------------- /examples/multiple_sensors/Makefile: -------------------------------------------------------------------------------- 1 | PROGRAM = multiple_sensors 2 | 3 | EXTRA_COMPONENTS = \ 4 | extras/onewire \ 5 | extras/ds18b20 \ 6 | extras/dht \ 7 | extras/http-parser \ 8 | extras/dhcpserver \ 9 | $(abspath ../../lib/adv_button) \ 10 | $(abspath ../../lib/led_codes)\ 11 | $(abspath ../../components/esp-8266/wifi_config) \ 12 | $(abspath ../../components/common/wolfssl) \ 13 | $(abspath ../../components/esp-8266/cJSON) \ 14 | $(abspath ../../components/common/homekit) 15 | 16 | FLASH_SIZE = 8 17 | FLASH_MODE = dout 18 | FLASH_SPEED = 40 19 | 20 | HOMEKIT_SPI_FLASH_BASE_ADDR = 0x8c000 21 | HOMEKIT_MAX_CLIENTS = 16 22 | HOMEKIT_SMALL = 0 23 | 24 | EXTRA_CFLAGS += -I../.. -DHOMEKIT_SHORT_APPLE_UUIDS 25 | EXTRA_CFLAGS += -DHOMEKIT_OVERCLOCK_PAIR_VERIFY 26 | EXTRA_CFLAGS += -DHOMEKIT_OVERCLOCK_PAIR_SETUP 27 | 28 | ## DEBUG 29 | #EXTRA_CFLAGS += -DHOMEKIT_DEBUG=1 30 | 31 | 32 | include $(SDK_PATH)/common.mk 33 | 34 | monitor: 35 | $(FILTEROUTPUT) --port $(ESPPORT) --baud 115200 --elf $(PROGRAM_OUT) 36 | -------------------------------------------------------------------------------- /examples/multiple_sensors/multiple_sensors.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include "wifi_config.h" 13 | 14 | #include 15 | #include 16 | 17 | 18 | //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 19 | const int led_gpio = 2; // Pin D4 20 | const int button_gpio = 4; //Pin (D2) 21 | const int motion_sensor_gpio = 16; // Wemos D1 mini pin: D0 22 | const int SENSOR_PIN = 5; //DHT sensor on pin D1 23 | const int IR_PIN = 14 ; // Wemos D1 mini pin: D5. 24 | //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 25 | 26 | bool led_value = false; //This is to keep track of the LED status. 27 | volatile float old_humidity_value = 0.0, old_temperature_value = 0.0 , old_light_value =0.0, old_move_value = 0.0; 28 | ETSTimer extra_func_timer ; 29 | 30 | homekit_characteristic_t temperature = HOMEKIT_CHARACTERISTIC_(CURRENT_TEMPERATURE, 0); 31 | homekit_characteristic_t humidity = HOMEKIT_CHARACTERISTIC_(CURRENT_RELATIVE_HUMIDITY, 0); 32 | //Additional for Motion 33 | homekit_characteristic_t motion_detected = HOMEKIT_CHARACTERISTIC_(MOTION_DETECTED, 0); 34 | homekit_characteristic_t currentAmbientLightLevel = HOMEKIT_CHARACTERISTIC_(CURRENT_AMBIENT_LIGHT_LEVEL, 0,.min_value = (float[]) {0},); 35 | homekit_characteristic_t name = HOMEKIT_CHARACTERISTIC_(NAME, "Sonoff Switch"); 36 | 37 | 38 | 39 | 40 | void identify_task(void *_args) { 41 | vTaskDelete(NULL); 42 | } 43 | 44 | void identify(homekit_value_t _value) { 45 | printf("identify\n"); 46 | xTaskCreate(identify_task, "identify", 128, NULL, 2, NULL); 47 | } 48 | 49 | void led_write(bool on) { 50 | gpio_write(led_gpio, on ? 0 : 1); 51 | led_value = on; //Keep track of the status 52 | } 53 | 54 | 55 | void reset_configuration_task() { 56 | //Flash the LED first before we start the reset 57 | for (int i=0; i<3; i++) { 58 | led_write(true); 59 | vTaskDelay(100 / portTICK_PERIOD_MS); 60 | led_write(false); 61 | vTaskDelay(100 / portTICK_PERIOD_MS); 62 | } 63 | 64 | printf("Resetting Wifi Config\n"); 65 | wifi_config_reset(); 66 | vTaskDelay(1000 / portTICK_PERIOD_MS); 67 | printf("Resetting HomeKit Config\n"); 68 | homekit_server_reset(); 69 | vTaskDelay(1000 / portTICK_PERIOD_MS); 70 | printf("Restarting\n"); 71 | sdk_system_restart(); 72 | vTaskDelete(NULL); 73 | } 74 | 75 | void reset_configuration() { 76 | printf("Resetting Sonoff configuration\n"); 77 | xTaskCreate(reset_configuration_task, "Reset configuration", 256, NULL, 2, NULL); 78 | } 79 | 80 | 81 | void sensor_worker() { 82 | //Temperature measurement 83 | float humidity_value, temperature_value; 84 | bool get_temp = false; 85 | 86 | get_temp = dht_read_float_data(DHT_TYPE_DHT22, SENSOR_PIN, &humidity_value, &temperature_value); 87 | if (get_temp) { 88 | // printf("RC >>> Sensor: temperature %g, humidity %g\n", temperature_value, humidity_value); 89 | 90 | if (temperature_value != old_temperature_value) { 91 | old_temperature_value = temperature_value; 92 | 93 | // current_temperature.value = HOMEKIT_FLOAT(temperature_value); //Update AC current temp 94 | // homekit_characteristic_notify(¤t_temperature, HOMEKIT_FLOAT(temperature_value)); 95 | 96 | temperature.value.float_value = temperature_value; 97 | homekit_characteristic_notify(&temperature, HOMEKIT_FLOAT(temperature_value)); 98 | } 99 | 100 | 101 | if (humidity_value != old_humidity_value) { 102 | old_humidity_value = humidity_value; 103 | humidity.value.float_value =humidity_value; 104 | //current_humidity.value = HOMEKIT_FLOAT(humidity_value); 105 | //homekit_characteristic_notify(¤t_humidity, current_humidity.value); 106 | homekit_characteristic_notify(&humidity, HOMEKIT_FLOAT(humidity_value)); 107 | } 108 | 109 | 110 | 111 | } else 112 | { 113 | printf("RC !!! ERROR Sensor\n"); 114 | //led_code(LED_GPIO, SENSOR_ERROR); 115 | 116 | } 117 | 118 | //printf("Checking Light\n"); 119 | //Light measurement 120 | float light_value; 121 | light_value = sdk_system_adc_read(); 122 | if (light_value != old_light_value) 123 | { 124 | old_light_value = light_value; 125 | currentAmbientLightLevel.value.float_value = (1024 - light_value); 126 | homekit_characteristic_notify(¤tAmbientLightLevel, HOMEKIT_FLOAT((1024 - light_value))); 127 | } 128 | 129 | uint32_t freeheap = xPortGetFreeHeapSize(); 130 | //printf("xPortGetFreeHeapSize = %d bytes\n", freeheap); 131 | 132 | 133 | } 134 | 135 | 136 | 137 | void movement_detected_fn(const uint8_t gpio) { 138 | printf("Movement detected\n"); 139 | old_move_value = true; 140 | motion_detected.value = HOMEKIT_BOOL(old_move_value); 141 | led_write(old_move_value); 142 | homekit_characteristic_notify(&motion_detected, HOMEKIT_BOOL(old_move_value)); 143 | 144 | } 145 | 146 | void movement_not_detected_fn(const uint8_t gpio) { 147 | printf("Movement not detected\n"); 148 | 149 | old_move_value = false; 150 | motion_detected.value = HOMEKIT_BOOL(old_move_value); 151 | led_write(old_move_value); 152 | homekit_characteristic_notify(&motion_detected, HOMEKIT_BOOL(old_move_value)); 153 | } 154 | 155 | 156 | void button_callback_single(const uint8_t gpio) { 157 | 158 | printf("Toggling relay\n"); 159 | led_write(!led_value); //A Single press will just toggle the LED. This was left for testing purposes. 160 | //The following code is left commented in case we want to implement a single button for something else in homekit. 161 | //switch_on.value.bool_value = !switch_on.value.bool_value; 162 | //relay_write(switch_on.value.bool_value); 163 | //homekit_characteristic_notify(&switch_on, switch_on.value); 164 | 165 | //http_get_task(1); 166 | // xTaskCreate(http_get_task, "http", 256, NULL, 1, NULL); 167 | //vTaskDelay(100 / portTICK_PERIOD_MS); 168 | 169 | } 170 | 171 | 172 | void button_hold_callback(const uint8_t gpio) { 173 | printf("Resetting Wifi\n"); 174 | reset_configuration(); 175 | 176 | } 177 | 178 | 179 | void temperature_sensor_identify(homekit_value_t _value) { 180 | printf("Temperature sensor identify\n"); 181 | } 182 | 183 | void light_sensor_identify(homekit_value_t _value) { 184 | printf("Light sensor identify\n"); 185 | } 186 | 187 | 188 | 189 | 190 | 191 | homekit_accessory_t *accessories[] = { 192 | HOMEKIT_ACCESSORY(.id=1, .category=homekit_accessory_category_thermostat, .services=(homekit_service_t*[]) { 193 | HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t*[]) { 194 | &name, 195 | HOMEKIT_CHARACTERISTIC(MANUFACTURER, "YP"), 196 | HOMEKIT_CHARACTERISTIC(SERIAL_NUMBER, "0012345"), 197 | HOMEKIT_CHARACTERISTIC(MODEL, "MultipleSensors"), 198 | HOMEKIT_CHARACTERISTIC(FIRMWARE_REVISION, "0.1"), 199 | HOMEKIT_CHARACTERISTIC(IDENTIFY, temperature_sensor_identify), 200 | NULL 201 | }), 202 | HOMEKIT_SERVICE(TEMPERATURE_SENSOR, .primary=true, .characteristics=(homekit_characteristic_t*[]) { 203 | HOMEKIT_CHARACTERISTIC(NAME, "Temperature Sensor"), 204 | &temperature, 205 | NULL 206 | }), 207 | HOMEKIT_SERVICE(HUMIDITY_SENSOR, .characteristics=(homekit_characteristic_t*[]) { 208 | HOMEKIT_CHARACTERISTIC(NAME, "Humidity Sensor"), 209 | &humidity, 210 | NULL 211 | }), 212 | NULL 213 | }), 214 | HOMEKIT_ACCESSORY(.id=2, .category=homekit_accessory_category_switch, .services=(homekit_service_t*[]){ 215 | HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t*[]){ 216 | HOMEKIT_CHARACTERISTIC(NAME, "Motion Sensor"), 217 | HOMEKIT_CHARACTERISTIC(MANUFACTURER, "YP"), 218 | HOMEKIT_CHARACTERISTIC(SERIAL_NUMBER, "0012346"), 219 | HOMEKIT_CHARACTERISTIC(MODEL, "MotionSensor"), 220 | HOMEKIT_CHARACTERISTIC(FIRMWARE_REVISION, "0.1"), 221 | HOMEKIT_CHARACTERISTIC(IDENTIFY, identify), 222 | NULL 223 | }), 224 | HOMEKIT_SERVICE(MOTION_SENSOR, .primary=true, .characteristics=(homekit_characteristic_t*[]){ 225 | HOMEKIT_CHARACTERISTIC(NAME, "Motion Sensor"), 226 | &motion_detected, 227 | NULL 228 | }), 229 | NULL 230 | }), 231 | HOMEKIT_ACCESSORY(.id=3, .category=homekit_accessory_category_sensor, .services=(homekit_service_t*[]){ 232 | HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t*[]){ 233 | HOMEKIT_CHARACTERISTIC(NAME, "Light Sensor"), 234 | HOMEKIT_CHARACTERISTIC(MANUFACTURER, "YP"), 235 | HOMEKIT_CHARACTERISTIC(SERIAL_NUMBER, "0012347"), 236 | HOMEKIT_CHARACTERISTIC(MODEL, "LightSensor"), 237 | HOMEKIT_CHARACTERISTIC(FIRMWARE_REVISION, "0.1"), 238 | HOMEKIT_CHARACTERISTIC(IDENTIFY, light_sensor_identify), 239 | NULL 240 | }), 241 | HOMEKIT_SERVICE(LIGHT_SENSOR, .primary=true, .characteristics=(homekit_characteristic_t*[]){ 242 | HOMEKIT_CHARACTERISTIC(NAME, "Light Sensor"), 243 | ¤tAmbientLightLevel, 244 | NULL 245 | }), 246 | NULL 247 | }), 248 | NULL 249 | }; 250 | 251 | 252 | 253 | void create_accessory_name() { 254 | uint8_t macaddr[6]; 255 | sdk_wifi_get_macaddr(STATION_IF, macaddr); 256 | 257 | int name_len = snprintf(NULL, 0, "Homekit Sensor-%02X%02X%02X", 258 | macaddr[3], macaddr[4], macaddr[5]); 259 | char *name_value = malloc(name_len+1); 260 | snprintf(name_value, name_len+1, "Homekit Sensor-%02X%02X%02X", 261 | macaddr[3], macaddr[4], macaddr[5]); 262 | 263 | name.value = HOMEKIT_STRING(name_value); 264 | } 265 | 266 | homekit_server_config_t config = { 267 | .accessories = accessories, 268 | .password = "111-11-111" 269 | }; 270 | 271 | // void on_wifi_ready() { 272 | // homekit_server_init(&config); 273 | 274 | // sdk_os_timer_setfn(&extra_func_timer, sensor_worker, NULL); 275 | // sdk_os_timer_disarm(&extra_func_timer); 276 | // sdk_os_timer_arm(&extra_func_timer, 10000, 1); 277 | // } 278 | 279 | void on_wifi_event(wifi_config_event_t event) { 280 | if (event == WIFI_CONFIG_CONNECTED) { 281 | printf("Connected to WiFi\n"); 282 | 283 | homekit_server_init(&config); 284 | 285 | sdk_os_timer_setfn(&extra_func_timer, sensor_worker, NULL); 286 | sdk_os_timer_disarm(&extra_func_timer); 287 | sdk_os_timer_arm(&extra_func_timer, 10000, 1); 288 | 289 | } else if (event == WIFI_CONFIG_DISCONNECTED) { 290 | printf("Disconnected from WiFi\n"); 291 | } 292 | } 293 | 294 | 295 | void gpio_init() { 296 | gpio_enable(led_gpio, GPIO_OUTPUT); 297 | led_write(true); 298 | 299 | 300 | adv_toggle_create(motion_sensor_gpio, false); // false -> without internal pull-up resistor 301 | adv_toggle_register_callback_fn(motion_sensor_gpio, movement_detected_fn, 1); // High gpio state 302 | adv_toggle_register_callback_fn(motion_sensor_gpio, movement_not_detected_fn, 0); // Low gpio state 303 | 304 | 305 | adv_button_create(button_gpio, true); 306 | adv_button_register_callback_fn(button_gpio, button_callback_single, 1); 307 | adv_button_register_callback_fn(button_gpio, button_hold_callback, 5); 308 | 309 | } 310 | 311 | 312 | void user_init(void) { 313 | uart_set_baud(0, 115200); 314 | // wifi_config_init("Homekit-sensor", NULL, on_wifi_ready); 315 | wifi_config_init2("Homekit-sensor", NULL, on_wifi_event); 316 | gpio_init(); 317 | create_accessory_name(); 318 | 319 | } 320 | 321 | 322 | 323 | 324 | -------------------------------------------------------------------------------- /examples/multiple_sensors_ac/Makefile: -------------------------------------------------------------------------------- 1 | PROGRAM = main 2 | 3 | EXTRA_COMPONENTS = \ 4 | extras/onewire \ 5 | extras/ds18b20 \ 6 | extras/dht \ 7 | extras/http-parser \ 8 | extras/dhcpserver \ 9 | extras/rboot-ota \ 10 | $(abspath ../../lib/adv_button) \ 11 | $(abspath ../../lib/led_codes)\ 12 | $(abspath ../../components/esp-8266/wifi_config) \ 13 | $(abspath ../../components/common/wolfssl) \ 14 | $(abspath ../../components/esp-8266/cJSON) \ 15 | $(abspath ../../components/esp-led-status) \ 16 | $(abspath ../../components/common/homekit)\ 17 | $(abspath ../../components/esp-ir)\ 18 | $(abspath ../../components/UDPlogger) 19 | 20 | 21 | FLASH_SIZE = 8 22 | FLASH_MODE = dout 23 | FLASH_SPEED = 40 24 | 25 | HOMEKIT_SPI_FLASH_BASE_ADDR = 0x8c000 26 | HOMEKIT_MAX_CLIENTS = 16 27 | HOMEKIT_SMALL = 0 28 | 29 | ##AYto einai gia to hostname 30 | 31 | 32 | EXTRA_CFLAGS += -I../.. -DHOMEKIT_SHORT_APPLE_UUIDS 33 | EXTRA_CFLAGS += -DHOMEKIT_OVERCLOCK_PAIR_VERIFY 34 | EXTRA_CFLAGS += -DHOMEKIT_OVERCLOCK_PAIR_SETUP 35 | EXTRA_CFLAGS += -DUDPLOG_PRINTF_TO_UDP 36 | EXTRA_CFLAGS += -DUDPLOG_PRINTF_ALSO_SERIAL 37 | EXTRA_CFLAGS += -DLWIP_NETIF_HOSTNAME=1 38 | EXTRA_CFLAGS += -DconfigUSE_TRACE_FACILITY 39 | 40 | ## DEBUG 41 | #EXTRA_CFLAGS += -DHOMEKIT_DEBUG=1 42 | 43 | 44 | include $(SDK_PATH)/common.mk 45 | 46 | signature: 47 | $(shell openssl sha384 -binary -out firmware/main.bin.sig firmware/main.bin) 48 | $(shell printf "%08x" `cat firmware/main.bin | wc -c`| xxd -r -p >>firmware/main.bin.sig) 49 | 50 | monitor: 51 | $(FILTEROUTPUT) --port $(ESPPORT) --baud 115200 --elf $(PROGRAM_OUT) 52 | -------------------------------------------------------------------------------- /examples/multiple_sensors_ac/ac_commands.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | //#include 6 | #include 7 | #include 8 | #include "ac_commands.h" 9 | 10 | //Below codes are for TOYOTOMI AC 11 | static const int16_t Fan[] = {9000,-4000,620,-1600,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-620,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620}; //AnalysIR Batch Export (IRremote) - RAW 12 | static const int16_t Cool_16[] = {9000,-4000,620,-1600,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620}; 13 | 14 | static const int16_t Cool_17[] = {9000,-4000,620,-1600,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620}; //AnalysIR Batch Export (IRremote) - RAW 15 | static const int16_t Cool_18[] = {9000,-4000,620,-1600,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-540,620}; //AnalysIR Batch Export (IRremote) - RAW 16 | static const int16_t Cool_19[] = {9000,-4000,620,-1600,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620}; //AnalysIR Batch Export (IRremote) - RAW 17 | static const int16_t Cool_20[] = {9000,-4000,620,-1600,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-1600,620}; //AnalysIR Batch Export (IRremote) - RAW 18 | static const int16_t Cool_21[] = {9000,-4000,620,-1600,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620}; //AnalysIR Batch Export (IRremote) - RAW 19 | static const int16_t Cool_22[] = {9000,-4000,620,-1600,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-1600,620}; //AnalysIR Batch Export (IRremote) - RAW 20 | static const int16_t Cool_23[] = {9000,-4000,620,-1600,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620}; //AnalysIR Batch Export (IRremote) - RAW 21 | static const int16_t Cool_24[] = {9000,-4000,620,-1600,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-1600,620}; //AnalysIR Batch Export (IRremote) - RAW 22 | static const int16_t Cool_25[] = {9000,-4000,620,-1600,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620}; //AnalysIR Batch Export (IRremote) - RAW 23 | static const int16_t Cool_26[] = {9000,-4000,620,-1600,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-1600,620}; //AnalysIR Batch Export (IRremote) - RAW 24 | static const int16_t Cool_27[] = {9000,-4000,620,-1600,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620}; //AnalysIR Batch Export (IRremote) - RAW 25 | static const int16_t Cool_28[] = {9000,-4000,620,-1600,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620}; //AnalysIR Batch Export (IRremote) - RAW 26 | static const int16_t Cool_29[] = {9000,-4000,620,-1600,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620}; //AnalysIR Batch Export (IRremote) - RAW 27 | static const int16_t Cool_30[] = {9000,-4000,620,-1600,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620}; //AnalysIR Batch Export (IRremote) - RAW 28 | 29 | 30 | static const int16_t Heat_16[] = {9000,-4000,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620}; 31 | static const int16_t Heat_17[] = {9000,-4000,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-1600,620}; 32 | static const int16_t Heat_18[] = {9000,-4000,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,1600,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620}; 33 | static const int16_t Heat_19[] = {9000,-4000,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-1600,620}; 34 | static const int16_t Heat_20[] = {9000,-4000,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620}; 35 | static const int16_t Heat_21[] = {9000,-4000,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-1600,620}; 36 | static const int16_t Heat_22[] = {9000,-4000,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620}; 37 | static const int16_t Heat_23[] = {9000,-4000,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-1600,620}; 38 | static const int16_t Heat_24[] = {9000,-4000,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620}; 39 | static const int16_t Heat_25[] = {9000,-4000,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620}; 40 | static const int16_t Heat_26[] = {9000,-4000,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620}; 41 | static const int16_t Heat_27[] = {9000,-4000,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620}; 42 | static const int16_t Heat_28[] = {9000,-4000,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620}; 43 | static const int16_t Heat_29[] = {9000,-4000,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620}; 44 | static const int16_t Heat_30[] = {9000,-4000,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620}; 45 | 46 | 47 | static const int16_t Off[] = {9000,-4000,620,-1600,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-1600,620,-540,620,-540,620,-1600,620,-540,620,-19000,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-540,620,-1600,620,-1600,620,-540,620,-1600,620}; //AnalysIR Batch Export (IRremote) - RAW 48 | 49 | 50 | 51 | 52 | void ac_button_off(){ 53 | 54 | //ir_tx_init(); 55 | printf("...Sending OFF command...\n"); 56 | ir_raw_send(Off, sizeof(Off) / sizeof(*Off)); 57 | 58 | } 59 | 60 | void ac_button_aut(){ 61 | 62 | //ir_tx_init(); 63 | printf("Sending Fan command\n"); 64 | ir_raw_send(Fan, sizeof(Fan) / sizeof(*Fan)); 65 | 66 | } 67 | 68 | void ac_command(int target_state, float target_temp){ 69 | 70 | int16_t *RawData; 71 | uint16_t length1; 72 | 73 | if(target_state == 2) 74 | { 75 | //Cool mode 76 | 77 | if (target_temp == 16.0) 78 | { 79 | RawData = Cool_16; 80 | length1 = sizeof(Cool_16)/ sizeof(*Cool_16); 81 | } 82 | else if (target_temp == 17.0) 83 | { 84 | RawData = Cool_17; 85 | length1 =sizeof(Cool_17)/ sizeof(*Cool_17); 86 | } 87 | else if (target_temp == 18.0) 88 | { 89 | 90 | RawData = Cool_18; 91 | length1 = sizeof(Cool_18)/sizeof(*Cool_18); 92 | } 93 | else if (target_temp == 19.0) 94 | { 95 | RawData = Cool_19; 96 | length1 = sizeof(Cool_19)/sizeof(*Cool_19); 97 | } 98 | else if (target_temp == 20.0) 99 | { 100 | RawData = Cool_20; 101 | length1 = sizeof(Cool_20)/sizeof(*Cool_20); 102 | } 103 | else if (target_temp == 21.0) 104 | { 105 | RawData = Cool_21; 106 | length1 = sizeof(Cool_21)/sizeof(*Cool_21); 107 | } 108 | else if (target_temp == 22.0) 109 | { 110 | RawData = Cool_22; 111 | length1 =sizeof(Cool_22)/ sizeof(*Cool_22); 112 | } 113 | else if (target_temp == 23.0) 114 | { 115 | RawData = Cool_23; 116 | length1 = sizeof(Cool_23)/sizeof(*Cool_23); 117 | } 118 | else if (target_temp == 24.0) 119 | { 120 | RawData = Cool_24; 121 | length1 = sizeof(Cool_24)/sizeof(*Cool_24); 122 | } 123 | else if (target_temp == 25.0) 124 | { 125 | RawData = Cool_25; 126 | length1 = sizeof(Cool_25)/sizeof(*Cool_25); 127 | } 128 | else if (target_temp == 26.0) 129 | { 130 | RawData = Cool_26; 131 | length1 = sizeof(Cool_26)/sizeof(*Cool_26); 132 | } 133 | else if (target_temp == 27.0) 134 | { 135 | RawData = Cool_27; 136 | length1 = sizeof(Cool_27)/sizeof(*Cool_27); 137 | } 138 | else if (target_temp == 28.0) 139 | { 140 | RawData = Cool_28; 141 | length1 =sizeof(Cool_28)/ sizeof(*Cool_28); 142 | } 143 | else if (target_temp == 29.0) 144 | { 145 | RawData = Cool_29; 146 | length1 = sizeof(Cool_29)/sizeof(*Cool_29); 147 | } 148 | else if (target_temp == 30.0) 149 | { 150 | RawData = Cool_30; 151 | length1 = sizeof(Cool_30)/sizeof(*Cool_30); 152 | } 153 | 154 | } 155 | 156 | if( target_state == 1) 157 | { 158 | //Heat mode 159 | if (target_temp == 16.0) 160 | { 161 | RawData = Heat_16; 162 | length1 = sizeof(Heat_16)/sizeof(*Heat_16); 163 | } 164 | else if (target_temp == 17.0) 165 | { 166 | RawData = Heat_17; 167 | length1 = sizeof(Heat_17)/sizeof(*Heat_17); 168 | } 169 | else if (target_temp == 18.0) 170 | { 171 | RawData = Heat_18; 172 | length1 = sizeof(Heat_18)/sizeof(*Heat_18); 173 | } 174 | else if (target_temp == 19.0) 175 | { 176 | RawData = Heat_19; 177 | length1 = sizeof(Heat_19)/sizeof(*Heat_19); 178 | } 179 | else if (target_temp == 20.0) 180 | { 181 | RawData = Heat_20; 182 | length1 = sizeof(Heat_20)/sizeof(*Heat_20); 183 | } 184 | else if (target_temp == 21.0) 185 | { 186 | RawData = Heat_21; 187 | length1 = sizeof(Heat_21)/sizeof(*Heat_21); 188 | } 189 | else if (target_temp == 22.0) 190 | { 191 | RawData = Heat_22; 192 | length1 = sizeof(Heat_22)/sizeof(*Heat_22); 193 | } 194 | else if (target_temp == 23.0) 195 | { 196 | RawData = Heat_23; 197 | length1 = sizeof(Heat_23)/sizeof(*Heat_23); 198 | } 199 | else if (target_temp == 24.0) 200 | { 201 | RawData = Heat_24; 202 | length1 = sizeof(Heat_24)/sizeof(*Heat_24); 203 | } 204 | else if (target_temp == 25.0) 205 | { 206 | RawData = Heat_25; 207 | length1 = sizeof(Heat_25)/sizeof(*Heat_25); 208 | } 209 | else if (target_temp == 26.0) 210 | { 211 | RawData = Heat_26; 212 | length1 = sizeof(Heat_26)/sizeof(*Heat_26); 213 | } 214 | else if (target_temp == 27.0) 215 | { 216 | RawData = Heat_27; 217 | length1 = sizeof(Heat_27)/sizeof(*Heat_27); 218 | } 219 | else if (target_temp == 28.0) 220 | { 221 | RawData = Heat_28; 222 | length1 = sizeof(Heat_28)/sizeof(*Heat_28); 223 | } 224 | else if (target_temp == 29.0) 225 | { 226 | RawData = Heat_29; 227 | length1 = sizeof(Heat_29)/sizeof(*Heat_29); 228 | } 229 | else if (target_temp == 30.0) 230 | { 231 | RawData = Heat_30; 232 | length1 = sizeof(Heat_30)/sizeof(*Heat_30); 233 | } 234 | 235 | } 236 | 237 | if( target_state == 0) 238 | { 239 | //printf("Fan mode\n", 30 ); 240 | RawData = Off; 241 | length1 = sizeof(Off)/sizeof(*Off); 242 | } 243 | 244 | //ir_tx_init(); 245 | ir_raw_send(RawData, length1); 246 | 247 | 248 | } 249 | -------------------------------------------------------------------------------- /examples/multiple_sensors_ac/ac_commands.h: -------------------------------------------------------------------------------- 1 | //#pragma once 2 | 3 | 4 | void ac_command(int target_state, float target_temp); 5 | void ac_button_off(); 6 | void ac_button_aut(); -------------------------------------------------------------------------------- /examples/multiple_sensors_ac/main.c: -------------------------------------------------------------------------------- 1 | //#include 2 | //#include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | //#include "../common/custom_characteristics.h" 19 | #include 20 | #include 21 | //#include "http.h" 22 | #include 23 | 24 | #include 25 | 26 | 27 | //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 28 | #include 29 | #include 30 | 31 | #include 32 | 33 | #include "FreeRTOS.h" 34 | #include "task.h" 35 | 36 | #include "lwip/err.h" 37 | #include "lwip/sockets.h" 38 | #include "lwip/sys.h" 39 | #include "lwip/netdb.h" 40 | #include "lwip/dns.h" 41 | #include "lwip/api.h" 42 | 43 | #include "ac_commands.h" 44 | 45 | #define UDPLOG_PRINTF_TO_UDP 46 | #define UDPLOG_PRINTF_ALSO_SERIAL 47 | //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 48 | 49 | #define DEVICE_MANUFACTURER "Unknown" 50 | #define DEVICE_NAME "MultiSensor" 51 | #define DEVICE_MODEL "esp8266" 52 | char serial_value[13]; //Device Serial is set upon boot based on MAC address 53 | #define FW_VERSION "0.0.1" 54 | 55 | //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 56 | //#define USE_THINGSPEAK 0 //Turn this into '1' if you want to use log temperature/humidity data at ThingsSpeak.com server 57 | bool USE_THINGSPEAK =false ; 58 | #define WEB_SERVER "api.thingspeak.com" 59 | char *API_KEY = NULL; //Private Key 60 | char *FIELD1 = NULL; //temp 61 | char *FIELD2 = NULL; //hum 62 | #define WEB_PORT "80" 63 | #define WEB_PATH "/update?api_key=" 64 | #define THINGSPEAK_INTERVAL 600000 //600000 = 10min , 300000 = 5min 60000 = 1min 65 | #define NUMBER_OF_RETRIES 5 66 | bool Http_TaskStarted =false; 67 | 68 | TaskHandle_t callThingsProcess_handle = NULL; 69 | 70 | 71 | //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 72 | 73 | // add this section to make your device OTA capable 74 | // create the extra characteristic &ota_trigger, at the end of the primary service (before the NULL) 75 | // it can be used in Eve, which will show it, where Home does not 76 | // and apply the four other parameters in the accessories_information section 77 | 78 | #include "ota-api.h" 79 | homekit_characteristic_t ota_trigger = API_OTA_TRIGGER; 80 | //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 81 | 82 | const int led_gpio = 2; // Pin D4 83 | const int button_gpio = 4; //Pin (D2) 84 | const int motion_sensor_gpio = 16; // Wemos D1 mini pin: D0 85 | const int SENSOR_PIN = 5; //DHT sensor on pin D1 86 | const int IR_PIN = 14 ; // Wemos D1 mini pin: D5. (Just for Reference) 87 | //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 88 | 89 | #define FREEHEAP() printf("Free Heap: %d\n", xPortGetFreeHeapSize()) 90 | 91 | volatile float old_humidity_value = 0.0, old_temperature_value = 0.0 , old_light_value =0.0, old_move_value = 0.0; 92 | //AC related variables 93 | volatile int stored_active_state = 0; 94 | volatile int current_ac_mode = 0; //0=Automatic , 1=Heater , 2=Cool 95 | volatile int current_ac_temp = 0; 96 | 97 | volatile bool paired = false; 98 | bool led_value = false; //This is to keep track of the LED status. 99 | volatile bool Wifi_Connected = false; 100 | 101 | 102 | //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 103 | //Light Sensor Parameters 104 | #define LIGHT_SENSOR_TYPE (0) 105 | #define LUX_CALC_SCALAR (14357564.33) 106 | #define LIGHT_SENSOR_OFFSET (0) 107 | #define LIGHT_SENSOR_RESISTOR (8500) 108 | #define LUX_CALC_EXPONENT (1.396066767) 109 | //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 110 | 111 | bool extra_function_TaskStarted = false; 112 | bool extra_http_TaskStarted = false; 113 | bool param_started = false; 114 | ETSTimer extra_func_timer ; 115 | 116 | void httpd_task(void *pvParameters) 117 | { 118 | if (!FIELD1) 119 | FIELD1= malloc(20); 120 | 121 | if (!API_KEY) 122 | API_KEY= malloc(20); 123 | 124 | if (!FIELD2) 125 | FIELD2= malloc(20); 126 | 127 | struct netconn *client = NULL; 128 | struct netconn *nc = netconn_new(NETCONN_TCP); 129 | if (nc == NULL) { 130 | printf("Failed to allocate socket.\n"); 131 | vTaskDelete(NULL); 132 | } 133 | netconn_bind(nc, IP_ADDR_ANY, 81); 134 | netconn_listen(nc); 135 | char buf[920]; 136 | const char *webpage = { 137 | "HTTP/1.1 200 OK\r\n" 138 | "Content-type: text/html\r\n\r\n" 139 | "HTTP Server" 140 | "" 146 | "
" 147 | "

Homekit AC

" 148 | "

URL: %s

" 149 | "

Uptime: %d seconds

" 150 | "

Free heap: %d bytes

" 151 | "

Thingspeak: %d

" 152 | "

API: %s

" 153 | "

Field1: %s

" 154 | "

Field2: %s

" 155 | "

" 157 | "

" 159 | "

" 161 | "

" 163 | "

" 165 | "
" 166 | }; 167 | /* disable LED */ 168 | 169 | while (1) { 170 | err_t err = netconn_accept(nc, &client); 171 | if (err == ERR_OK) { 172 | struct netbuf *nb; 173 | if ((err = netconn_recv(client, &nb)) == ERR_OK) { 174 | void *data; 175 | u16_t len; 176 | netbuf_data(nb, &data, &len); 177 | /* check for a GET request */ 178 | if (!strncmp(data, "GET ", 4)) { 179 | char uri[25]; 180 | const int max_uri_len = 25; 181 | char *sp1, *sp2; 182 | /* extract URI */ 183 | sp1 = data + 4; 184 | sp2 = memchr(sp1, ' ', max_uri_len); 185 | int len = sp2 - sp1; 186 | memcpy(uri, sp1, len); 187 | uri[len] = '\0'; 188 | printf("uri: %s\n", uri); 189 | if (!strncmp(uri, "/REBOOT", max_uri_len)) 190 | sdk_system_restart(); 191 | else if (!strncmp(uri, "/UPDATE", max_uri_len)) 192 | { 193 | printf("Updating firmware...\n"); 194 | rboot_set_temp_rom(1); 195 | vTaskDelay(1000 / portTICK_PERIOD_MS); 196 | sdk_system_restart(); 197 | } 198 | else if (!strncmp(uri, "/OFF", max_uri_len)) 199 | { 200 | taskENTER_CRITICAL(); 201 | ac_button_off(); 202 | taskEXIT_CRITICAL(); 203 | } 204 | else if (!strncmp(uri, "/COOL", max_uri_len)) 205 | { 206 | ac_command(2,22); 207 | } 208 | else if (!strncmp(uri, "/HEAT", max_uri_len)) 209 | { 210 | ac_command(1,27); 211 | } 212 | else if (!strncmp(uri, "/thingspeak", max_uri_len)) 213 | { 214 | 215 | USE_THINGSPEAK = !USE_THINGSPEAK ; 216 | sysparam_set_int8("USE_THINGSPEAK",(int) USE_THINGSPEAK); 217 | if (USE_THINGSPEAK == false) { 218 | //If the flag just turned false, you must delete the already current task. 219 | taskHttp_delete(); 220 | } 221 | 222 | } 223 | else if (!strncmp(uri, "/reset-homekit", max_uri_len)) 224 | { 225 | printf("Resetting HomeKit Config\n"); 226 | homekit_server_reset(); 227 | vTaskDelay(1000 / portTICK_PERIOD_MS); 228 | printf("Restarting\n"); 229 | sdk_system_restart(); 230 | } 231 | else if (!strncmp(uri, "/api", 4)) 232 | { 233 | if (!API_KEY) 234 | API_KEY= malloc(20); 235 | int length1 = strlen(uri); 236 | strncpy(API_KEY,uri+5,length1-4); 237 | sysparam_set_string("API_KEY",API_KEY); 238 | } 239 | else if (!strncmp(uri, "/field1", 7)) 240 | { 241 | int length1 = strlen(uri); 242 | if((length1-7)<10 && length1>7) 243 | { 244 | if (!FIELD1) 245 | FIELD1= malloc(20); 246 | strncpy(FIELD1,uri+8,length1-6); 247 | printf("%s\n",FIELD1); 248 | sysparam_set_string("FIELD1",FIELD1); 249 | } 250 | } 251 | else if (!strncmp(uri, "/field2", 7)) 252 | { 253 | int length1 = strlen(uri); 254 | if((length1-7)<10 && length1>7) 255 | { 256 | if (!FIELD2) 257 | FIELD2= malloc(20); 258 | strncpy(FIELD2,uri+8,length1-6); 259 | printf("%s\n",FIELD2); 260 | sysparam_set_string("FIELD2",FIELD2); 261 | } 262 | } 263 | 264 | 265 | // gpio_write(2, true); 266 | printf("TEST\n"); 267 | snprintf(buf, sizeof(buf), webpage, 268 | uri, 269 | xTaskGetTickCount() * portTICK_PERIOD_MS / 1000, 270 | (int) xPortGetFreeHeapSize(),(int) USE_THINGSPEAK,API_KEY,FIELD1,FIELD2); 271 | netconn_write(client, buf, strlen(buf), NETCONN_COPY); 272 | 273 | } 274 | } 275 | netbuf_delete(nb); 276 | 277 | } 278 | printf("Closing connection\n"); 279 | netconn_close(client); 280 | netconn_delete(client); 281 | } 282 | } 283 | 284 | inline double fast_precise_pow(double a, double b) { 285 | int e = abs((int)b); 286 | 287 | union { 288 | double d; 289 | int x[2]; 290 | } u = { a }; 291 | 292 | u.x[1] = (int) ((b - e) * (u.x[1] - 1072632447) + 1072632447); 293 | u.x[0] = 0; 294 | 295 | double r = 1.0; 296 | 297 | while (e) { 298 | if (e & 1) { 299 | r *= a; 300 | } 301 | a *= a; 302 | e >>= 1; 303 | } 304 | 305 | return r * u.d; 306 | } 307 | 308 | float light_sensor_task() { 309 | // https://www.allaboutcircuits.com/projects/design-a-luxmeter-using-a-light-dependent-resistor/ 310 | //Thanks to: https://github.com/RavenSystem/esp-homekit-devices/blob/2fd952227bedebc6694236fe64129b6861791dac/devices/HAA/main.c#L3258 311 | 312 | float luxes = 0.0001f; 313 | 314 | const float adc_raw_read = sdk_system_adc_read(); 315 | float ldr_resistor; 316 | if (LIGHT_SENSOR_TYPE < 2) { 317 | 318 | if (LIGHT_SENSOR_TYPE == 0) { 319 | ldr_resistor = LIGHT_SENSOR_RESISTOR * ((1023.1 - adc_raw_read) / adc_raw_read); 320 | } 321 | else if (LIGHT_SENSOR_TYPE == 1) 322 | { 323 | ldr_resistor = (LIGHT_SENSOR_RESISTOR * adc_raw_read) / (1023.1 - adc_raw_read); 324 | } 325 | luxes = 1 / fast_precise_pow(ldr_resistor, LUX_CALC_EXPONENT); 326 | luxes = (luxes * LUX_CALC_SCALAR) + LIGHT_SENSOR_OFFSET; 327 | } 328 | else if (LIGHT_SENSOR_TYPE == 2) 329 | { 330 | luxes = adc_raw_read; 331 | 332 | } 333 | else if (LIGHT_SENSOR_TYPE == 3) 334 | { 335 | luxes = 1023 - adc_raw_read; 336 | 337 | } 338 | 339 | 340 | printf("Luxes: %g\n", luxes); 341 | printf("ADC: %g\n",(float) sdk_system_adc_read()); 342 | 343 | if (luxes < 0.0001f) { 344 | luxes = 0.0001f; 345 | } else if (luxes > 100000.f) { 346 | luxes = 100000.f; 347 | } 348 | 349 | 350 | return luxes; 351 | } 352 | 353 | 354 | 355 | //#################################################################################### 356 | //LED codes 357 | // 1000ms ON, 1000ms OFF 358 | led_status_pattern_t waiting_wifi = LED_STATUS_PATTERN({1500, -500}); 359 | 360 | // one short blink every 3 seconds 361 | led_status_pattern_t normal_mode = LED_STATUS_PATTERN({100, -2900}); 362 | 363 | // one short blink every 3 seconds 364 | led_status_pattern_t unpaired = LED_STATUS_PATTERN({100, -100, 100, -100, 100, -700}); 365 | 366 | led_status_pattern_t pairing_started = LED_STATUS_PATTERN({400, -200,400, -200, 400, -200, 100, -700}); 367 | 368 | 369 | // three short blinks 370 | led_status_pattern_t three_short_blinks = LED_STATUS_PATTERN({100, -100, 100, -100, 100, -700}); 371 | 372 | #define STATUS_LED_PIN 2 373 | 374 | static led_status_t led_status ; 375 | //#################################################################################### 376 | 377 | 378 | void on_update(homekit_characteristic_t *ch, homekit_value_t value, void *context) { 379 | update_state(); 380 | } 381 | 382 | void on_temp_update(homekit_characteristic_t *ch, homekit_value_t value, void *context) { 383 | update_temp(); 384 | } 385 | 386 | 387 | void on_active_change(homekit_characteristic_t *ch, homekit_value_t value, void *context) { 388 | update_active(); 389 | } 390 | 391 | ////%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 392 | 393 | 394 | 395 | //following code thanks to @maccoylton at https://github.com/maccoylton/esp-homekit-common-functions/blob/master/shared_functions/shared_functions.c 396 | //* configUSE_TRACE_FACILITY must be defined as 1 in FreeRTOSConfig.h , or in makefile: EXTRA_CFLAGS += -DconfigUSE_TRACE_FACILITY 397 | // * uxTaskGetSystemState() to be available. 398 | TaskHandle_t task_stats_task_handle = NULL; 399 | void task_stats_task ( void *args) 400 | { 401 | TaskStatus_t *pxTaskStatusArray; 402 | UBaseType_t uxArraySize, x; 403 | uint32_t ulTotalRunTime; 404 | unsigned long ulStatsAsPercentage; 405 | 406 | 407 | printf ("%s", __func__); 408 | 409 | while (1) { 410 | /* Take a snapshot of the number of tasks in case it changes while this 411 | function is executing. */ 412 | uxArraySize = uxTaskGetNumberOfTasks(); 413 | 414 | printf (", uxTaskGetNumberOfTasks %ld", uxArraySize); 415 | /* Allocate a TaskStatus_t structure for each task. An array could be 416 | allocated statically at compile time. */ 417 | pxTaskStatusArray = pvPortMalloc( uxArraySize * sizeof( TaskStatus_t ) ); 418 | 419 | printf (", pvPortMalloc"); 420 | 421 | if( pxTaskStatusArray != NULL ) 422 | { 423 | /* Generate raw status information about each task. */ 424 | uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, 425 | uxArraySize, 426 | &ulTotalRunTime ); 427 | 428 | printf (", uxTaskGetSystemState, ulTotalRunTime %d, array size %ld\n", ulTotalRunTime, uxArraySize); 429 | 430 | /* Avoid divide by zero errors. */ 431 | /* if( ulTotalRunTime > 0 ) 432 | {*/ 433 | /* For each populated position in the pxTaskStatusArray array, 434 | format the raw data as human readable ASCII data. */ 435 | for( x = 0; x < uxArraySize; x++ ) 436 | { 437 | /* What percentage of the total run time has the task used? 438 | This will always be rounded down to the nearest integer. 439 | ulTotalRunTimeDiv100 has already been divided by 100. */ 440 | ulStatsAsPercentage = 441 | pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime / 100; 442 | 443 | 444 | printf ( "Name:%-20s, Runtime Counter:%-3d, Current State:%-3d, Current Priority:%-5ld, Base Priority:%-5ld, High Water Mark (bytes) %-5d\n", 445 | pxTaskStatusArray[ x ].pcTaskName, 446 | pxTaskStatusArray[ x ].ulRunTimeCounter, 447 | pxTaskStatusArray[ x ].eCurrentState, 448 | pxTaskStatusArray[ x ].uxCurrentPriority , 449 | pxTaskStatusArray[ x ].uxBasePriority, 450 | pxTaskStatusArray[x].usStackHighWaterMark); 451 | 452 | /* printf ( " Runtime Percentage:%lu,",ulStatsAsPercentage);*/ 453 | 454 | } 455 | /* }*/ 456 | 457 | 458 | 459 | /* The array is no longer needed, free the memory it consumes. */ 460 | vPortFree( pxTaskStatusArray ); 461 | printf ("%s, vPortFree\n", __func__); 462 | } 463 | 464 | FREEHEAP(); 465 | 466 | vTaskDelay((30000) / portTICK_PERIOD_MS); 467 | } 468 | 469 | } 470 | 471 | void switch_on_callback(homekit_characteristic_t *_ch, homekit_value_t on, void *context); 472 | homekit_characteristic_t switch_on = HOMEKIT_CHARACTERISTIC_( 473 | ON, false, .callback=HOMEKIT_CHARACTERISTIC_CALLBACK(switch_on_callback) 474 | ); 475 | 476 | 477 | void switch_on_callback(homekit_characteristic_t *_ch, homekit_value_t on, void *context) { 478 | printf("Task Stats\n"); 479 | FREEHEAP(); 480 | if (switch_on.value.bool_value) 481 | { 482 | if (task_stats_task_handle == NULL){ 483 | xTaskCreate(task_stats_task, "task_stats_task", 256 , NULL, tskIDLE_PRIORITY+1, &task_stats_task_handle); 484 | } else { 485 | printf ("%s task_Status_set TRUE, but task pointer not NULL\n", __func__); 486 | } 487 | } 488 | else 489 | { 490 | if (task_stats_task_handle != NULL){ 491 | vTaskDelete (task_stats_task_handle); 492 | task_stats_task_handle = NULL; 493 | } else { 494 | printf ("%s task_Status_set FALSE, but task pointer is NULL\n", __func__); 495 | } 496 | FREEHEAP(); 497 | 498 | } 499 | 500 | } 501 | // //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 502 | //Temperature, Humidity sensors 503 | homekit_characteristic_t temperature = HOMEKIT_CHARACTERISTIC_(CURRENT_TEMPERATURE, 0); 504 | homekit_characteristic_t humidity = HOMEKIT_CHARACTERISTIC_(CURRENT_RELATIVE_HUMIDITY, 0); 505 | //Additional for Motion Sensor 506 | homekit_characteristic_t motion_detected = HOMEKIT_CHARACTERISTIC_(MOTION_DETECTED, 0); 507 | homekit_characteristic_t currentAmbientLightLevel = HOMEKIT_CHARACTERISTIC_(CURRENT_AMBIENT_LIGHT_LEVEL, 0,.min_value = (float[]) {0},); 508 | homekit_characteristic_t name = HOMEKIT_CHARACTERISTIC_(NAME, "Sonoff Switch"); 509 | //AC Required Parameters 510 | homekit_characteristic_t active = HOMEKIT_CHARACTERISTIC_(ACTIVE, 0,.callback=HOMEKIT_CHARACTERISTIC_CALLBACK(on_active_change)); 511 | homekit_characteristic_t current_temperature = HOMEKIT_CHARACTERISTIC_(CURRENT_TEMPERATURE, 0); 512 | homekit_characteristic_t current_heater_cooler_state = HOMEKIT_CHARACTERISTIC_(CURRENT_HEATER_COOLER_STATE, 0); 513 | homekit_characteristic_t target_heater_cooler_state = HOMEKIT_CHARACTERISTIC_(TARGET_HEATER_COOLER_STATE, 0, .callback=HOMEKIT_CHARACTERISTIC_CALLBACK(on_update)); 514 | //optionals 515 | //homekit_characteristic_t units = HOMEKIT_CHARACTERISTIC_(TEMPERATURE_DISPLAY_UNITS, 0); 516 | homekit_characteristic_t cooling_threshold = HOMEKIT_CHARACTERISTIC_(COOLING_THRESHOLD_TEMPERATURE, 18,.callback=HOMEKIT_CHARACTERISTIC_CALLBACK(on_temp_update),.min_value = (float[]) {18},.max_value = (float[]) {30},.min_step = (float[]) {1} ); 517 | homekit_characteristic_t heating_threshold = HOMEKIT_CHARACTERISTIC_(HEATING_THRESHOLD_TEMPERATURE, 25,.callback=HOMEKIT_CHARACTERISTIC_CALLBACK(on_temp_update),.min_value = (float[]) {18},.max_value = (float[]) {30},.min_step = (float[]) {1}); 518 | //homekit_characteristic_t rotation_speed = HOMEKIT_CHARACTERISTIC_(ROTATION_SPEED, 0, .callback=HOMEKIT_CHARACTERISTIC_CALLBACK(on_update)); 519 | 520 | //Device Information 521 | homekit_characteristic_t manufacturer = HOMEKIT_CHARACTERISTIC_(MANUFACTURER, DEVICE_MANUFACTURER); 522 | homekit_characteristic_t serial = HOMEKIT_CHARACTERISTIC_(SERIAL_NUMBER, serial_value); 523 | homekit_characteristic_t model = HOMEKIT_CHARACTERISTIC_(MODEL, DEVICE_MODEL); 524 | homekit_characteristic_t revision = HOMEKIT_CHARACTERISTIC_(FIRMWARE_REVISION, FW_VERSION); 525 | //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 526 | //AC related code 527 | void update_state() { 528 | uint8_t target_state = target_heater_cooler_state.value.int_value; 529 | uint8_t active_status = active.value.int_value; 530 | uint8_t current_state = current_heater_cooler_state.value.int_value; 531 | //printf("Running update_state() \n" ); 532 | printf("UPDATE STATE: Active State: %d, Current State: %d, Target State: %d \n",active_status, current_state, target_state ); 533 | 534 | 535 | //current_heater_cooler_state.value = HOMEKIT_UINT8(target_state+1); 536 | //homekit_characteristic_notify(¤t_heater_cooler_state, current_heater_cooler_state.value); 537 | sysparam_set_int8("ac_mode",target_state); 538 | current_ac_mode = target_state; 539 | stored_active_state = active_status; 540 | 541 | if (active_status == 0) { 542 | // printf("OFF\n" ); 543 | // ac_button_off(); 544 | } 545 | else 546 | { 547 | if(target_state == 0){ 548 | taskENTER_CRITICAL(); 549 | ac_button_aut(); 550 | taskEXIT_CRITICAL(); 551 | led_status_signal(led_status, &three_short_blinks); 552 | } 553 | else if ((target_state + 1 )!=current_state){ 554 | //printf("AC is now ON, updating temp\n" ); 555 | update_temp(); 556 | } 557 | } 558 | 559 | } 560 | void update_temp() { 561 | //TARGET: 562 | //0 = AUTOMATIC 563 | //1 = HEAT 564 | //2 = COOL 565 | 566 | //CURRENT STATE: 567 | //0 = inactive 568 | //1 = idle 569 | //2 = heating 570 | //3 = cooling 571 | 572 | //printf("Running update_temp() \n" ); 573 | uint8_t target_state = target_heater_cooler_state.value.int_value; 574 | uint8_t active_status = active.value.int_value; 575 | uint8_t current_state = current_heater_cooler_state.value.int_value; 576 | printf("UPDATE TEMP: Active Status: %d, Current State: %d, Target State: %d \n",active_status, current_state, target_state ); 577 | 578 | 579 | float target_temp1 = 0; 580 | target_state = (int)target_state; 581 | 582 | if (target_state == 0)//AUTOMATIC 583 | { 584 | if (active_status ==1) 585 | { 586 | printf("This should normally sent AUTO command\n" ); 587 | //Auto mode 588 | current_heater_cooler_state.value = HOMEKIT_UINT8(target_state); 589 | homekit_characteristic_notify(¤t_heater_cooler_state, current_heater_cooler_state.value); 590 | } 591 | 592 | /* code */ 593 | } 594 | else if (target_state == 1) { //HEAT 595 | //Read the Heat target 596 | target_temp1= heating_threshold.value.float_value; 597 | current_heater_cooler_state.value = HOMEKIT_UINT8(target_state+1); 598 | homekit_characteristic_notify(¤t_heater_cooler_state, current_heater_cooler_state.value); 599 | } 600 | else if (target_state == 2) //COOLING 601 | { 602 | //Else read the Cool target 603 | target_temp1= cooling_threshold.value.float_value; 604 | current_heater_cooler_state.value = HOMEKIT_UINT8(target_state+1); 605 | homekit_characteristic_notify(¤t_heater_cooler_state, current_heater_cooler_state.value); 606 | } 607 | current_ac_temp = (int)target_temp1; 608 | printf("Target temp: %.1f\n",target_temp1 ); 609 | 610 | sysparam_set_int8("ac_mode",target_state); 611 | sysparam_set_int8("ac_temp",(int)target_temp1); 612 | 613 | taskENTER_CRITICAL(); 614 | ac_command(target_state,target_temp1); 615 | taskEXIT_CRITICAL(); 616 | 617 | led_status_signal(led_status, &three_short_blinks); 618 | 619 | } 620 | 621 | void update_active() { 622 | 623 | //printf("\nRunning update_active() \n" ); 624 | uint8_t target_state = target_heater_cooler_state.value.int_value; 625 | uint8_t active_status = active.value.int_value; 626 | uint8_t current_state = current_heater_cooler_state.value.int_value; 627 | printf("\nUPDATE ACTIVE: Active Status: %d, Current State: %d, Target State: %d \n",active_status, current_state, target_state ); 628 | 629 | //If its being requested to turn ON and saved status is different, then send IR command 630 | 631 | if (active_status == 1 ) 632 | { 633 | if (target_state == 0) 634 | { 635 | taskENTER_CRITICAL(); 636 | ac_button_aut(); 637 | taskEXIT_CRITICAL(); 638 | led_status_signal(led_status, &three_short_blinks); 639 | } 640 | else 641 | { 642 | update_temp(); 643 | } 644 | } 645 | 646 | //If it is requested to turn off 647 | if (active_status == 0 ) { 648 | // printf("OFF\n" ); 649 | taskENTER_CRITICAL(); 650 | ac_button_off(); 651 | taskEXIT_CRITICAL(); 652 | led_status_signal(led_status, &three_short_blinks); 653 | } 654 | 655 | 656 | stored_active_state = active_status; 657 | 658 | //save ON/OFF status to sysparameters 659 | sysparam_set_int8("ac_active",stored_active_state); 660 | 661 | 662 | } 663 | 664 | void int_ac_state(){ 665 | //At reboot, set initial AC state from saved parameters 666 | sysparam_status_t status; 667 | 668 | printf("Initializing AC parameters\n"); 669 | 670 | status = sysparam_get_int8("ac_mode", ¤t_ac_mode); 671 | if (status == SYSPARAM_OK){ 672 | 673 | int new_current_status = 1; 674 | if (current_ac_mode == 1){ 675 | //Cool 676 | new_current_status =2; 677 | 678 | status = sysparam_get_int8("ac_temp", ¤t_ac_temp); 679 | if (status == SYSPARAM_OK){ 680 | heating_threshold.value = HOMEKIT_FLOAT((float)current_ac_temp); 681 | } 682 | 683 | } 684 | if (current_ac_mode == 2) 685 | { 686 | //Heating 687 | new_current_status =3; 688 | status = sysparam_get_int8("ac_temp", ¤t_ac_temp); 689 | if (status == SYSPARAM_OK){ 690 | printf("Temp:%d \n",current_ac_temp); 691 | cooling_threshold.value = HOMEKIT_FLOAT((float)current_ac_temp); 692 | 693 | } 694 | } 695 | 696 | current_heater_cooler_state.value = HOMEKIT_UINT8(new_current_status); 697 | target_heater_cooler_state.value = HOMEKIT_UINT8(current_ac_mode); 698 | 699 | } 700 | 701 | 702 | status = sysparam_get_int8("ac_active", &stored_active_state); 703 | if (status == SYSPARAM_OK){ 704 | active.value = HOMEKIT_UINT8(stored_active_state); 705 | } 706 | 707 | //Thingspeak parameters initialiazation 708 | 709 | if (!FIELD1) 710 | FIELD1= malloc(20); 711 | 712 | if (!API_KEY) 713 | API_KEY= malloc(20); 714 | 715 | if (!FIELD2) 716 | FIELD2= malloc(20); 717 | 718 | status = sysparam_get_int8("USE_THINGSPEAK", &USE_THINGSPEAK); 719 | status = sysparam_get_string("API_KEY",&API_KEY); 720 | status = sysparam_get_string("FIELD1",&FIELD1); 721 | status = sysparam_get_string("FIELD2",&FIELD2); 722 | 723 | 724 | } 725 | //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 726 | 727 | 728 | //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 729 | void call_things_process() 730 | { 731 | int successes = 0, failures = 0; 732 | printf("HTTP get task starting...\r\n"); 733 | 734 | while(1) { 735 | FREEHEAP(); 736 | if (xPortGetFreeHeapSize()<8000){ 737 | printf("Low free heap\n"); 738 | printf("Temporarily killing http task\n\n"); 739 | taskHttp_delete(); 740 | } 741 | 742 | 743 | if (Wifi_Connected == true) 744 | { 745 | printf("Running HTTP get request...\r\n"); 746 | 747 | if (old_humidity_value == 0.0) 748 | { 749 | printf("Temporarily killing http task, sensor values are not ready \r\n"); 750 | taskHttp_delete(); 751 | 752 | //vTaskDelay(120000 / portTICK_PERIOD_MS); 753 | //continue; 754 | } 755 | 756 | const struct addrinfo hints = { 757 | .ai_family = AF_UNSPEC, 758 | .ai_socktype = SOCK_STREAM, 759 | }; 760 | struct addrinfo *res; 761 | 762 | printf("Running DNS lookup for %s...\r\n", WEB_SERVER); 763 | int err = getaddrinfo(WEB_SERVER, WEB_PORT, &hints, &res); 764 | 765 | if (err != 0 || res == NULL) { 766 | printf("DNS lookup failed err=%d res=%p\r\n", err, res); 767 | if(res) 768 | freeaddrinfo(res); 769 | 770 | vTaskDelay(1000 / portTICK_PERIOD_MS); 771 | failures++; 772 | if (failures>NUMBER_OF_RETRIES) 773 | { 774 | printf("Too many http failures. Temporarily killing http task\r\n"); 775 | taskHttp_delete(); 776 | } 777 | continue; 778 | } 779 | 780 | #if LWIP_IPV6 781 | { 782 | struct netif *netif = sdk_system_get_netif(0); 783 | int i; 784 | for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 785 | printf(" ip6 %d state %x\n", i, netif_ip6_addr_state(netif, i)); 786 | if (!ip6_addr_isinvalid(netif_ip6_addr_state(netif, i))) 787 | printf(" ip6 addr %d = %s\n", i, ip6addr_ntoa(netif_ip6_addr(netif, i))); 788 | } 789 | } 790 | #endif 791 | 792 | struct sockaddr *sa = res->ai_addr; 793 | if (sa->sa_family == AF_INET) { 794 | printf("DNS lookup succeeded. IP=%s\r\n", inet_ntoa(((struct sockaddr_in *)sa)->sin_addr)); 795 | } 796 | #if LWIP_IPV6 797 | if (sa->sa_family == AF_INET6) { 798 | printf("DNS lookup succeeded. IP=%s\r\n", inet6_ntoa(((struct sockaddr_in6 *)sa)->sin6_addr)); 799 | } 800 | #endif 801 | 802 | int s = socket(res->ai_family, res->ai_socktype, 0); 803 | if(s < 0) { 804 | printf("... Failed to allocate socket.\r\n"); 805 | freeaddrinfo(res); 806 | vTaskDelay(1000 / portTICK_PERIOD_MS); 807 | failures++; 808 | if (failures>NUMBER_OF_RETRIES) 809 | { 810 | printf("Too many http failures. Temporarily killing http task\r\n"); 811 | taskHttp_delete(); 812 | } 813 | continue; 814 | } 815 | 816 | printf("... allocated socket\r\n"); 817 | 818 | if(connect(s, res->ai_addr, res->ai_addrlen) != 0) { 819 | close(s); 820 | freeaddrinfo(res); 821 | printf("... socket connect failed.\r\n"); 822 | vTaskDelay(4000 / portTICK_PERIOD_MS); 823 | failures++; 824 | // if (failures>NUMBER_OF_RETRIES) 825 | // { 826 | // printf("Temporarily killing http task"); 827 | // vTaskDelete(callThingsProcess_handle); 828 | // callThingsProcess_handle = NULL; 829 | // } 830 | if (failures>NUMBER_OF_RETRIES) 831 | { 832 | printf("Too many http failures. Temporarily killing http task\r\n"); 833 | taskHttp_delete(); 834 | } 835 | 836 | continue; 837 | } 838 | 839 | printf("... connected\r\n"); 840 | freeaddrinfo(res); 841 | 842 | char temp2[10]; 843 | snprintf(temp2, sizeof(temp2),"%2.2f", old_temperature_value ); 844 | printf("%s \n",temp2); 845 | printf(temp2); 846 | 847 | char hum1[6]; 848 | snprintf(hum1,sizeof(hum1), "%2.2f", old_humidity_value ); 849 | printf("%s \n",hum1 ); 850 | 851 | 852 | //char req[300]="GET " WEB_PATH API_KEY "&" FIELD1; 853 | char req[300]="GET " WEB_PATH; 854 | strncat(req,API_KEY,16); 855 | strncat(req,"&",2); 856 | strncat(req,FIELD1,20); 857 | strncat(req,temp2,10); 858 | strncat(req,"&",2); 859 | strncat(req,FIELD2,20); 860 | strncat(req,hum1,6); 861 | strncat(req," HTTP/1.1\r\nHost: "WEB_SERVER"\r\nUser-Agent: esp-open-rtos/0.1 esp8266\r\nConnection: close\r\n\r\n",250); 862 | 863 | 864 | printf("%s \n",req ); 865 | 866 | 867 | // printf("%s \n",req ); 868 | 869 | if (write(s, req, strlen(req)) < 0) { 870 | printf("... socket send failed\r\n"); 871 | close(s); 872 | vTaskDelay(4000 / portTICK_PERIOD_MS); 873 | failures++; 874 | if (failures>NUMBER_OF_RETRIES) 875 | { 876 | printf("Temporarily killing http task\n"); 877 | taskHttp_delete(); 878 | } 879 | continue; 880 | } 881 | printf("... socket send success\r\n"); 882 | 883 | static char recv_buf[128]; 884 | int r; 885 | do { 886 | bzero(recv_buf, 128); 887 | r = read(s, recv_buf, 127); 888 | if(r > 0) { 889 | printf("%s", recv_buf); 890 | } 891 | } while(r > 0); 892 | 893 | printf("... done reading from socket. Last read return=%d errno=%d\r\n", r, errno); 894 | 895 | 896 | if(r != 0) 897 | failures++; 898 | else 899 | successes++; 900 | close(s); 901 | printf("successes = %d failures = %d\r\n", successes, failures); 902 | printf("\r\nEnding!\r\n"); 903 | 904 | successes=0; 905 | failures =0; 906 | 907 | vTaskDelay(THINGSPEAK_INTERVAL / portTICK_PERIOD_MS); 908 | } 909 | else 910 | { 911 | vTaskDelay(60000 / portTICK_PERIOD_MS); 912 | } 913 | 914 | } 915 | } 916 | //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 917 | 918 | 919 | void identify_task(void *_args) { 920 | vTaskDelete(NULL); 921 | } 922 | 923 | void identify(homekit_value_t _value) { 924 | printf("identify\n"); 925 | xTaskCreate(identify_task, "identify", 128, NULL, 2, NULL); 926 | sensor_worker(); 927 | vTaskDelay(100 / portTICK_PERIOD_MS); 928 | } 929 | 930 | 931 | 932 | void led_write(bool on) { 933 | gpio_write(led_gpio, on ? 0 : 1); 934 | led_value = on; //Keep track of the status 935 | } 936 | 937 | 938 | void reset_configuration_task() { 939 | //Flash the LED first before we start the reset 940 | for (int i=0; i<3; i++) { 941 | led_write(true); 942 | vTaskDelay(100 / portTICK_PERIOD_MS); 943 | led_write(false); 944 | vTaskDelay(100 / portTICK_PERIOD_MS); 945 | } 946 | 947 | printf("Resetting Wifi Config\n"); 948 | wifi_config_reset(); 949 | vTaskDelay(1000 / portTICK_PERIOD_MS); 950 | printf("Resetting HomeKit Config\n"); 951 | homekit_server_reset(); 952 | vTaskDelay(1000 / portTICK_PERIOD_MS); 953 | printf("Restarting\n"); 954 | sdk_system_restart(); 955 | 956 | vTaskDelete(NULL); 957 | } 958 | 959 | void reset_configuration() { 960 | printf("Resetting Sonoff configuration\n"); 961 | xTaskCreate(reset_configuration_task, "Reset configuration", 256, NULL, 2, NULL); 962 | vTaskDelay(100 / portTICK_PERIOD_MS); 963 | } 964 | 965 | 966 | void sensor_worker() { 967 | //Temperature measurement 968 | float humidity_value, temperature_value; 969 | bool get_temp = false; 970 | 971 | get_temp = dht_read_float_data(DHT_TYPE_DHT22, SENSOR_PIN, &humidity_value, &temperature_value); 972 | if (get_temp) { 973 | // printf("RC >>> Sensor: temperature %g, humidity %g\n", temperature_value, humidity_value); 974 | 975 | if (temperature_value != old_temperature_value) { 976 | old_temperature_value = temperature_value; 977 | 978 | current_temperature.value = HOMEKIT_FLOAT(temperature_value); //Update AC current temp 979 | homekit_characteristic_notify(¤t_temperature, HOMEKIT_FLOAT(temperature_value)); 980 | 981 | temperature.value.float_value = temperature_value; 982 | homekit_characteristic_notify(&temperature, HOMEKIT_FLOAT(temperature_value)); 983 | } 984 | 985 | 986 | if (humidity_value != old_humidity_value) { 987 | old_humidity_value = humidity_value; 988 | humidity.value.float_value =humidity_value; 989 | //current_humidity.value = HOMEKIT_FLOAT(humidity_value); 990 | //homekit_characteristic_notify(¤t_humidity, current_humidity.value); 991 | homekit_characteristic_notify(&humidity, HOMEKIT_FLOAT(humidity_value)); 992 | } 993 | 994 | 995 | 996 | } else 997 | { 998 | printf("RC !!! ERROR Sensor\n"); 999 | 1000 | //led_code(LED_GPIO, SENSOR_ERROR); 1001 | 1002 | } 1003 | 1004 | //printf("Checking Light\n"); 1005 | //Light measurement 1006 | float light_value; 1007 | //light_value = sdk_system_adc_read(); 1008 | 1009 | //New version thanks to @Ravensystem and HAA 3.7.0, 5.0.4 1010 | light_value = light_sensor_task(); 1011 | 1012 | if (light_value != old_light_value) 1013 | { 1014 | old_light_value = light_value; 1015 | //currentAmbientLightLevel.value.float_value = (1024 - light_value); 1016 | //homekit_characteristic_notify(¤tAmbientLightLevel, HOMEKIT_FLOAT((1024 - light_value))); 1017 | currentAmbientLightLevel.value.float_value = ( light_value); 1018 | homekit_characteristic_notify(¤tAmbientLightLevel, HOMEKIT_FLOAT(( light_value))); 1019 | } 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | 1026 | } 1027 | 1028 | 1029 | void movement_detected_fn(const uint8_t gpio) { 1030 | printf("Movement detected\n"); 1031 | old_move_value = true; 1032 | motion_detected.value = HOMEKIT_BOOL(old_move_value); 1033 | //led_write(old_move_value); 1034 | led_status_signal(led_status, &three_short_blinks); 1035 | homekit_characteristic_notify(&motion_detected, HOMEKIT_BOOL(old_move_value)); 1036 | 1037 | } 1038 | 1039 | void movement_not_detected_fn(const uint8_t gpio) { 1040 | printf("Movement not detected\n"); 1041 | 1042 | old_move_value = false; 1043 | motion_detected.value = HOMEKIT_BOOL(old_move_value); 1044 | 1045 | homekit_characteristic_notify(&motion_detected, HOMEKIT_BOOL(old_move_value)); 1046 | } 1047 | 1048 | 1049 | 1050 | 1051 | void button_callback_single(const uint8_t gpio) { 1052 | 1053 | printf("Toggling relay\n"); 1054 | //led_write(!led_value); //A Single press will just toggle the LED. This was left for testing purposes. 1055 | //The following code is left commented in case we want to implement a single button for something else in homekit. 1056 | //switch_on.value.bool_value = !switch_on.value.bool_value; 1057 | //relay_write(switch_on.value.bool_value); 1058 | //homekit_characteristic_notify(&switch_on, switch_on.value); 1059 | 1060 | //http_get_task(1); 1061 | // xTaskCreate(http_get_task, "http", 256, NULL, 1, NULL); 1062 | //vTaskDelay(100 / portTICK_PERIOD_MS); 1063 | 1064 | } 1065 | 1066 | 1067 | void button_hold_callback(const uint8_t gpio) { 1068 | printf("Resetting Wifi\n"); 1069 | reset_configuration(); 1070 | 1071 | } 1072 | 1073 | void temperature_sensor_identify(homekit_value_t _value) { 1074 | printf("Temperature sensor identify\n"); 1075 | } 1076 | 1077 | void light_sensor_identify(homekit_value_t _value) { 1078 | printf("Light sensor identify\n"); 1079 | } 1080 | 1081 | 1082 | 1083 | 1084 | homekit_accessory_t *accessories[] = { 1085 | HOMEKIT_ACCESSORY(.id=1, .category=homekit_accessory_category_thermostat, .services=(homekit_service_t*[]) { 1086 | HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t*[]) { 1087 | &name, 1088 | &manufacturer, 1089 | &serial, 1090 | &model, 1091 | &revision, 1092 | HOMEKIT_CHARACTERISTIC(IDENTIFY, temperature_sensor_identify), 1093 | NULL 1094 | }), 1095 | HOMEKIT_SERVICE(HEATER_COOLER, .primary=true, .characteristics=(homekit_characteristic_t*[]) { 1096 | HOMEKIT_CHARACTERISTIC(NAME, "AirConditioner"), 1097 | &active, 1098 | ¤t_temperature, 1099 | //&target_temperature, 1100 | ¤t_heater_cooler_state, 1101 | &target_heater_cooler_state, 1102 | &cooling_threshold, 1103 | &heating_threshold, 1104 | // &units, 1105 | // &rotation_speed, 1106 | &ota_trigger, 1107 | NULL 1108 | }), 1109 | NULL 1110 | }), 1111 | HOMEKIT_ACCESSORY( .category=homekit_accessory_category_sensor, .services=(homekit_service_t*[]){ 1112 | HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t*[]){ 1113 | &name, 1114 | &manufacturer, 1115 | &serial, 1116 | &model, 1117 | &revision, 1118 | HOMEKIT_CHARACTERISTIC(IDENTIFY, temperature_sensor_identify), 1119 | NULL 1120 | }), 1121 | HOMEKIT_SERVICE(MOTION_SENSOR, .primary=true, .characteristics=(homekit_characteristic_t*[]){ 1122 | HOMEKIT_CHARACTERISTIC(NAME, "Motion Sensor"), 1123 | &motion_detected, 1124 | NULL 1125 | }), 1126 | 1127 | HOMEKIT_SERVICE(TEMPERATURE_SENSOR, .primary=true, .characteristics=(homekit_characteristic_t*[]) { 1128 | HOMEKIT_CHARACTERISTIC(NAME, "Temperature Sensor"), 1129 | &temperature, 1130 | NULL 1131 | }), 1132 | HOMEKIT_SERVICE(LIGHT_SENSOR, .primary=true, .characteristics=(homekit_characteristic_t*[]){ 1133 | HOMEKIT_CHARACTERISTIC(NAME, "Light Sensor"), 1134 | ¤tAmbientLightLevel, 1135 | NULL 1136 | }), 1137 | 1138 | HOMEKIT_SERVICE(HUMIDITY_SENSOR, .characteristics=(homekit_characteristic_t*[]) { 1139 | HOMEKIT_CHARACTERISTIC(NAME, "Humidity Sensor"), 1140 | &humidity, 1141 | NULL 1142 | }), 1143 | NULL 1144 | }), 1145 | NULL 1146 | 1147 | }; 1148 | 1149 | int event_counter =0; 1150 | void on_event(homekit_event_t event) { 1151 | paired = homekit_is_paired(); 1152 | event_counter+=1; 1153 | 1154 | if ((!paired && event_counter>15) || paired){ 1155 | if (extra_http_TaskStarted == false){ 1156 | extra_http_TaskStarted = true; 1157 | xTaskCreate(&httpd_task, "http_server", 1024, NULL, tskIDLE_PRIORITY+2, NULL); 1158 | printf("\n\nSTARTING HTTP SEVER . . . \n\n"); 1159 | } 1160 | } 1161 | 1162 | 1163 | if (event == HOMEKIT_EVENT_SERVER_INITIALIZED) { 1164 | led_status_set(led_status, paired ? NULL : &unpaired); 1165 | printf("SERVER JUST INITIALIZED\n"); 1166 | 1167 | if (paired == true){ 1168 | //led_status_set(led_status, NULL); 1169 | 1170 | if (USE_THINGSPEAK == true && !Http_TaskStarted){ 1171 | //Start the ThingsSpeak process 1172 | FREEHEAP(); 1173 | if (xPortGetFreeHeapSize()>8000){ 1174 | printf("http task started\n"); 1175 | xTaskCreate(call_things_process, "http", 1024, NULL, 1, &callThingsProcess_handle); 1176 | Http_TaskStarted=true; 1177 | } 1178 | } 1179 | 1180 | if (extra_function_TaskStarted ==false) 1181 | { 1182 | if (sdk_wifi_station_get_connect_status() == STATION_GOT_IP) { 1183 | UDPLOG_PRINTF_TO_UDP; 1184 | //UDPLOG_PRINTF_ALSO_SERIAL; 1185 | //udplog_init(3); 1186 | udplog_init(tskIDLE_PRIORITY+1); 1187 | printf("Started UDP logging1\n"); 1188 | 1189 | printf("Found pairing, starting timers\n"); 1190 | sdk_os_timer_setfn(&extra_func_timer, sensor_worker, NULL); 1191 | //sdk_os_timer_disarm(&extra_func_timer); 1192 | sdk_os_timer_arm(&extra_func_timer, 10000, 1); 1193 | extra_function_TaskStarted=true; 1194 | 1195 | adv_toggle_create(motion_sensor_gpio, false); // false -> without internal pull-up resistor 1196 | adv_toggle_register_callback_fn(motion_sensor_gpio, movement_detected_fn, 1); // High gpio state 1197 | adv_toggle_register_callback_fn(motion_sensor_gpio, movement_not_detected_fn, 0); // Low gpio state 1198 | 1199 | } 1200 | } 1201 | 1202 | if (param_started == false){ 1203 | int_ac_state(); 1204 | param_started=true; 1205 | } 1206 | } 1207 | 1208 | 1209 | } 1210 | else if (event == HOMEKIT_EVENT_CLIENT_CONNECTED) { 1211 | if (!paired){ 1212 | led_status_set(led_status, &pairing_started); 1213 | } 1214 | else 1215 | { 1216 | led_status_set(led_status, NULL); 1217 | } 1218 | 1219 | printf("CLIENT JUST CONNECTED\n"); 1220 | 1221 | 1222 | } 1223 | else if (event == HOMEKIT_EVENT_CLIENT_DISCONNECTED) { 1224 | if (!paired){ 1225 | led_status_set(led_status, &unpaired); 1226 | 1227 | }else 1228 | { 1229 | //Τhis is where I start secondart tasks. The pairing has already been completed and a first client disconnection has happened. 1230 | //if (extra_http_TaskStarted == false){ 1231 | // extra_http_TaskStarted = true; 1232 | // xTaskCreate(&httpd_task, "http_server", 1024, NULL, tskIDLE_PRIORITY+2, NULL); 1233 | // } 1234 | } 1235 | 1236 | printf("CLIENT JUST DISCONNECTED\n"); 1237 | 1238 | } 1239 | else if (event == HOMEKIT_EVENT_CLIENT_VERIFIED) { 1240 | printf("CLIENT JUST VERIFIED\n"); 1241 | if (paired == true) 1242 | { 1243 | if (extra_http_TaskStarted == false){ 1244 | extra_http_TaskStarted = true; 1245 | xTaskCreate(&httpd_task, "http_server", 1024, NULL, tskIDLE_PRIORITY+2, NULL); 1246 | } 1247 | 1248 | led_status_set(led_status, NULL); 1249 | if (callThingsProcess_handle == NULL) 1250 | { 1251 | //printf("The CALL PROCESS IS NOT NULL\n"); 1252 | printf("\n\n\n\n\n\n\nHTTP FLAG IS %d\n\n\n\n\n\n\n\n",(int)Http_TaskStarted); 1253 | if (USE_THINGSPEAK == true && !Http_TaskStarted){ 1254 | //Start the ThingsSpeak process 1255 | FREEHEAP(); 1256 | if (xPortGetFreeHeapSize()>8000){ 1257 | printf("http task started\n"); 1258 | xTaskCreate(call_things_process, "http", 1024, NULL, 1, &callThingsProcess_handle); 1259 | Http_TaskStarted=true; 1260 | } 1261 | } 1262 | } 1263 | if (extra_function_TaskStarted ==false) 1264 | { 1265 | if (sdk_wifi_station_get_connect_status() == STATION_GOT_IP) { 1266 | UDPLOG_PRINTF_TO_UDP; 1267 | //UDPLOG_PRINTF_ALSO_SERIAL; 1268 | //udplog_init(3); 1269 | udplog_init(tskIDLE_PRIORITY+1); 1270 | printf("Started UDP logging2\n"); 1271 | 1272 | printf("Found pairing, starting timers\n"); 1273 | sdk_os_timer_setfn(&extra_func_timer, sensor_worker, NULL); 1274 | //sdk_os_timer_disarm(&extra_func_timer); 1275 | sdk_os_timer_arm(&extra_func_timer, 10000, 1); 1276 | extra_function_TaskStarted=true; 1277 | 1278 | adv_toggle_create(motion_sensor_gpio, false); // false -> without internal pull-up resistor 1279 | adv_toggle_register_callback_fn(motion_sensor_gpio, movement_detected_fn, 1); // High gpio state 1280 | adv_toggle_register_callback_fn(motion_sensor_gpio, movement_not_detected_fn, 0); // Low gpio state 1281 | } 1282 | } 1283 | 1284 | if (param_started == false){ 1285 | int_ac_state(); 1286 | param_started=true; 1287 | } 1288 | 1289 | 1290 | } 1291 | 1292 | 1293 | } 1294 | else if (event == HOMEKIT_EVENT_PAIRING_ADDED || event == HOMEKIT_EVENT_PAIRING_REMOVED) { 1295 | paired = homekit_is_paired(); 1296 | led_status_set(led_status, paired ? NULL : &unpaired); 1297 | printf("CLIENT JUST PAIRED\n"); 1298 | 1299 | if (!paired){ 1300 | printf("CLIENT LOST PAIRING - REBOOT\n"); 1301 | vTaskDelay(1000 / portTICK_PERIOD_MS); 1302 | sdk_system_restart(); 1303 | } 1304 | // if (USE_THINGSPEAK == 1){ 1305 | // if (TaskStarted == false){ 1306 | // //Start the ThingsSpeak process only if relevant flag is set 1307 | // printf("http task started\n"); 1308 | // xTaskCreate(call_things_process, "http", 1024, NULL, 1, NULL); 1309 | // TaskStarted=true; 1310 | // } 1311 | // } 1312 | 1313 | // sdk_os_timer_arm(&extra_func_timer, 10000, 1); 1314 | 1315 | // adv_toggle_create(motion_sensor_gpio, false); // false -> without internal pull-up resistor 1316 | // adv_toggle_register_callback_fn(motion_sensor_gpio, movement_detected_fn, 1); // High gpio state 1317 | // adv_toggle_register_callback_fn(motion_sensor_gpio, movement_not_detected_fn, 0); // Low gpio state 1318 | 1319 | 1320 | // adv_button_create(button_gpio, true); 1321 | // adv_button_register_callback_fn(button_gpio, button_callback_single, 1); 1322 | // adv_button_register_callback_fn(button_gpio, button_hold_callback, 5); 1323 | } 1324 | } 1325 | 1326 | void taskHttp_delete() 1327 | { 1328 | TaskHandle_t xTask = callThingsProcess_handle; 1329 | Http_TaskStarted = false; 1330 | //vTaskSuspendAll(); 1331 | if( callThingsProcess_handle != NULL ) 1332 | { 1333 | /* The task is going to be deleted. 1334 | Set the handle to NULL. */ 1335 | callThingsProcess_handle = NULL; 1336 | /* Delete using the copy of the handle. */ 1337 | vTaskDelete( xTask ); 1338 | } 1339 | //xTaskResumeAll(); 1340 | } 1341 | 1342 | 1343 | void create_accessory_name() { 1344 | uint8_t macaddr[6]; 1345 | sdk_wifi_get_macaddr(STATION_IF, macaddr); 1346 | 1347 | int name_len = snprintf(NULL, 0, "HomekitSensor-%02X%02X%02X", 1348 | macaddr[3], macaddr[4], macaddr[5]); 1349 | char *name_value = malloc(name_len+1); 1350 | snprintf(name_value, name_len+1, "HomekitSensor-%02X%02X%02X", 1351 | macaddr[3], macaddr[4], macaddr[5]); 1352 | 1353 | name.value = HOMEKIT_STRING(name_value); 1354 | 1355 | 1356 | snprintf(serial_value, 13, "%02X%02X%02X%02X%02X%02X", macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]); 1357 | 1358 | } 1359 | 1360 | homekit_server_config_t config = { 1361 | .accessories = accessories, 1362 | .password = "222-22-222", 1363 | .on_event = on_event, 1364 | }; 1365 | 1366 | void on_wifi_event(wifi_config_event_t event) { 1367 | 1368 | 1369 | if (event == WIFI_CONFIG_CONNECTED) 1370 | { 1371 | printf("CONNECTED TO >>> WIFI <<<\n"); 1372 | //led_status_signal(led_status, &three_short_blinks); //This seemed like needed, otherwise the library does not work well. 1373 | led_status_set(led_status, NULL); 1374 | 1375 | //led_status_set(led_status,NULL); 1376 | Wifi_Connected=true; 1377 | 1378 | create_accessory_name(); 1379 | // if (homekit_is_paired()){ 1380 | // char *custom_hostname = name.value.string_value; 1381 | // struct netif *netif = sdk_system_get_netif(STATION_IF); 1382 | // if (netif) { 1383 | // printf("HOSTNAME set>>>>>:%s\n", custom_hostname); 1384 | // LOCK_TCPIP_CORE(); 1385 | // dhcp_release_and_stop(netif); 1386 | // netif->hostname = "foobar"; 1387 | // netif->hostname =custom_hostname; 1388 | // dhcp_start(netif); 1389 | // UNLOCK_TCPIP_CORE(); 1390 | // } 1391 | // } 1392 | //OTA 1393 | int c_hash=ota_read_sysparam(&manufacturer.value.string_value,&serial.value.string_value, 1394 | &model.value.string_value,&revision.value.string_value); 1395 | 1396 | 1397 | c_hash=1; revision.value.string_value="0.0.1"; //cheat line 1398 | config.accessories[0]->config_number=c_hash; 1399 | 1400 | 1401 | 1402 | homekit_server_init(&config); 1403 | FREEHEAP(); 1404 | } 1405 | else if (event == WIFI_CONFIG_DISCONNECTED) 1406 | { 1407 | Wifi_Connected = false; 1408 | printf("DISCONNECTED FROM >>> WIFI <<<\n"); 1409 | led_status_set(led_status,&waiting_wifi); 1410 | } 1411 | } 1412 | 1413 | 1414 | 1415 | void hardware_init() { 1416 | gpio_enable(led_gpio, GPIO_OUTPUT); 1417 | // led_write(true); 1418 | 1419 | gpio_set_pullup(SENSOR_PIN, false, false); 1420 | gpio_set_pullup(IR_PIN, false, false); 1421 | 1422 | // IR Common initialization (can be done only once) 1423 | ir_tx_init(); 1424 | 1425 | adv_button_create(button_gpio, true); 1426 | adv_button_register_callback_fn(button_gpio, button_callback_single, 1); 1427 | adv_button_register_callback_fn(button_gpio, button_hold_callback, 2); 1428 | 1429 | led_status = led_status_init(STATUS_LED_PIN, 0); 1430 | 1431 | 1432 | 1433 | } 1434 | 1435 | 1436 | void user_init(void) { 1437 | uart_set_baud(0, 115200); 1438 | printf("SDK version:%s\n", sdk_system_get_sdk_version()); 1439 | hardware_init(); 1440 | 1441 | 1442 | 1443 | //wifi_config_init("Homekit-sensor", NULL, on_wifi_ready); 1444 | wifi_config_init2("Homekit-Sensor", NULL, on_wifi_event); 1445 | 1446 | } 1447 | -------------------------------------------------------------------------------- /examples/multiple_sensors_ac/ota-api.c: -------------------------------------------------------------------------------- 1 | #include //for printf 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | // the first function is the ONLY thing needed for a repo to support ota after having started with ota-boot 11 | // in ota-boot the user gets to set the wifi and the repository details and it then installs the ota-main binary 12 | 13 | void ota_update(void *arg) { //arg not used 14 | rboot_set_temp_rom(1); //select the OTA main routine 15 | sdk_system_restart(); //#include 16 | // there is a bug in the esp SDK such that if you do not power cycle the chip after serial flashing, restart is unreliable 17 | } 18 | 19 | // this function is optional to couple Homekit parameters to the sysparam variables and github parameters 20 | unsigned int ota_read_sysparam(char **manufacturer,char **serial,char **model,char **revision) { 21 | sysparam_status_t status; 22 | char *value; 23 | 24 | status = sysparam_get_string("ota_repo", &value); 25 | if (status == SYSPARAM_OK) { 26 | strchr(value,'/')[0]=0; 27 | *manufacturer=value; 28 | *model=value+strlen(value)+1; 29 | } else { 30 | *manufacturer="manuf_unknown"; 31 | *model="model_unknown"; 32 | } 33 | status = sysparam_get_string("ota_version", &value); 34 | if (status == SYSPARAM_OK) { 35 | *revision=value; 36 | } else *revision="0.0.0"; 37 | 38 | uint8_t macaddr[6]; 39 | sdk_wifi_get_macaddr(STATION_IF, macaddr); 40 | *serial=malloc(18); 41 | sprintf(*serial,"%02X:%02X:%02X:%02X:%02X:%02X",macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]); 42 | 43 | unsigned int c_hash=0; 44 | char version[16]; 45 | char* rev=version; 46 | char* dot; 47 | strncpy(rev,*revision,16); 48 | if ((dot=strchr(rev,'.'))) {dot[0]=0; c_hash= atoi(rev); rev=dot+1;} 49 | if ((dot=strchr(rev,'.'))) {dot[0]=0; c_hash=c_hash*1000+atoi(rev); rev=dot+1;} 50 | c_hash=c_hash*1000+atoi(rev); 51 | //c_hash=c_hash*10 +configuration_variant; //possible future extension 52 | printf("manuf=\'%s\' serial=\'%s\' model=\'%s\' revision=\'%s\' c#=%d\n",*manufacturer,*serial,*model,*revision,c_hash); 53 | return c_hash; 54 | } 55 | 56 | 57 | 58 | 59 | #include 60 | #include 61 | #include 62 | 63 | static ETSTimer update_timer; 64 | 65 | void ota_set(homekit_value_t value) { 66 | if (value.format != homekit_format_bool) { 67 | printf("Invalid ota-value format: %d\n", value.format); 68 | return; 69 | } 70 | if (value.bool_value) { 71 | //make a distinct light pattern or other feedback to the user = call identify routine 72 | sdk_os_timer_setfn(&update_timer, ota_update, NULL); 73 | sdk_os_timer_arm(&update_timer, 500, 0); //wait 0.5 seconds to trigger the reboot so gui can update and events sent 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /examples/multiple_sensors_ac/ota-api.h: -------------------------------------------------------------------------------- 1 | #ifndef __HOMEKIT_CUSTOM_CHARACTERISTICS__ 2 | #define __HOMEKIT_CUSTOM_CHARACTERISTICS__ 3 | 4 | #define HOMEKIT_CUSTOM_UUID(value) (value "-0e36-4a42-ad11-745a73b84f2b") 5 | 6 | #define HOMEKIT_SERVICE_CUSTOM_SETUP HOMEKIT_CUSTOM_UUID("000000FF") 7 | 8 | #define HOMEKIT_CHARACTERISTIC_CUSTOM_OTA_TRIGGER HOMEKIT_CUSTOM_UUID("F0000001") 9 | #define HOMEKIT_DECLARE_CHARACTERISTIC_CUSTOM_OTA_TRIGGER(_value, ...) \ 10 | .type = HOMEKIT_CHARACTERISTIC_CUSTOM_OTA_TRIGGER, \ 11 | .description = "}FirmwareUpdate", \ 12 | .format = homekit_format_bool, \ 13 | .permissions = homekit_permissions_paired_read \ 14 | | homekit_permissions_paired_write \ 15 | | homekit_permissions_notify, \ 16 | .value = HOMEKIT_BOOL_(_value), \ 17 | ##__VA_ARGS__ 18 | 19 | unsigned int ota_read_sysparam(char **manufacturer,char **serial,char **model,char **revision); 20 | 21 | void ota_update(void *arg); 22 | 23 | void ota_set(homekit_value_t value); 24 | 25 | #define API_OTA_TRIGGER HOMEKIT_CHARACTERISTIC_(CUSTOM_OTA_TRIGGER, false, .setter=ota_set) 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /lib/adv_button/Makefile: -------------------------------------------------------------------------------- 1 | PROGRAM = adv_button 2 | 3 | FLASH_SIZE = 8 4 | FLASH_MODE = dout 5 | FLASH_SPEED = 40 6 | 7 | EXTRA_CFLAGS += -I../.. 8 | 9 | include $(abspath ../../sdk/esp-open-rtos/common.mk) 10 | 11 | monitor: 12 | $(FILTEROUTPUT) --port $(ESPPORT) --baud 115200 --elf $(PROGRAM_OUT) 13 | -------------------------------------------------------------------------------- /lib/adv_button/adv_button.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Advanced Button Manager 3 | * 4 | * Copyright 2018 José A. Jiménez (@RavenSystem) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | /* 20 | * Based on Button library by Maxim Kulkin (@MaximKulkin), licensed under the MIT License. 21 | * https://github.com/maximkulkin/esp-homekit-demo/blob/master/examples/button/button.c 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include "adv_button.h" 28 | 29 | #define DEBOUNCE_TIME 40 30 | #define DISABLE_TIME 80 31 | #define DOUBLEPRESS_TIME 400 32 | #define LONGPRESS_TIME 450 33 | #define VERYLONGPRESS_TIME 1200 34 | #define HOLDPRESS_COUNT 5 // HOLDPRESS_TIME = HOLDPRESS_COUNT * 2000 35 | #define TOGGLE_EVALUATE_INTERVAL 25 36 | 37 | typedef struct _adv_button { 38 | uint8_t gpio; 39 | 40 | button_callback_fn singlepress_callback_fn; 41 | button_callback_fn doublepress_callback_fn; 42 | button_callback_fn longpress_callback_fn; 43 | button_callback_fn verylongpress_callback_fn; 44 | button_callback_fn holdpress_callback_fn; 45 | 46 | bool is_down; 47 | uint8_t press_count; 48 | uint8_t hold_count; 49 | ETSTimer press_timer; 50 | ETSTimer hold_timer; 51 | volatile uint32_t last_event_time; 52 | 53 | struct _adv_button *next; 54 | } adv_button_t; 55 | 56 | typedef struct _adv_toggle { 57 | uint8_t gpio; 58 | 59 | button_callback_fn low_callback_fn; 60 | button_callback_fn high_callback_fn; 61 | button_callback_fn both_callback_fn; 62 | 63 | bool state; 64 | bool old_state; 65 | volatile uint16_t value; 66 | 67 | struct _adv_toggle *next; 68 | } adv_toggle_t; 69 | 70 | static adv_button_t *buttons = NULL; 71 | static adv_toggle_t *toggles = NULL; 72 | static uint8_t used_gpio; 73 | static uint32_t disable_time = 0; 74 | static ETSTimer push_down_timer, push_up_timer, toggle_evaluate; 75 | 76 | static adv_button_t *button_find_by_gpio(const uint8_t gpio) { 77 | adv_button_t *button = buttons; 78 | 79 | while (button && button->gpio != gpio) { 80 | button = button->next; 81 | } 82 | 83 | return button; 84 | } 85 | 86 | static adv_toggle_t *toggle_find_by_gpio(const uint8_t gpio) { 87 | adv_toggle_t *toggle = toggles; 88 | 89 | while (toggle && toggle->gpio != gpio) { 90 | toggle = toggle->next; 91 | } 92 | 93 | return toggle; 94 | } 95 | 96 | IRAM void adv_button_set_disable_time() { 97 | disable_time = xTaskGetTickCountFromISR(); 98 | } 99 | 100 | IRAM static void push_down_timer_callback() { 101 | sdk_os_timer_disarm(&push_down_timer); 102 | 103 | const uint32_t now = xTaskGetTickCountFromISR(); 104 | 105 | if (now - disable_time > DISABLE_TIME / portTICK_PERIOD_MS) { 106 | if (gpio_read(used_gpio) == 0) { 107 | adv_button_t *button = button_find_by_gpio(used_gpio); 108 | sdk_os_timer_arm(&button->hold_timer, 2000, 1); 109 | button->hold_count = 0; 110 | button->last_event_time = now; 111 | button->is_down = true; 112 | } 113 | } 114 | } 115 | 116 | IRAM static void push_up_timer_callback() { 117 | sdk_os_timer_disarm(&push_up_timer); 118 | 119 | const uint32_t now = xTaskGetTickCountFromISR(); 120 | 121 | if (now - disable_time > DISABLE_TIME / portTICK_PERIOD_MS) { 122 | adv_button_t *button = button_find_by_gpio(used_gpio); 123 | if (gpio_read(used_gpio) == 1 && button->is_down) { 124 | sdk_os_timer_disarm(&button->hold_timer); 125 | button->is_down = false; 126 | button->hold_count = 0; 127 | 128 | if (now - button->last_event_time > VERYLONGPRESS_TIME / portTICK_PERIOD_MS) { 129 | // Very Long button pressed 130 | button->press_count = 0; 131 | if (button->verylongpress_callback_fn) { 132 | button->verylongpress_callback_fn(used_gpio); 133 | } else if (button->longpress_callback_fn) { 134 | button->longpress_callback_fn(used_gpio); 135 | } else { 136 | button->singlepress_callback_fn(used_gpio); 137 | } 138 | } else if (now - button->last_event_time > LONGPRESS_TIME / portTICK_PERIOD_MS) { 139 | // Long button pressed 140 | button->press_count = 0; 141 | if (button->longpress_callback_fn) { 142 | button->longpress_callback_fn(used_gpio); 143 | } else { 144 | button->singlepress_callback_fn(used_gpio); 145 | } 146 | } else if (button->doublepress_callback_fn) { 147 | button->press_count++; 148 | if (button->press_count > 1) { 149 | // Double button pressed 150 | sdk_os_timer_disarm(&button->press_timer); 151 | button->press_count = 0; 152 | button->doublepress_callback_fn(used_gpio); 153 | } else { 154 | sdk_os_timer_arm(&button->press_timer, DOUBLEPRESS_TIME, 0); 155 | } 156 | } else { 157 | button->singlepress_callback_fn(used_gpio); 158 | } 159 | } 160 | } 161 | } 162 | 163 | IRAM static void adv_button_intr_callback(const uint8_t gpio) { 164 | used_gpio = gpio; 165 | 166 | if (gpio_read(used_gpio) == 1) { 167 | sdk_os_timer_arm(&push_up_timer, DEBOUNCE_TIME, 0); 168 | } else { 169 | sdk_os_timer_arm(&push_down_timer, DEBOUNCE_TIME, 0); 170 | } 171 | } 172 | 173 | static void no_function_callback(uint8_t gpio) { 174 | printf("!!! AdvButton: No function defined\n"); 175 | } 176 | 177 | static void adv_button_single_callback(void *arg) { 178 | adv_button_t *button = arg; 179 | // Single button pressed 180 | button->press_count = 0; 181 | button->singlepress_callback_fn(button->gpio); 182 | } 183 | 184 | static void adv_button_hold_callback(void *arg) { 185 | adv_button_t *button = arg; 186 | 187 | // Hold button pressed 188 | if (gpio_read(button->gpio) == 0) { 189 | button->hold_count++; 190 | 191 | if (button->hold_count == HOLDPRESS_COUNT) { 192 | sdk_os_timer_disarm(&button->hold_timer); 193 | button->hold_count = 0; 194 | button->press_count = 0; 195 | if (button->holdpress_callback_fn) { 196 | button->holdpress_callback_fn(button->gpio); 197 | } else { 198 | no_function_callback(button->gpio); 199 | } 200 | 201 | adv_button_set_disable_time(); 202 | } 203 | } else { 204 | sdk_os_timer_disarm(&button->hold_timer); 205 | button->hold_count = 0; 206 | } 207 | } 208 | 209 | int adv_button_create(const uint8_t gpio, bool pullup_resistor) { 210 | adv_button_t *button = button_find_by_gpio(gpio); 211 | adv_toggle_t *toggle = toggle_find_by_gpio(gpio); 212 | 213 | if (!button && !toggle) { 214 | button = malloc(sizeof(adv_button_t)); 215 | memset(button, 0, sizeof(*button)); 216 | button->gpio = gpio; 217 | 218 | if (!buttons) { 219 | sdk_os_timer_disarm(&push_down_timer); 220 | sdk_os_timer_setfn(&push_down_timer, push_down_timer_callback, NULL); 221 | sdk_os_timer_disarm(&push_up_timer); 222 | sdk_os_timer_setfn(&push_up_timer, push_up_timer_callback, NULL); 223 | } 224 | 225 | button->next = buttons; 226 | buttons = button; 227 | 228 | button->is_down = false; 229 | button->hold_count = 0; 230 | button->press_count = 0; 231 | 232 | if (button->gpio != 0) { 233 | gpio_enable(button->gpio, GPIO_INPUT); 234 | } 235 | 236 | gpio_set_pullup(button->gpio, pullup_resistor, pullup_resistor); 237 | gpio_set_interrupt(button->gpio, GPIO_INTTYPE_EDGE_ANY, adv_button_intr_callback); 238 | 239 | sdk_os_timer_disarm(&button->hold_timer); 240 | sdk_os_timer_setfn(&button->hold_timer, adv_button_hold_callback, button); 241 | sdk_os_timer_disarm(&button->press_timer); 242 | sdk_os_timer_setfn(&button->press_timer, adv_button_single_callback, button); 243 | 244 | button->singlepress_callback_fn = no_function_callback; 245 | 246 | return 0; 247 | } 248 | 249 | return -1; 250 | } 251 | 252 | #define maxvalue_unsigned(x) ((1 << (8 * sizeof(x))) - 1) 253 | IRAM static void toggle_evaluate_fn() { // Based on https://github.com/pcsaito/esp-homekit-demo/blob/LPFToggle/examples/sonoff_basic_toggle/toggle.c 254 | adv_toggle_t *toggle = toggles; 255 | 256 | while (toggle) { 257 | toggle->value += ((gpio_read(toggle->gpio) * maxvalue_unsigned(toggle->value)) - toggle->value) >> 3; 258 | toggle->state = (toggle->value > (maxvalue_unsigned(toggle->value) >> 1)); 259 | 260 | if (toggle->state != toggle->old_state) { 261 | toggle->old_state = toggle->state; 262 | 263 | if (toggle->both_callback_fn) { 264 | toggle->both_callback_fn(toggle->gpio); 265 | } 266 | 267 | if (gpio_read(toggle->gpio)) { 268 | if (toggle->high_callback_fn) { 269 | toggle->high_callback_fn(toggle->gpio); 270 | } 271 | } else { 272 | if (toggle->low_callback_fn) { 273 | toggle->low_callback_fn(toggle->gpio); 274 | } 275 | } 276 | 277 | } 278 | 279 | toggle = toggle->next; 280 | } 281 | } 282 | 283 | int adv_toggle_create(const uint8_t gpio, bool pullup_resistor) { 284 | adv_button_t *button = button_find_by_gpio(gpio); 285 | adv_toggle_t *toggle = toggle_find_by_gpio(gpio); 286 | 287 | if (!button && !toggle) { 288 | toggle = malloc(sizeof(adv_toggle_t)); 289 | memset(toggle, 0, sizeof(*toggle)); 290 | toggle->gpio = gpio; 291 | 292 | if (!toggles) { 293 | sdk_os_timer_disarm(&toggle_evaluate); 294 | sdk_os_timer_setfn(&toggle_evaluate, toggle_evaluate_fn, NULL); 295 | sdk_os_timer_arm(&toggle_evaluate, TOGGLE_EVALUATE_INTERVAL, 1); 296 | } 297 | 298 | toggle->next = toggles; 299 | toggles = toggle; 300 | 301 | if (toggle->gpio != 0) { 302 | gpio_enable(toggle->gpio, GPIO_INPUT); 303 | } 304 | 305 | gpio_set_pullup(toggle->gpio, pullup_resistor, pullup_resistor); 306 | 307 | toggle->state = gpio_read(toggle->gpio); 308 | 309 | toggle->old_state = toggle->state; 310 | toggle->value = 32764; 311 | 312 | return 0; 313 | } 314 | 315 | return -1; 316 | } 317 | 318 | int adv_button_register_callback_fn(const uint8_t gpio, button_callback_fn callback, const uint8_t button_callback_type) { 319 | adv_button_t *button = button_find_by_gpio(gpio); 320 | 321 | if (button) { 322 | switch (button_callback_type) { 323 | case 1: 324 | if (callback) { 325 | button->singlepress_callback_fn = callback; 326 | } else { 327 | button->singlepress_callback_fn = no_function_callback; 328 | } 329 | break; 330 | 331 | case 2: 332 | button->doublepress_callback_fn = callback; 333 | break; 334 | 335 | case 3: 336 | button->longpress_callback_fn = callback; 337 | break; 338 | 339 | case 4: 340 | button->verylongpress_callback_fn = callback; 341 | break; 342 | 343 | case 5: 344 | button->holdpress_callback_fn = callback; 345 | break; 346 | 347 | default: 348 | return -2; 349 | break; 350 | } 351 | 352 | return 0; 353 | } 354 | 355 | return -1; 356 | } 357 | 358 | int adv_toggle_register_callback_fn(const uint8_t gpio, button_callback_fn callback, const uint8_t toggle_callback_type) { 359 | adv_toggle_t *toggle = toggle_find_by_gpio(gpio); 360 | 361 | if (toggle) { 362 | switch (toggle_callback_type) { 363 | case 0: 364 | toggle->low_callback_fn = callback; 365 | break; 366 | 367 | case 1: 368 | toggle->high_callback_fn = callback; 369 | break; 370 | 371 | case 2: 372 | toggle->both_callback_fn = callback; 373 | break; 374 | 375 | default: 376 | return -2; 377 | break; 378 | } 379 | 380 | return 0; 381 | } 382 | 383 | return -1; 384 | } 385 | 386 | void adv_button_destroy(const uint8_t gpio) { 387 | if (buttons) { 388 | adv_button_t *button = NULL; 389 | if (buttons->gpio == gpio) { 390 | button = buttons; 391 | buttons = buttons->next; 392 | } else { 393 | adv_button_t *b = buttons; 394 | while (b->next) { 395 | if (b->next->gpio == gpio) { 396 | button = b->next; 397 | b->next = b->next->next; 398 | break; 399 | } 400 | } 401 | } 402 | 403 | if (button) { 404 | sdk_os_timer_disarm(&button->hold_timer); 405 | sdk_os_timer_disarm(&button->press_timer); 406 | gpio_set_interrupt(button->gpio, GPIO_INTTYPE_EDGE_ANY, NULL); 407 | if (button->gpio != 0) { 408 | gpio_disable(button->gpio); 409 | } 410 | } 411 | } 412 | } 413 | 414 | void adv_toggle_destroy(const uint8_t gpio) { 415 | if (toggles) { 416 | adv_toggle_t *toggle = NULL; 417 | if (toggles->gpio == gpio) { 418 | toggle = toggles; 419 | toggles = toggles->next; 420 | } else { 421 | adv_toggle_t *b = toggles; 422 | while (b->next) { 423 | if (b->next->gpio == gpio) { 424 | toggle = b->next; 425 | b->next = b->next->next; 426 | break; 427 | } 428 | } 429 | } 430 | 431 | if (toggle) { 432 | if (toggle->gpio != 0) { 433 | gpio_disable(toggle->gpio); 434 | } 435 | } 436 | 437 | if (!toggles) { 438 | sdk_os_timer_disarm(&toggle_evaluate); 439 | } 440 | } 441 | } 442 | -------------------------------------------------------------------------------- /lib/adv_button/adv_button.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Advanced Button Manager 3 | * 4 | * Copyright 2018 José A. Jiménez (@RavenSystem) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | /* 20 | * Based on Button library by Maxim Kulkin (@MaximKulkin), licensed under the MIT License. 21 | * https://github.com/maximkulkin/esp-homekit-demo/blob/master/examples/button/button.c 22 | */ 23 | 24 | #ifndef __ADVANCED_BUTTON__ 25 | #define __ADVANCED_BUTTON__ 26 | 27 | typedef void (*button_callback_fn)(uint8_t gpio); 28 | 29 | int adv_button_create(uint8_t gpio, bool pullup_resistor); 30 | void adv_button_destroy(uint8_t gpio); 31 | void adv_button_set_disable_time(); 32 | 33 | int adv_toggle_create(uint8_t gpio, bool pullup_resistor); 34 | void adv_toggle_destroy(uint8_t gpio); 35 | 36 | /* 37 | * Button callback types: 38 | * 1 Single press 39 | * 2 Double press 40 | * 3 Long press 41 | * 4 Very long press 42 | * 5 Hold press 43 | */ 44 | int adv_button_register_callback_fn(uint8_t gpio, button_callback_fn callback, uint8_t button_callback_type); 45 | 46 | /* 47 | * Toggle callback types: 48 | * 0 Low 49 | * 1 High 50 | * 2 Both 51 | */ 52 | int adv_toggle_register_callback_fn(uint8_t gpio, button_callback_fn callback, uint8_t toggle_callback_type); 53 | 54 | #endif // __ADVANCED_BUTTON__ 55 | -------------------------------------------------------------------------------- /lib/adv_button/component.mk: -------------------------------------------------------------------------------- 1 | # Component makefile for adv_button 2 | 3 | INC_DIRS += $(adv_button_ROOT) 4 | 5 | adv_button_INC_DIR = $(adv_button_ROOT) 6 | adv_button_SRC_DIR = $(adv_button_ROOT) 7 | 8 | $(eval $(call component_compile_rules,adv_button)) 9 | -------------------------------------------------------------------------------- /lib/adv_button/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Advanced Button Manager Example 3 | * 4 | * Copyright 2018 José A. Jiménez (@RavenSystem) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "adv_button.h" 25 | 26 | 27 | #ifndef BUTTON_GPIO 28 | #define BUTTON_GPIO 0 29 | #endif 30 | 31 | void singlepress_callback(uint8_t gpio) { 32 | printf(">>>>> Example button: Single Press function called using GPIO->%i\n", gpio); 33 | } 34 | 35 | void doublepress_callback(uint8_t gpio) { 36 | printf(">>>>> Example button: Double Press function called using GPIO->%i\n", gpio); 37 | } 38 | 39 | void longpress_callback(uint8_t gpio) { 40 | printf(">>>>> Example button: Long Press function called using GPIO->%i\n", gpio); 41 | } 42 | 43 | void verylongpress_callback(uint8_t gpio) { 44 | printf(">>>>> Example button: Very Long Press function called using GPIO->%i\n", gpio); 45 | } 46 | 47 | void holdpress_callback(uint8_t gpio) { 48 | printf(">>>>> Example button: Hold Press function called using GPIO->%i\n", gpio); 49 | } 50 | 51 | void user_init(void) { 52 | uart_set_baud(0, 115200); 53 | 54 | printf("\n>>>>> ADV BUTTON EXAMPLE\n\n"); 55 | 56 | adv_button_create(BUTTON_GPIO, true); 57 | 58 | adv_button_register_callback_fn(BUTTON_GPIO, singlepress_callback, 1); 59 | adv_button_register_callback_fn(BUTTON_GPIO, doublepress_callback, 2); 60 | adv_button_register_callback_fn(BUTTON_GPIO, longpress_callback, 3); 61 | adv_button_register_callback_fn(BUTTON_GPIO, verylongpress_callback, 4); 62 | adv_button_register_callback_fn(BUTTON_GPIO, holdpress_callback, 5); 63 | } 64 | -------------------------------------------------------------------------------- /lib/led_codes/component.mk: -------------------------------------------------------------------------------- 1 | # Component makefile for led_codes 2 | 3 | INC_DIRS += $(led_codes_ROOT) 4 | 5 | led_codes_INC_DIR = $(led_codes_ROOT) 6 | led_codes_SRC_DIR = $(led_codes_ROOT) 7 | 8 | $(eval $(call component_compile_rules,led_codes)) 9 | 10 | -------------------------------------------------------------------------------- /lib/led_codes/led_codes.c: -------------------------------------------------------------------------------- 1 | /* 2 | * LED Codes 3 | * 4 | * Copyright 2018 José A. Jiménez (@RavenSystem) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "led_codes.h" 26 | 27 | #define DURATION_OFF 150 28 | 29 | typedef struct led_params_t { 30 | blinking_params_t blinking_params; 31 | uint8_t gpio; 32 | bool status; 33 | ETSTimer timer; 34 | uint8_t count; 35 | uint32_t delay; 36 | } led_params_t; 37 | 38 | led_params_t led_params; 39 | 40 | void led_code_run() { 41 | led_params.status = !led_params.status; 42 | 43 | gpio_write(led_params.gpio, led_params.status); 44 | 45 | if (led_params.status == 0) { 46 | led_params.delay = (led_params.blinking_params.duration * 1000) + 90; 47 | } else { 48 | led_params.delay = DURATION_OFF; 49 | led_params.count++; 50 | } 51 | 52 | sdk_os_timer_disarm(&led_params.timer); 53 | 54 | if (led_params.count < led_params.blinking_params.times) { 55 | sdk_os_timer_arm(&led_params.timer, led_params.delay, 0); 56 | } 57 | } 58 | 59 | void led_code(uint8_t gpio, blinking_params_t blinking_params) { 60 | led_params.gpio = gpio; 61 | led_params.blinking_params = blinking_params; 62 | 63 | sdk_os_timer_disarm(&led_params.timer); 64 | sdk_os_timer_setfn(&led_params.timer, led_code_run, NULL); 65 | 66 | led_params.status = 1; 67 | led_params.count = 0; 68 | 69 | led_code_run(); 70 | } 71 | -------------------------------------------------------------------------------- /lib/led_codes/led_codes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * LED Codes 3 | * 4 | * Copyright 2018 José A. Jiménez (@RavenSystem) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #pragma once 20 | 21 | typedef struct blinking_params_t { 22 | uint8_t times; 23 | uint8_t duration; 24 | } blinking_params_t; 25 | 26 | #define GENERIC_ERROR (blinking_params_t){6,0} 27 | #define SENSOR_ERROR (blinking_params_t){5,0} 28 | #define WIFI_CONNECTED (blinking_params_t){1,2} 29 | #define IDENTIFY_ACCESSORY (blinking_params_t){1,3} 30 | #define RESTART_DEVICE (blinking_params_t){2,2} 31 | #define WIFI_CONFIG_RESET (blinking_params_t){2,0} 32 | #define EXTRA_CONFIG_RESET (blinking_params_t){2,1} 33 | #define FUNCTION_A (blinking_params_t){1,0} 34 | #define FUNCTION_B (blinking_params_t){2,0} 35 | #define FUNCTION_C (blinking_params_t){3,0} 36 | #define FUNCTION_D (blinking_params_t){4,0} 37 | 38 | void led_code(uint8_t gpio, blinking_params_t blinking_params); 39 | -------------------------------------------------------------------------------- /wifi.h.sample: -------------------------------------------------------------------------------- 1 | #define WIFI_SSID "mywifi" 2 | #define WIFI_PASSWORD "mypassword" 3 | --------------------------------------------------------------------------------