├── ESP8266_homkit_switch └── ESP8266_homkit_switch.ino │ ├── ESP8266_homkit_switch.ino │ ├── ESP8266_homkit_switch.rar │ ├── ESPHelper.cpp │ ├── ESPHelper.h │ ├── Metro.cpp │ ├── Metro.h │ ├── PubSubClient.cpp │ ├── PubSubClient.h │ ├── README.md │ └── Resources │ └── Switch.jpg ├── NeoPixel ├── NeoPixel.ino └── README.md ├── README.md ├── RGBStrip ├── Arduino │ └── libraries │ │ ├── ESPHelper-master │ │ ├── LICENSE │ │ ├── README.md │ │ ├── examples │ │ │ ├── OTA │ │ │ │ └── OTA.ino │ │ │ ├── RGBLight │ │ │ │ └── RGBLight.ino │ │ │ ├── RelayControlV2 │ │ │ │ └── RelayControlV2.ino │ │ │ ├── basicUse │ │ │ │ └── basicUse.ino │ │ │ ├── buttonDemo │ │ │ │ └── buttonDemo.ino │ │ │ ├── multiNetwork │ │ │ │ └── multiNetwork.ino │ │ │ ├── relayControl │ │ │ │ └── relayControl.ino │ │ │ └── temperatureSensor_ds18b20 │ │ │ │ └── temperatureSensor_ds18b20.ino │ │ ├── keywords.txt │ │ ├── library.json │ │ ├── library.properties │ │ └── src │ │ │ ├── ESPHelper.cpp │ │ │ ├── ESPHelper.h │ │ │ ├── PubSubClient.cpp │ │ │ └── PubSubClient.h │ │ └── HSB_Color-master │ │ ├── HSBColor.cpp │ │ ├── HSBColor.h │ │ └── README.md ├── HAP-NodeJS │ └── accessories │ │ └── RGBLight_accessory.js ├── README.md ├── RGBStrip.ino └── resources │ └── RGBStrip.jpg └── esp8266-weather-station-oled-DST-master ├── esp8266-weather-station-oled-DST ├── DSEG7Classic-BoldFont.h ├── README.md ├── WeatherStationFonts.h ├── WeatherStationImages.h └── esp8266-weather-station-oled-DST.ino └── resources ├── 1-3_day_forecast.jpg ├── 4-6_day_forecast.jpg ├── Boston_EDT.jpg ├── DHT22_sensor.jpg ├── DHT22_update.jpg ├── Thumbs.db ├── Zurich_CET.jpg ├── conditions.jpg ├── cover.jpg ├── splash.jpg └── thingspeak.jpg /ESP8266_homkit_switch/ESP8266_homkit_switch.ino/ESP8266_homkit_switch.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 ItKindaWorks All right reserved. 3 | github.com/ItKindaWorks 4 | 5 | This file is part of ESPHelper 6 | 7 | ESPHelper is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | ESPHelper is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with ESPHelper. If not, see . 19 | */ 20 | 21 | /* 22 | This is a simple demo of an MQTT enabled button. A button is attahed 23 | to pin 0 with a pull-up resistor and each time the button is pressed, 24 | it toggles the state and publishes the new state to the MQTT broker. 25 | It is also subscribed to the same topic that it publishes to so that 26 | the state of the toggle can be updated from the MQTT side. 27 | */ 28 | #include "ESPHelper.h" 29 | #include "PubSubClient.h" 30 | #define TOPIC "/home/vSwitch1" 31 | #define NETWORK_HOSTNAME "switch1" 32 | #define OTA_PASSWORD "___" 33 | 34 | #define BUTTON_PIN D0 //button on pin 0 with pull up resistor (pulled low on press) 35 | #define BLINK_PIN D4 36 | 37 | 38 | char* buttonTopic = TOPIC; 39 | char* hostnameStr = NETWORK_HOSTNAME; 40 | 41 | const int buttonPin = BUTTON_PIN; 42 | //const int blinkPin = BLINK_PIN; 43 | 44 | bool currentState = false; 45 | 46 | bool lastButtonState = false; 47 | 48 | //set this info for your own network 49 | netInfo homeNet = {.name = "___", .mqtt = "192.168.1.1", .ssid = "___", .pass = "___"}; 50 | ESPHelper myESP(&homeNet); 51 | 52 | void setup() { 53 | //setup ota on esphelper 54 | myESP.OTA_enable(); 55 | myESP.OTA_setPassword(OTA_PASSWORD); 56 | myESP.OTA_setHostnameWithVersion(hostnameStr); 57 | 58 | //enable the connection heartbeat 59 | //myESP.enableHeartbeat(blinkPin); 60 | 61 | //subscribe to the button topic (this allows outside control of the state of the switch) 62 | myESP.addSubscription(buttonTopic); 63 | 64 | //start ESPHelper 65 | myESP.begin(); 66 | 67 | //setup the mqtt callback function 68 | myESP.setCallback(callback); 69 | 70 | //set the button pin as an input 71 | pinMode(buttonPin, INPUT); 72 | } 73 | 74 | 75 | void loop(){ 76 | if(myESP.loop() == FULL_CONNECTION){ 77 | 78 | //read the button (low on press, high on release) 79 | bool buttonState = digitalRead(buttonPin); 80 | 81 | //if the button is pressed (LOW) and previously was not pressed(HIGH) 82 | if(buttonState == LOW && lastButtonState == HIGH){ 83 | //invert the current state 84 | currentState = !currentState; 85 | 86 | //publish to mqtt based on current state 87 | if(currentState){ 88 | myESP.publish(buttonTopic, "1", true); 89 | } 90 | else{ 91 | myESP.publish(buttonTopic, "0", true); 92 | } 93 | 94 | //set the lastButtonState to LOW to prevent multiple triggers 95 | lastButtonState = LOW; 96 | 97 | //wait half a second (poor mans debounce) 98 | delay(500); 99 | } 100 | 101 | //else if the button is not pressed and set lastButtonState to HIGH 102 | else if(buttonState == HIGH){lastButtonState = HIGH;} 103 | } 104 | yield(); 105 | } 106 | 107 | 108 | void callback(char* topic, byte* payload, unsigned int length) { 109 | 110 | //if the payload is '1' then set the state to true 111 | if(payload[0] == '1'){ 112 | currentState = true; 113 | } 114 | 115 | //otherwise set the current state to false 116 | else{ 117 | currentState = false; 118 | } 119 | } 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /ESP8266_homkit_switch/ESP8266_homkit_switch.ino/ESP8266_homkit_switch.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Supersimo88/Arduino-ESP8266-HomeKit/8dce60573587cb245d3ca042adf26854feb60ecb/ESP8266_homkit_switch/ESP8266_homkit_switch.ino/ESP8266_homkit_switch.rar -------------------------------------------------------------------------------- /ESP8266_homkit_switch/ESP8266_homkit_switch.ino/ESPHelper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ESPHelper.cpp 3 | Copyright (c) 2016 ItKindaWorks Inc All right reserved. 4 | github.com/ItKindaWorks 5 | 6 | This file is part of ESPHelper 7 | 8 | ESPHelper is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | ESPHelper is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with ESPHelper. If not, see . 20 | */ 21 | 22 | 23 | #include "ESPHelper.h" 24 | 25 | //empy initializer 26 | ESPHelper::ESPHelper(){ } 27 | 28 | //initializer with single netInfo network 29 | ESPHelper::ESPHelper(netInfo *startingNet){ 30 | _currentNet = *startingNet; 31 | 32 | _ssidSet = true; 33 | _passSet = true; 34 | _mqttSet = true; 35 | 36 | _hoppingAllowed = false; 37 | 38 | _useOTA = false; 39 | } 40 | 41 | 42 | //initializer with netInfo array and index 43 | ESPHelper::ESPHelper(netInfo *netList[], uint8_t netCount, uint8_t startIndex){ 44 | _netList = netList; 45 | _netCount = netCount; 46 | _currentIndex = startIndex; 47 | 48 | _hoppingAllowed = true; 49 | 50 | _useOTA = false; 51 | 52 | _currentNet = *netList[constrain(_currentIndex, 0, _netCount)]; 53 | 54 | _ssidSet = true; 55 | _passSet = true; 56 | _mqttSet = true; 57 | } 58 | 59 | //initializer with single network information 60 | ESPHelper::ESPHelper(const char *ssid, const char *pass, const char *mqttIP){ 61 | _currentNet.ssid = ssid; 62 | _currentNet.pass = pass; 63 | _currentNet.mqtt = mqttIP; 64 | 65 | _hoppingAllowed = false; 66 | 67 | _useOTA = false; 68 | 69 | _ssidSet = true; 70 | _passSet = true; 71 | _mqttSet = true; 72 | } 73 | 74 | //start the wifi & mqtt systems and attempt connection (currently blocking) 75 | //true on: parameter check validated 76 | //false on: parameter check failed 77 | bool ESPHelper::begin(){ 78 | 79 | if(checkParams()){ 80 | // Generate client name based on MAC address and last 8 bits of microsecond counter 81 | _clientName += "esp8266-"; 82 | uint8_t mac[6]; 83 | WiFi.macAddress(mac); 84 | _clientName += macToStr(mac); 85 | 86 | client = PubSubClient(_currentNet.mqtt, 1883, wifiClient); 87 | 88 | WiFi.mode(WIFI_STA); 89 | WiFi.begin(_currentNet.ssid, _currentNet.pass); 90 | 91 | ArduinoOTA.onStart([]() {/* ota start code */}); 92 | ArduinoOTA.onEnd([]() { 93 | WiFi.disconnect(); 94 | int timeout = 0; 95 | while(WiFi.status() != WL_DISCONNECTED && timeout < 200){ 96 | delay(10); 97 | timeout++; 98 | } 99 | }); 100 | ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {/* ota progress code */}); 101 | ArduinoOTA.onError([](ota_error_t error) {/* ota error code */}); 102 | 103 | int timeout = 0; //counter for begin connection attempts 104 | while ((!client.connected() || WiFi.status() != WL_CONNECTED) && timeout < 200 ) { //max 2 sec before timeout 105 | reconnect(); 106 | delay(10); 107 | timeout++; 108 | } 109 | 110 | OTA_begin(); 111 | 112 | _hasBegun = true; 113 | return true; 114 | } 115 | return false; 116 | } 117 | 118 | void ESPHelper::end(){ 119 | OTA_disable(); 120 | WiFi.disconnect(); 121 | } 122 | 123 | //main loop - should be called as often as possible - handles wifi/mqtt connection and mqtt handler 124 | //true on: network/server connected 125 | //false on: network or server disconnected 126 | int ESPHelper::loop(){ 127 | if(checkParams()){ 128 | if (!client.connected() || WiFi.status() != WL_CONNECTED) { 129 | reconnect(); 130 | // return _connectionStatus; 131 | } 132 | 133 | if(_connectionStatus >= WIFI_ONLY){ 134 | 135 | if(_connectionStatus == FULL_CONNECTION){client.loop();} 136 | 137 | heartbeat(); 138 | 139 | //check for whether we want to use OTA and whether the system is running 140 | if(_useOTA && _OTArunning) {ArduinoOTA.handle();} 141 | //if we want to use OTA but its not running yet, start it up. 142 | else if(_useOTA && !_OTArunning){ 143 | OTA_begin(); 144 | ArduinoOTA.handle(); 145 | } 146 | 147 | 148 | return _connectionStatus; 149 | } 150 | } 151 | return false; 152 | } 153 | 154 | //subscribe to a speicifc topic (does not add to topic list) 155 | //true on: subscription success 156 | //false on: subscription failed (either from PubSub lib or network is disconnected) 157 | bool ESPHelper::subscribe(const char* topic, int qos){ 158 | if(_connectionStatus == FULL_CONNECTION){ 159 | bool returnVal = client.subscribe(topic, qos); 160 | client.loop(); 161 | return returnVal; 162 | } 163 | else{return false;} 164 | } 165 | 166 | //add a topic to the list of subscriptions and attempt to subscribe to the topic on the spot 167 | //true on: subscription added to list (does not guarantee that the topic was subscribed to, only that it was added to the list) 168 | //false on: subscription not added to list 169 | bool ESPHelper::addSubscription(const char* topic){ 170 | bool subscribed = false; 171 | for(int i = 0; i < MAX_SUBSCRIPTIONS; i++){ 172 | if(_subscriptions[i].isUsed == false){ 173 | _subscriptions[i].topic = topic; 174 | _subscriptions[i].isUsed = true; 175 | subscribed = true; 176 | break; 177 | } 178 | } 179 | if(subscribed){subscribe(topic, _qos);} 180 | 181 | 182 | return subscribed; 183 | } 184 | 185 | //loops through list of subscriptions and attempts to subscribe to all topics 186 | void ESPHelper::resubscribe(){ 187 | for(int i = 0; i < MAX_SUBSCRIPTIONS; i++){ 188 | if(_subscriptions[i].isUsed){ 189 | subscribe(_subscriptions[i].topic, _qos); 190 | yield(); 191 | } 192 | } 193 | } 194 | 195 | //attempts to remove a topic from the topic list 196 | //true on: subscription removed from list (does not guarantee that the topic was unsubscribed from, only that it was removed from the list) 197 | //false on: topic was not found in list and therefore cannot be removed 198 | bool ESPHelper::removeSubscription(const char* topic){ 199 | bool returnVal = false; 200 | String topicStr = topic; 201 | for(int i = 0; i < MAX_SUBSCRIPTIONS; i++){ 202 | if(_subscriptions[i].isUsed){ 203 | String subStr = _subscriptions[i].topic; 204 | if(subStr.equals(topicStr)){ 205 | _subscriptions[i].isUsed = false; 206 | client.unsubscribe(_subscriptions[i].topic); 207 | returnVal = true; 208 | break; 209 | } 210 | } 211 | } 212 | 213 | return returnVal; 214 | } 215 | 216 | //publish to a specified topic 217 | void ESPHelper::publish(const char* topic, const char* payload){ 218 | publish(topic, payload, false); 219 | } 220 | 221 | //publish to a specified topic with a given retain level 222 | void ESPHelper::publish(const char* topic, const char* payload, bool retain){ 223 | client.publish(topic, payload, retain); 224 | } 225 | 226 | //set the callback function for MQTT 227 | //true on: mqtt has been initialized 228 | //false on: mqtt not been inistialized 229 | bool ESPHelper::setCallback(MQTT_CALLBACK_SIGNATURE){ 230 | if(_hasBegun) { 231 | client.setCallback(callback); 232 | return true; 233 | } 234 | else{ 235 | return false; 236 | } 237 | } 238 | 239 | //attempts to connect to wifi & mqtt server if not connected 240 | void ESPHelper::reconnect() { 241 | static int tryCount = 0; 242 | 243 | if(reconnectMetro.check()){ 244 | //attempt to connect to the wifi if connection is lost 245 | if(WiFi.status() != WL_CONNECTED){ 246 | _connectionStatus = NO_CONNECTION; 247 | // _connected = false; 248 | debugPrint("."); 249 | tryCount++; 250 | if(tryCount == 20){ 251 | changeNetwork(); 252 | tryCount = 0; 253 | return; 254 | } 255 | } 256 | 257 | // make sure we are connected to WIFI before attemping to reconnect to MQTT 258 | //----note---- maybe want to reset tryCount whenever we succeed at getting wifi connection? 259 | if(WiFi.status() == WL_CONNECTED){ 260 | debugPrintln("\n---WIFI Connected!---"); 261 | _connectionStatus = WIFI_ONLY; 262 | 263 | int timeout = 0; //allow a max of 10 mqtt connection attempts before timing out 264 | while (!client.connected() && timeout < 10) { 265 | debugPrint("Attemping MQTT connection"); 266 | 267 | //if connected, subscribe to the topic(s) we want to be notified about 268 | if (client.connect((char*) _clientName.c_str())) { 269 | debugPrintln(" -- Connected"); 270 | // _connected = true; 271 | _connectionStatus = FULL_CONNECTION; 272 | resubscribe(); 273 | } 274 | else{ 275 | debugPrintln(" -- Failed"); 276 | // _connected = false; 277 | } 278 | timeout++; 279 | } 280 | 281 | if(timeout >= 10 && !client.connected()){ //if we still cant connect to mqtt after 10 attempts increment the try count 282 | tryCount++; 283 | if(tryCount == 20){ 284 | changeNetwork(); 285 | tryCount = 0; 286 | return; 287 | } 288 | } 289 | } 290 | 291 | reconnectMetro.reset(); 292 | } 293 | } 294 | 295 | //changes the current network settings to the next listed network if network hopping is allowed 296 | void ESPHelper::changeNetwork(){ 297 | 298 | if(_hoppingAllowed){ 299 | _currentIndex++; 300 | if(_currentIndex >= _netCount){_currentIndex = 0;} 301 | 302 | _currentNet = *_netList[_currentIndex]; 303 | 304 | debugPrint("Trying next network: "); 305 | debugPrintln(_currentNet.ssid); 306 | 307 | updateNetwork(); 308 | } 309 | 310 | 311 | // debugPrintln("\tDisconnecting from WiFi"); 312 | // WiFi.disconnect(); 313 | // debugPrintln("\tAttempting to begin on new network"); 314 | // WiFi.begin(_currentNet.ssid, _currentNet.pass); 315 | // debugPrintln("\tSetting new MQTT server"); 316 | // client.setServer(_currentNet.mqtt, 1883); 317 | // debugPrintln("\tDone - Ready for next reconnect attempt"); 318 | //ALL THIS COMMENTED CODE IS HANDLED BY updateNetwork() 319 | } 320 | 321 | void ESPHelper::updateNetwork(){ 322 | debugPrintln("\tDisconnecting from WiFi"); 323 | WiFi.disconnect(); 324 | debugPrintln("\tAttempting to begin on new network"); 325 | WiFi.begin(_currentNet.ssid, _currentNet.pass); 326 | debugPrintln("\tSetting new MQTT server"); 327 | client.setServer(_currentNet.mqtt, 1883); 328 | debugPrintln("\tDone - Ready for next reconnect attempt"); 329 | } 330 | 331 | //generate unique MQTT name from MAC addr 332 | String ESPHelper::macToStr(const uint8_t* mac){ 333 | 334 | String result; 335 | 336 | for (int i = 0; i < 6; ++i) { 337 | result += String(mac[i], 16); 338 | 339 | if (i < 5){ 340 | result += ':'; 341 | } 342 | } 343 | 344 | return result; 345 | } 346 | 347 | //change the current network info to a new netInfo - does not automatically disconnect from current network if already connected 348 | void ESPHelper::setNetInfo(netInfo newNetwork){ 349 | _currentNet = newNetwork; 350 | _ssidSet = true; 351 | _passSet = true; 352 | _mqttSet = true; 353 | } 354 | 355 | //change the current network info to a new *netInfo - does not automatically disconnect from current network if already connected 356 | void ESPHelper::setNetInfo(netInfo *newNetwork){ 357 | _currentNet = *newNetwork; 358 | _ssidSet = true; 359 | _passSet = true; 360 | _mqttSet = true; 361 | } 362 | 363 | //return the current netInfo state 364 | netInfo* ESPHelper::getNetInfo(){ 365 | return &_currentNet; 366 | } 367 | 368 | //return the current SSID 369 | const char* ESPHelper::getSSID(){ 370 | if(_ssidSet){return _currentNet.ssid;} 371 | return "SSID NOT SET"; 372 | } 373 | //set a new SSID - does not automatically disconnect from current network if already connected 374 | void ESPHelper::setSSID(const char* ssid){ 375 | _currentNet.ssid = ssid; 376 | _ssidSet = true; 377 | } 378 | 379 | //return the current network password 380 | const char* ESPHelper::getPASS(){ 381 | if(_passSet){return _currentNet.pass;} 382 | return "PASS NOT SET"; 383 | } 384 | //set a new network password - does not automatically disconnect from current network if already connected 385 | void ESPHelper::setPASS(const char* pass){ 386 | _currentNet.pass = pass; 387 | _passSet = true; 388 | } 389 | 390 | //return the current MQTT server IP 391 | const char* ESPHelper::getMQTTIP(){ 392 | if(_mqttSet){return _currentNet.mqtt;} 393 | return "MQTT IP NOT SET"; 394 | } 395 | //set a new MQTT server IP - does not automatically disconnect from current network/server if already connected 396 | void ESPHelper::setMQTTIP(const char* mqttIP){ 397 | _currentNet.mqtt = mqttIP; 398 | _mqttSet = true; 399 | } 400 | 401 | 402 | int ESPHelper::getMQTTQOS(){ 403 | return _qos; 404 | 405 | } 406 | void ESPHelper::setMQTTQOS(int qos){ 407 | _qos = qos; 408 | } 409 | 410 | 411 | String ESPHelper::getIP(){ 412 | return WiFi.localIP().toString(); 413 | } 414 | 415 | 416 | int ESPHelper::getStatus(){ 417 | return _connectionStatus; 418 | } 419 | 420 | 421 | 422 | //make sure all network parameters are set 423 | //true on: all network parameters have been set 424 | //false on: not all network parameters have been set 425 | bool ESPHelper::checkParams(){ 426 | if(_ssidSet && _passSet && _mqttSet){return true;} 427 | return false; 428 | } 429 | 430 | //enable or disable hopping - generally set automatically by initializer 431 | void ESPHelper::setHopping(bool canHop){ 432 | _hoppingAllowed = canHop; 433 | } 434 | 435 | //DEBUG ONLY - print the subscribed topics list to the serial line 436 | void ESPHelper::listSubscriptions(){ 437 | for(int i = 0; i < MAX_SUBSCRIPTIONS; i++){ 438 | if(_subscriptions[i].isUsed){ 439 | debugPrintln(_subscriptions[i].topic); 440 | } 441 | } 442 | } 443 | 444 | 445 | 446 | //enable the connection heartbeat on a given pin 447 | void ESPHelper::enableHeartbeat(int16_t pin){ 448 | #ifdef DEBUG 449 | if(pin == 1){_heartbeatEnabled = false;} 450 | else{ 451 | _heartbeatEnabled = true; 452 | _ledPin = pin; 453 | pinMode(_ledPin, OUTPUT); 454 | digitalWrite(_ledPin, HIGH); 455 | } 456 | #else 457 | _heartbeatEnabled = true; 458 | _ledPin = pin; 459 | pinMode(_ledPin, OUTPUT); 460 | digitalWrite(_ledPin, HIGH); 461 | #endif 462 | } 463 | 464 | //disable the connection heartbeat 465 | void ESPHelper::disableHeartbeat(){ 466 | _heartbeatEnabled = false; 467 | } 468 | 469 | //heartbeat to indicate network/mqtt connection 470 | void ESPHelper::heartbeat(){ 471 | static Metro heartbeatMetro = Metro(10); 472 | static int counter = 0; 473 | 474 | static bool ledState = true; 475 | 476 | if(heartbeatMetro.check() && _heartbeatEnabled){ 477 | if(counter == 1){ 478 | digitalWrite(_ledPin, ledState); 479 | heartbeatMetro.interval(10); 480 | ledState = !ledState; 481 | } 482 | else if(counter == 2){ 483 | digitalWrite(_ledPin, ledState); 484 | heartbeatMetro.interval(300); 485 | ledState = !ledState; 486 | } 487 | else if(counter == 3){ 488 | digitalWrite(_ledPin, ledState); 489 | heartbeatMetro.interval(10); 490 | ledState = !ledState; 491 | } 492 | else{ 493 | digitalWrite(_ledPin, ledState); 494 | heartbeatMetro.interval(1000); 495 | ledState = !ledState; 496 | counter = 0; 497 | } 498 | counter++; 499 | } 500 | } 501 | 502 | //enable use of OTA updates 503 | void ESPHelper::OTA_enable(){ 504 | _useOTA = true; 505 | OTA_begin(); 506 | } 507 | 508 | //begin the OTA subsystem but with a check for connectivity and enabled use of OTA 509 | void ESPHelper::OTA_begin(){ 510 | if(_connectionStatus >= WIFI_ONLY && _useOTA){ 511 | ArduinoOTA.begin(); 512 | _OTArunning = true; 513 | } 514 | } 515 | 516 | //disable use of OTA updates 517 | void ESPHelper::OTA_disable(){ 518 | _useOTA = false; 519 | _OTArunning = false; 520 | } 521 | 522 | //set a password for OTA updates 523 | void ESPHelper::OTA_setPassword(const char* pass){ 524 | ArduinoOTA.setPassword(pass); 525 | } 526 | 527 | void ESPHelper::OTA_setHostname(const char* hostname){ 528 | strcpy(_hostname, hostname); 529 | ArduinoOTA.setHostname(_hostname); 530 | } 531 | 532 | void ESPHelper::OTA_setHostnameWithVersion(const char* hostname){ 533 | strcpy(_hostname, hostname); 534 | strcat(_hostname, "----"); 535 | strcat(_hostname, VERSION); 536 | 537 | ArduinoOTA.setHostname(_hostname); 538 | } 539 | 540 | 541 | -------------------------------------------------------------------------------- /ESP8266_homkit_switch/ESP8266_homkit_switch.ino/ESPHelper.h: -------------------------------------------------------------------------------- 1 | /* 2 | ESPHelper.h 3 | Copyright (c) 2016 ItKindaWorks Inc All right reserved. 4 | github.com/ItKindaWorks 5 | 6 | This file is part of ESPHelper 7 | 8 | ESPHelper is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | ESPHelper is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with ESPHelper. If not, see . 20 | */ 21 | 22 | 23 | 24 | #ifndef ESP_HELPER_H 25 | #define ESP_HELPER_H 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #include "PubSubClient.h" 32 | #include 33 | #include "Metro.h" 34 | 35 | #define MAX_SUBSCRIPTIONS 25 //feel free to change this if you need more subsciptions 36 | 37 | #define VERSION "1-2-5" 38 | 39 | #define DEFAULT_QOS 1; //at least once - devices are garunteed to get a message. 40 | 41 | // #define DEBUG 42 | 43 | enum connStatus {NO_CONNECTION, WIFI_ONLY, FULL_CONNECTION}; 44 | 45 | 46 | #ifdef DEBUG 47 | #define debugPrint(x) Serial.print(x) //debug on 48 | #define debugPrintln(x) Serial.println(x) //debug on 49 | #else 50 | #define debugPrint(x) {;} //debug off 51 | #define debugPrintln(x) {;} //debug off 52 | #endif 53 | 54 | struct netInfo { 55 | const char* name; 56 | const char* mqtt; 57 | const char* ssid; 58 | const char* pass; 59 | }; 60 | typedef struct netInfo netInfo; 61 | 62 | struct subscription{ 63 | bool isUsed = false; 64 | const char* topic; 65 | }; 66 | typedef struct subscription subscription; 67 | 68 | 69 | class ESPHelper{ 70 | 71 | public: 72 | int16_t _hoppingAllowed = false; 73 | bool _fullyConnected = false; 74 | 75 | netInfo _currentNet; 76 | netInfo *_currentNetwork; 77 | 78 | Metro reconnectMetro = Metro(500); 79 | 80 | PubSubClient client; 81 | 82 | ESPHelper(); 83 | ESPHelper(netInfo *startingNet); 84 | ESPHelper(netInfo **startingNet, uint8_t netCount, uint8_t startIndex = 0); 85 | ESPHelper(const char *ssid, const char *pass, const char *mqttIP); 86 | 87 | bool begin(); 88 | void end(); 89 | 90 | int loop(); 91 | 92 | bool subscribe(const char* topic, int qos); 93 | bool addSubscription(const char* topic); 94 | bool removeSubscription(const char* topic); 95 | 96 | void publish(const char* topic, const char* payload); 97 | void publish(const char* topic, const char* payload, bool retain); 98 | 99 | bool setCallback(MQTT_CALLBACK_SIGNATURE); 100 | 101 | void reconnect(); 102 | 103 | void updateNetwork(); //manually disconnect and reconnecting to network/mqtt using current values (generally called after setting new network values) 104 | 105 | const char* getSSID(); 106 | void setSSID(const char *ssid); 107 | 108 | const char* getPASS(); 109 | void setPASS(const char *pass); 110 | 111 | const char* getMQTTIP(); 112 | void setMQTTIP(const char *mqttIP); 113 | 114 | int getMQTTQOS(); 115 | void setMQTTQOS(int qos); 116 | 117 | String getIP(); 118 | 119 | int getStatus(); 120 | 121 | void setNetInfo(netInfo newNetwork); 122 | void setNetInfo(netInfo *newNetwork); 123 | netInfo* getNetInfo(); 124 | 125 | void setHopping(bool canHop); 126 | 127 | void listSubscriptions(); 128 | 129 | void enableHeartbeat(int16_t pin); 130 | void disableHeartbeat(); 131 | void heartbeat(); 132 | 133 | void OTA_enable(); 134 | void OTA_disable(); 135 | void OTA_begin(); 136 | void OTA_setPassword(const char* pass); 137 | void OTA_setHostname(const char* hostname); 138 | void OTA_setHostnameWithVersion(const char* hostname); 139 | 140 | private: 141 | WiFiClient wifiClient; 142 | 143 | String _clientName; 144 | 145 | int _connectionStatus = NO_CONNECTION; 146 | 147 | uint8_t _netCount = 0; 148 | uint8_t _currentIndex = 0; 149 | 150 | bool _ssidSet = false; 151 | bool _passSet = false; 152 | bool _mqttSet = false; 153 | 154 | bool _useOTA = false; 155 | bool _OTArunning = false; 156 | 157 | bool _hasBegun = false; 158 | 159 | netInfo **_netList; 160 | 161 | int16_t _ledPin = 2; 162 | bool _heartbeatEnabled = false; 163 | 164 | subscription _subscriptions[MAX_SUBSCRIPTIONS]; 165 | 166 | char _hostname[64]; 167 | 168 | int _qos = DEFAULT_QOS; 169 | 170 | 171 | void changeNetwork(); 172 | 173 | String macToStr(const uint8_t* mac); 174 | 175 | bool checkParams(); 176 | 177 | void resubscribe(); 178 | }; 179 | 180 | #endif 181 | 182 | 183 | -------------------------------------------------------------------------------- /ESP8266_homkit_switch/ESP8266_homkit_switch.ino/Metro.cpp: -------------------------------------------------------------------------------- 1 | 2 | #if defined(ARDUINO) && ARDUINO >= 100 3 | #include "Arduino.h" 4 | #else 5 | #include "WProgram.h" 6 | #endif 7 | #include "Metro.h" 8 | 9 | 10 | Metro::Metro(unsigned long interval_millis) 11 | { 12 | this->autoreset = 0; 13 | interval(interval_millis); 14 | reset(); 15 | } 16 | 17 | // New creator so I can use either the original check behavior or benjamin.soelberg's 18 | // suggested one (see below). 19 | // autoreset = 0 is benjamin.soelberg's check behavior 20 | // autoreset != 0 is the original behavior 21 | 22 | Metro::Metro(unsigned long interval_millis, uint8_t autoreset) 23 | { 24 | this->autoreset = autoreset; // Fix by Paul Bouchier 25 | interval(interval_millis); 26 | reset(); 27 | } 28 | 29 | void Metro::interval(unsigned long interval_millis) 30 | { 31 | this->interval_millis = interval_millis; 32 | } 33 | 34 | // Benjamin.soelberg's check behavior: 35 | // When a check is true, add the interval to the internal counter. 36 | // This should guarantee a better overall stability. 37 | 38 | // Original check behavior: 39 | // When a check is true, add the interval to the current millis() counter. 40 | // This method can add a certain offset over time. 41 | 42 | char Metro::check() 43 | { 44 | if (millis() - this->previous_millis >= this->interval_millis) { 45 | // As suggested by benjamin.soelberg@gmail.com, the following line 46 | // this->previous_millis = millis(); 47 | // was changed to 48 | // this->previous_millis += this->interval_millis; 49 | 50 | // If the interval is set to 0 we revert to the original behavior 51 | if (this->interval_millis <= 0 || this->autoreset ) { 52 | this->previous_millis = millis(); 53 | } else { 54 | this->previous_millis += this->interval_millis; 55 | } 56 | 57 | return 1; 58 | } 59 | 60 | 61 | 62 | return 0; 63 | 64 | } 65 | 66 | void Metro::reset() 67 | { 68 | 69 | this->previous_millis = millis(); 70 | 71 | } 72 | 73 | 74 | -------------------------------------------------------------------------------- /ESP8266_homkit_switch/ESP8266_homkit_switch.ino/Metro.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef Metro_h 4 | #define Metro_h 5 | 6 | #include 7 | 8 | class Metro 9 | { 10 | 11 | public: 12 | Metro(unsigned long interval_millis); 13 | Metro(unsigned long interval_millis, uint8_t autoreset); 14 | void interval(unsigned long interval_millis); 15 | char check(); 16 | void reset(); 17 | 18 | private: 19 | uint8_t autoreset; 20 | unsigned long previous_millis, interval_millis; 21 | 22 | }; 23 | 24 | #endif 25 | 26 | 27 | -------------------------------------------------------------------------------- /ESP8266_homkit_switch/ESP8266_homkit_switch.ino/PubSubClient.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | PubSubClient.cpp - A simple client for MQTT. 3 | Nick O'Leary 4 | http://knolleary.net 5 | */ 6 | 7 | #include "PubSubClient.h" 8 | #include "Arduino.h" 9 | 10 | PubSubClient::PubSubClient() { 11 | this->_state = MQTT_DISCONNECTED; 12 | this->_client = NULL; 13 | this->stream = NULL; 14 | setCallback(NULL); 15 | } 16 | 17 | PubSubClient::PubSubClient(Client& client) { 18 | this->_state = MQTT_DISCONNECTED; 19 | setClient(client); 20 | this->stream = NULL; 21 | } 22 | 23 | PubSubClient::PubSubClient(IPAddress addr, uint16_t port, Client& client) { 24 | this->_state = MQTT_DISCONNECTED; 25 | setServer(addr, port); 26 | setClient(client); 27 | this->stream = NULL; 28 | } 29 | PubSubClient::PubSubClient(IPAddress addr, uint16_t port, Client& client, Stream& stream) { 30 | this->_state = MQTT_DISCONNECTED; 31 | setServer(addr,port); 32 | setClient(client); 33 | setStream(stream); 34 | } 35 | PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) { 36 | this->_state = MQTT_DISCONNECTED; 37 | setServer(addr, port); 38 | setCallback(callback); 39 | setClient(client); 40 | this->stream = NULL; 41 | } 42 | PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) { 43 | this->_state = MQTT_DISCONNECTED; 44 | setServer(addr,port); 45 | setCallback(callback); 46 | setClient(client); 47 | setStream(stream); 48 | } 49 | 50 | PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, Client& client) { 51 | this->_state = MQTT_DISCONNECTED; 52 | setServer(ip, port); 53 | setClient(client); 54 | this->stream = NULL; 55 | } 56 | PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, Client& client, Stream& stream) { 57 | this->_state = MQTT_DISCONNECTED; 58 | setServer(ip,port); 59 | setClient(client); 60 | setStream(stream); 61 | } 62 | PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) { 63 | this->_state = MQTT_DISCONNECTED; 64 | setServer(ip, port); 65 | setCallback(callback); 66 | setClient(client); 67 | this->stream = NULL; 68 | } 69 | PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) { 70 | this->_state = MQTT_DISCONNECTED; 71 | setServer(ip,port); 72 | setCallback(callback); 73 | setClient(client); 74 | setStream(stream); 75 | } 76 | 77 | PubSubClient::PubSubClient(const char* domain, uint16_t port, Client& client) { 78 | this->_state = MQTT_DISCONNECTED; 79 | setServer(domain,port); 80 | setClient(client); 81 | this->stream = NULL; 82 | } 83 | PubSubClient::PubSubClient(const char* domain, uint16_t port, Client& client, Stream& stream) { 84 | this->_state = MQTT_DISCONNECTED; 85 | setServer(domain,port); 86 | setClient(client); 87 | setStream(stream); 88 | } 89 | PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) { 90 | this->_state = MQTT_DISCONNECTED; 91 | setServer(domain,port); 92 | setCallback(callback); 93 | setClient(client); 94 | this->stream = NULL; 95 | } 96 | PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) { 97 | this->_state = MQTT_DISCONNECTED; 98 | setServer(domain,port); 99 | setCallback(callback); 100 | setClient(client); 101 | setStream(stream); 102 | } 103 | 104 | boolean PubSubClient::connect(const char *id) { 105 | return connect(id,NULL,NULL,0,0,0,0); 106 | } 107 | 108 | boolean PubSubClient::connect(const char *id, const char *user, const char *pass) { 109 | return connect(id,user,pass,0,0,0,0); 110 | } 111 | 112 | boolean PubSubClient::connect(const char *id, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage) { 113 | return connect(id,NULL,NULL,willTopic,willQos,willRetain,willMessage); 114 | } 115 | 116 | boolean PubSubClient::connect(const char *id, const char *user, const char *pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage) { 117 | if (!connected()) { 118 | int result = 0; 119 | 120 | if (domain != NULL) { 121 | result = _client->connect(this->domain, this->port); 122 | } else { 123 | result = _client->connect(this->ip, this->port); 124 | } 125 | if (result == 1) { 126 | nextMsgId = 1; 127 | // Leave room in the buffer for header and variable length field 128 | uint16_t length = 5; 129 | unsigned int j; 130 | 131 | #if MQTT_VERSION == MQTT_VERSION_3_1 132 | uint8_t d[9] = {0x00,0x06,'M','Q','I','s','d','p', MQTT_VERSION}; 133 | #define MQTT_HEADER_VERSION_LENGTH 9 134 | #elif MQTT_VERSION == MQTT_VERSION_3_1_1 135 | uint8_t d[7] = {0x00,0x04,'M','Q','T','T',MQTT_VERSION}; 136 | #define MQTT_HEADER_VERSION_LENGTH 7 137 | #endif 138 | for (j = 0;j>1); 154 | } 155 | } 156 | 157 | buffer[length++] = v; 158 | 159 | buffer[length++] = ((MQTT_KEEPALIVE) >> 8); 160 | buffer[length++] = ((MQTT_KEEPALIVE) & 0xFF); 161 | length = writeString(id,buffer,length); 162 | if (willTopic) { 163 | length = writeString(willTopic,buffer,length); 164 | length = writeString(willMessage,buffer,length); 165 | } 166 | 167 | if(user != NULL) { 168 | length = writeString(user,buffer,length); 169 | if(pass != NULL) { 170 | length = writeString(pass,buffer,length); 171 | } 172 | } 173 | 174 | write(MQTTCONNECT,buffer,length-5); 175 | 176 | lastInActivity = lastOutActivity = millis(); 177 | 178 | while (!_client->available()) { 179 | unsigned long t = millis(); 180 | if (t-lastInActivity >= ((int32_t) MQTT_SOCKET_TIMEOUT*1000UL)) { 181 | _state = MQTT_CONNECTION_TIMEOUT; 182 | _client->stop(); 183 | return false; 184 | } 185 | } 186 | uint8_t llen; 187 | uint16_t len = readPacket(&llen); 188 | 189 | if (len == 4) { 190 | if (buffer[3] == 0) { 191 | lastInActivity = millis(); 192 | pingOutstanding = false; 193 | _state = MQTT_CONNECTED; 194 | return true; 195 | } else { 196 | _state = buffer[3]; 197 | } 198 | } 199 | _client->stop(); 200 | } else { 201 | _state = MQTT_CONNECT_FAILED; 202 | } 203 | return false; 204 | } 205 | return true; 206 | } 207 | 208 | // reads a byte into result 209 | boolean PubSubClient::readByte(uint8_t * result) { 210 | uint32_t previousMillis = millis(); 211 | while(!_client->available()) { 212 | uint32_t currentMillis = millis(); 213 | if(currentMillis - previousMillis >= ((int32_t) MQTT_SOCKET_TIMEOUT * 1000)){ 214 | return false; 215 | } 216 | } 217 | *result = _client->read(); 218 | return true; 219 | } 220 | 221 | // reads a byte into result[*index] and increments index 222 | boolean PubSubClient::readByte(uint8_t * result, uint16_t * index){ 223 | uint16_t current_index = *index; 224 | uint8_t * write_address = &(result[current_index]); 225 | if(readByte(write_address)){ 226 | *index = current_index + 1; 227 | return true; 228 | } 229 | return false; 230 | } 231 | 232 | uint16_t PubSubClient::readPacket(uint8_t* lengthLength) { 233 | uint16_t len = 0; 234 | if(!readByte(buffer, &len)) return 0; 235 | bool isPublish = (buffer[0]&0xF0) == MQTTPUBLISH; 236 | uint32_t multiplier = 1; 237 | uint16_t length = 0; 238 | uint8_t digit = 0; 239 | uint16_t skip = 0; 240 | uint8_t start = 0; 241 | 242 | do { 243 | if(!readByte(&digit)) return 0; 244 | buffer[len++] = digit; 245 | length += (digit & 127) * multiplier; 246 | multiplier *= 128; 247 | } while ((digit & 128) != 0); 248 | *lengthLength = len-1; 249 | 250 | if (isPublish) { 251 | // Read in topic length to calculate bytes to skip over for Stream writing 252 | if(!readByte(buffer, &len)) return 0; 253 | if(!readByte(buffer, &len)) return 0; 254 | skip = (buffer[*lengthLength+1]<<8)+buffer[*lengthLength+2]; 255 | start = 2; 256 | if (buffer[0]&MQTTQOS1) { 257 | // skip message id 258 | skip += 2; 259 | } 260 | } 261 | 262 | for (uint16_t i = start;istream) { 265 | if (isPublish && len-*lengthLength-2>skip) { 266 | this->stream->write(digit); 267 | } 268 | } 269 | if (len < MQTT_MAX_PACKET_SIZE) { 270 | buffer[len] = digit; 271 | } 272 | len++; 273 | } 274 | 275 | if (!this->stream && len > MQTT_MAX_PACKET_SIZE) { 276 | len = 0; // This will cause the packet to be ignored. 277 | } 278 | 279 | return len; 280 | } 281 | 282 | boolean PubSubClient::loop() { 283 | if (connected()) { 284 | unsigned long t = millis(); 285 | if ((t - lastInActivity > MQTT_KEEPALIVE*1000UL) || (t - lastOutActivity > MQTT_KEEPALIVE*1000UL)) { 286 | if (pingOutstanding) { 287 | this->_state = MQTT_CONNECTION_TIMEOUT; 288 | _client->stop(); 289 | return false; 290 | } else { 291 | buffer[0] = MQTTPINGREQ; 292 | buffer[1] = 0; 293 | _client->write(buffer,2); 294 | lastOutActivity = t; 295 | lastInActivity = t; 296 | pingOutstanding = true; 297 | } 298 | } 299 | if (_client->available()) { 300 | uint8_t llen; 301 | uint16_t len = readPacket(&llen); 302 | uint16_t msgId = 0; 303 | uint8_t *payload; 304 | if (len > 0) { 305 | lastInActivity = t; 306 | uint8_t type = buffer[0]&0xF0; 307 | if (type == MQTTPUBLISH) { 308 | if (callback) { 309 | uint16_t tl = (buffer[llen+1]<<8)+buffer[llen+2]; /* topic length in bytes */ 310 | memmove(buffer+llen+2,buffer+llen+3,tl); /* move topic inside buffer 1 byte to front */ 311 | buffer[llen+2+tl] = 0; /* end the topic as a 'C' string with \x00 */ 312 | char *topic = (char*) buffer+llen+2; 313 | // msgId only present for QOS>0 314 | if ((buffer[0]&0x06) == MQTTQOS1) { 315 | msgId = (buffer[llen+3+tl]<<8)+buffer[llen+3+tl+1]; 316 | payload = buffer+llen+3+tl+2; 317 | callback(topic,payload,len-llen-3-tl-2); 318 | 319 | buffer[0] = MQTTPUBACK; 320 | buffer[1] = 2; 321 | buffer[2] = (msgId >> 8); 322 | buffer[3] = (msgId & 0xFF); 323 | _client->write(buffer,4); 324 | lastOutActivity = t; 325 | 326 | } else { 327 | payload = buffer+llen+3+tl; 328 | callback(topic,payload,len-llen-3-tl); 329 | } 330 | } 331 | } else if (type == MQTTPINGREQ) { 332 | buffer[0] = MQTTPINGRESP; 333 | buffer[1] = 0; 334 | _client->write(buffer,2); 335 | } else if (type == MQTTPINGRESP) { 336 | pingOutstanding = false; 337 | } 338 | } 339 | } 340 | return true; 341 | } 342 | return false; 343 | } 344 | 345 | boolean PubSubClient::publish(const char* topic, const char* payload) { 346 | return publish(topic,(const uint8_t*)payload,strlen(payload),false); 347 | } 348 | 349 | boolean PubSubClient::publish(const char* topic, const char* payload, boolean retained) { 350 | return publish(topic,(const uint8_t*)payload,strlen(payload),retained); 351 | } 352 | 353 | boolean PubSubClient::publish(const char* topic, const uint8_t* payload, unsigned int plength) { 354 | return publish(topic, payload, plength, false); 355 | } 356 | 357 | boolean PubSubClient::publish(const char* topic, const uint8_t* payload, unsigned int plength, boolean retained) { 358 | if (connected()) { 359 | if (MQTT_MAX_PACKET_SIZE < 5 + 2+strlen(topic) + plength) { 360 | // Too long 361 | return false; 362 | } 363 | // Leave room in the buffer for header and variable length field 364 | uint16_t length = 5; 365 | length = writeString(topic,buffer,length); 366 | uint16_t i; 367 | for (i=0;i 0) { 405 | digit |= 0x80; 406 | } 407 | buffer[pos++] = digit; 408 | llen++; 409 | } while(len>0); 410 | 411 | pos = writeString(topic,buffer,pos); 412 | 413 | rc += _client->write(buffer,pos); 414 | 415 | for (i=0;iwrite((char)pgm_read_byte_near(payload + i)); 417 | } 418 | 419 | lastOutActivity = millis(); 420 | 421 | return rc == tlen + 4 + plength; 422 | } 423 | 424 | boolean PubSubClient::write(uint8_t header, uint8_t* buf, uint16_t length) { 425 | uint8_t lenBuf[4]; 426 | uint8_t llen = 0; 427 | uint8_t digit; 428 | uint8_t pos = 0; 429 | uint16_t rc; 430 | uint16_t len = length; 431 | do { 432 | digit = len % 128; 433 | len = len / 128; 434 | if (len > 0) { 435 | digit |= 0x80; 436 | } 437 | lenBuf[pos++] = digit; 438 | llen++; 439 | } while(len>0); 440 | 441 | buf[4-llen] = header; 442 | for (int i=0;i 0) && result) { 452 | bytesToWrite = (bytesRemaining > MQTT_MAX_TRANSFER_SIZE)?MQTT_MAX_TRANSFER_SIZE:bytesRemaining; 453 | rc = _client->write(writeBuf,bytesToWrite); 454 | result = (rc == bytesToWrite); 455 | bytesRemaining -= rc; 456 | writeBuf += rc; 457 | } 458 | return result; 459 | #else 460 | rc = _client->write(buf+(4-llen),length+1+llen); 461 | lastOutActivity = millis(); 462 | return (rc == 1+llen+length); 463 | #endif 464 | } 465 | 466 | boolean PubSubClient::subscribe(const char* topic) { 467 | return subscribe(topic, 0); 468 | } 469 | 470 | boolean PubSubClient::subscribe(const char* topic, uint8_t qos) { 471 | if (qos < 0 || qos > 1) { 472 | return false; 473 | } 474 | if (MQTT_MAX_PACKET_SIZE < 9 + strlen(topic)) { 475 | // Too long 476 | return false; 477 | } 478 | if (connected()) { 479 | // Leave room in the buffer for header and variable length field 480 | uint16_t length = 5; 481 | nextMsgId++; 482 | if (nextMsgId == 0) { 483 | nextMsgId = 1; 484 | } 485 | buffer[length++] = (nextMsgId >> 8); 486 | buffer[length++] = (nextMsgId & 0xFF); 487 | length = writeString((char*)topic, buffer,length); 488 | buffer[length++] = qos; 489 | return write(MQTTSUBSCRIBE|MQTTQOS1,buffer,length-5); 490 | } 491 | return false; 492 | } 493 | 494 | boolean PubSubClient::unsubscribe(const char* topic) { 495 | if (MQTT_MAX_PACKET_SIZE < 9 + strlen(topic)) { 496 | // Too long 497 | return false; 498 | } 499 | if (connected()) { 500 | uint16_t length = 5; 501 | nextMsgId++; 502 | if (nextMsgId == 0) { 503 | nextMsgId = 1; 504 | } 505 | buffer[length++] = (nextMsgId >> 8); 506 | buffer[length++] = (nextMsgId & 0xFF); 507 | length = writeString(topic, buffer,length); 508 | return write(MQTTUNSUBSCRIBE|MQTTQOS1,buffer,length-5); 509 | } 510 | return false; 511 | } 512 | 513 | void PubSubClient::disconnect() { 514 | buffer[0] = MQTTDISCONNECT; 515 | buffer[1] = 0; 516 | _client->write(buffer,2); 517 | _state = MQTT_DISCONNECTED; 518 | _client->stop(); 519 | lastInActivity = lastOutActivity = millis(); 520 | } 521 | 522 | uint16_t PubSubClient::writeString(const char* string, uint8_t* buf, uint16_t pos) { 523 | const char* idp = string; 524 | uint16_t i = 0; 525 | pos += 2; 526 | while (*idp) { 527 | buf[pos++] = *idp++; 528 | i++; 529 | } 530 | buf[pos-i-2] = (i >> 8); 531 | buf[pos-i-1] = (i & 0xFF); 532 | return pos; 533 | } 534 | 535 | 536 | boolean PubSubClient::connected() { 537 | boolean rc; 538 | if (_client == NULL ) { 539 | rc = false; 540 | } else { 541 | rc = (int)_client->connected(); 542 | if (!rc) { 543 | if (this->_state == MQTT_CONNECTED) { 544 | this->_state = MQTT_CONNECTION_LOST; 545 | _client->flush(); 546 | _client->stop(); 547 | } 548 | } 549 | } 550 | return rc; 551 | } 552 | 553 | PubSubClient& PubSubClient::setServer(uint8_t * ip, uint16_t port) { 554 | IPAddress addr(ip[0],ip[1],ip[2],ip[3]); 555 | return setServer(addr,port); 556 | } 557 | 558 | PubSubClient& PubSubClient::setServer(IPAddress ip, uint16_t port) { 559 | this->ip = ip; 560 | this->port = port; 561 | this->domain = NULL; 562 | return *this; 563 | } 564 | 565 | PubSubClient& PubSubClient::setServer(const char * domain, uint16_t port) { 566 | this->domain = domain; 567 | this->port = port; 568 | return *this; 569 | } 570 | 571 | PubSubClient& PubSubClient::setCallback(MQTT_CALLBACK_SIGNATURE) { 572 | this->callback = callback; 573 | return *this; 574 | } 575 | 576 | PubSubClient& PubSubClient::setClient(Client& client){ 577 | this->_client = &client; 578 | return *this; 579 | } 580 | 581 | PubSubClient& PubSubClient::setStream(Stream& stream){ 582 | this->stream = &stream; 583 | return *this; 584 | } 585 | 586 | int PubSubClient::state() { 587 | return this->_state; 588 | } 589 | -------------------------------------------------------------------------------- /ESP8266_homkit_switch/ESP8266_homkit_switch.ino/PubSubClient.h: -------------------------------------------------------------------------------- 1 | /* 2 | PubSubClient.h - A simple client for MQTT. 3 | Nick O'Leary 4 | http://knolleary.net 5 | */ 6 | 7 | #ifndef PubSubClient_h 8 | #define PubSubClient_h 9 | 10 | #include 11 | #include "IPAddress.h" 12 | #include "Client.h" 13 | #include "Stream.h" 14 | 15 | #define MQTT_VERSION_3_1 3 16 | #define MQTT_VERSION_3_1_1 4 17 | 18 | // MQTT_VERSION : Pick the version 19 | //#define MQTT_VERSION MQTT_VERSION_3_1 20 | #ifndef MQTT_VERSION 21 | #define MQTT_VERSION MQTT_VERSION_3_1_1 22 | #endif 23 | 24 | // MQTT_MAX_PACKET_SIZE : Maximum packet size 25 | #ifndef MQTT_MAX_PACKET_SIZE 26 | #define MQTT_MAX_PACKET_SIZE 128 27 | #endif 28 | 29 | // MQTT_KEEPALIVE : keepAlive interval in Seconds 30 | #ifndef MQTT_KEEPALIVE 31 | #define MQTT_KEEPALIVE 15 32 | #endif 33 | 34 | // MQTT_SOCKET_TIMEOUT: socket timeout interval in Seconds 35 | #ifndef MQTT_SOCKET_TIMEOUT 36 | #define MQTT_SOCKET_TIMEOUT 15 37 | #endif 38 | 39 | // MQTT_MAX_TRANSFER_SIZE : limit how much data is passed to the network client 40 | // in each write call. Needed for the Arduino Wifi Shield. Leave undefined to 41 | // pass the entire MQTT packet in each write call. 42 | //#define MQTT_MAX_TRANSFER_SIZE 80 43 | 44 | // Possible values for client.state() 45 | #define MQTT_CONNECTION_TIMEOUT -4 46 | #define MQTT_CONNECTION_LOST -3 47 | #define MQTT_CONNECT_FAILED -2 48 | #define MQTT_DISCONNECTED -1 49 | #define MQTT_CONNECTED 0 50 | #define MQTT_CONNECT_BAD_PROTOCOL 1 51 | #define MQTT_CONNECT_BAD_CLIENT_ID 2 52 | #define MQTT_CONNECT_UNAVAILABLE 3 53 | #define MQTT_CONNECT_BAD_CREDENTIALS 4 54 | #define MQTT_CONNECT_UNAUTHORIZED 5 55 | 56 | #define MQTTCONNECT 1 << 4 // Client request to connect to Server 57 | #define MQTTCONNACK 2 << 4 // Connect Acknowledgment 58 | #define MQTTPUBLISH 3 << 4 // Publish message 59 | #define MQTTPUBACK 4 << 4 // Publish Acknowledgment 60 | #define MQTTPUBREC 5 << 4 // Publish Received (assured delivery part 1) 61 | #define MQTTPUBREL 6 << 4 // Publish Release (assured delivery part 2) 62 | #define MQTTPUBCOMP 7 << 4 // Publish Complete (assured delivery part 3) 63 | #define MQTTSUBSCRIBE 8 << 4 // Client Subscribe request 64 | #define MQTTSUBACK 9 << 4 // Subscribe Acknowledgment 65 | #define MQTTUNSUBSCRIBE 10 << 4 // Client Unsubscribe request 66 | #define MQTTUNSUBACK 11 << 4 // Unsubscribe Acknowledgment 67 | #define MQTTPINGREQ 12 << 4 // PING Request 68 | #define MQTTPINGRESP 13 << 4 // PING Response 69 | #define MQTTDISCONNECT 14 << 4 // Client is Disconnecting 70 | #define MQTTReserved 15 << 4 // Reserved 71 | 72 | #define MQTTQOS0 (0 << 1) 73 | #define MQTTQOS1 (1 << 1) 74 | #define MQTTQOS2 (2 << 1) 75 | 76 | #ifdef ESP8266 77 | #include 78 | #define MQTT_CALLBACK_SIGNATURE std::function callback 79 | #else 80 | #define MQTT_CALLBACK_SIGNATURE void (*callback)(char*, uint8_t*, unsigned int) 81 | #endif 82 | 83 | class PubSubClient { 84 | private: 85 | Client* _client; 86 | uint8_t buffer[MQTT_MAX_PACKET_SIZE]; 87 | uint16_t nextMsgId; 88 | unsigned long lastOutActivity; 89 | unsigned long lastInActivity; 90 | bool pingOutstanding; 91 | MQTT_CALLBACK_SIGNATURE; 92 | uint16_t readPacket(uint8_t*); 93 | boolean readByte(uint8_t * result); 94 | boolean readByte(uint8_t * result, uint16_t * index); 95 | boolean write(uint8_t header, uint8_t* buf, uint16_t length); 96 | uint16_t writeString(const char* string, uint8_t* buf, uint16_t pos); 97 | IPAddress ip; 98 | const char* domain; 99 | uint16_t port; 100 | Stream* stream; 101 | int _state; 102 | public: 103 | PubSubClient(); 104 | PubSubClient(Client& client); 105 | PubSubClient(IPAddress, uint16_t, Client& client); 106 | PubSubClient(IPAddress, uint16_t, Client& client, Stream&); 107 | PubSubClient(IPAddress, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client); 108 | PubSubClient(IPAddress, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&); 109 | PubSubClient(uint8_t *, uint16_t, Client& client); 110 | PubSubClient(uint8_t *, uint16_t, Client& client, Stream&); 111 | PubSubClient(uint8_t *, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client); 112 | PubSubClient(uint8_t *, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&); 113 | PubSubClient(const char*, uint16_t, Client& client); 114 | PubSubClient(const char*, uint16_t, Client& client, Stream&); 115 | PubSubClient(const char*, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client); 116 | PubSubClient(const char*, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&); 117 | 118 | PubSubClient& setServer(IPAddress ip, uint16_t port); 119 | PubSubClient& setServer(uint8_t * ip, uint16_t port); 120 | PubSubClient& setServer(const char * domain, uint16_t port); 121 | PubSubClient& setCallback(MQTT_CALLBACK_SIGNATURE); 122 | PubSubClient& setClient(Client& client); 123 | PubSubClient& setStream(Stream& stream); 124 | 125 | boolean connect(const char* id); 126 | boolean connect(const char* id, const char* user, const char* pass); 127 | boolean connect(const char* id, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage); 128 | boolean connect(const char* id, const char* user, const char* pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage); 129 | void disconnect(); 130 | boolean publish(const char* topic, const char* payload); 131 | boolean publish(const char* topic, const char* payload, boolean retained); 132 | boolean publish(const char* topic, const uint8_t * payload, unsigned int plength); 133 | boolean publish(const char* topic, const uint8_t * payload, unsigned int plength, boolean retained); 134 | boolean publish_P(const char* topic, const uint8_t * payload, unsigned int plength, boolean retained); 135 | boolean subscribe(const char* topic); 136 | boolean subscribe(const char* topic, uint8_t qos); 137 | boolean unsubscribe(const char* topic); 138 | boolean loop(); 139 | boolean connected(); 140 | int state(); 141 | }; 142 | 143 | 144 | #endif 145 | -------------------------------------------------------------------------------- /ESP8266_homkit_switch/ESP8266_homkit_switch.ino/README.md: -------------------------------------------------------------------------------- 1 | # Apple HomeKit programmable switch 2 | use a 3rd party HomeKit app like Elgato EVE since programmabile switch is not yet supported in Apple Home app, one configured you can use it through the Home app 3 | 4 | ![scheme](https://github.com/Supersimo88/Arduino-ESP8266-HomeKit/blob/master/ESP8266_homkit_switch/ESP8266_homkit_switch.ino/Resources/Switch.jpg) 5 | -------------------------------------------------------------------------------- /ESP8266_homkit_switch/ESP8266_homkit_switch.ino/Resources/Switch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Supersimo88/Arduino-ESP8266-HomeKit/8dce60573587cb245d3ca042adf26854feb60ecb/ESP8266_homkit_switch/ESP8266_homkit_switch.ino/Resources/Switch.jpg -------------------------------------------------------------------------------- /NeoPixel/NeoPixel.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define PIN D8 10 | Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800); 11 | 12 | const char* ssid = "___"; // your WiFi ssid 13 | const char* password = "___"; // your WiFi password 14 | const char* host = "officelight"; // the name of your fixture, and the base channel to listen to 15 | IPAddress MQTTserver(192, 168, 1, 1); // your MQTT server IP 16 | #define HOSTNAME "ESP8266-OTA-LIGHT-" 17 | 18 | /* NO NEED TO CHANGE BENEATH THIS LINE */ 19 | int hue = 0; 20 | float brightness = 0.0; 21 | float brightnessold = 1.0; 22 | float saturation = 0.0; 23 | 24 | #define BUFFER_SIZE 100 25 | 26 | WiFiClient wclient; 27 | PubSubClient client(wclient, MQTTserver); 28 | 29 | 30 | void callback(const MQTT::Publish& pub) { 31 | 32 | uint16_t i, j; 33 | 34 | currentValues(); 35 | String myMessage = String(pub.payload_string()); 36 | // handle message arrived 37 | Serial.print(pub.topic()); 38 | Serial.print(" => "); 39 | String myTopic = String(pub.topic()); 40 | 41 | 42 | if(myTopic == host) 43 | { 44 | 45 | Serial.println(pub.payload_string()); 46 | 47 | if(pub.payload_string() == "on") 48 | { 49 | 50 | // use this to reset parameters if you want them to always come on bright white. 51 | //hue = 0; 52 | //brightness = 1.0; 53 | brightness = brightnessold; 54 | //saturation = 0.0; 55 | 56 | 57 | for(i=0; i. 20 | */ 21 | 22 | #include "ESPHelper.h" 23 | 24 | netInfo homeNet = {.name = "NETWORK NICKNAME", .mqtt = "YOUR MQTT-IP", .ssid = "YOUR SSID", .pass = "YOUR NETWORK PASS"}; 25 | 26 | ESPHelper myESP(&homeNet); 27 | 28 | void setup() { 29 | 30 | Serial.begin(115200); //start the serial line 31 | delay(500); 32 | 33 | Serial.println("Starting Up, Please Wait..."); 34 | 35 | myESP.OTA_enable(); 36 | myESP.OTA_setPassword("SET OTA PASSWORD"); 37 | myESP.OTA_setHostnameWithVersion("SET OTA HOSTNAME"); 38 | 39 | myESP.addSubscription("/test"); 40 | 41 | myESP.begin(); 42 | myESP.setCallback(callback); //can only set callback after begin method. Calling before begin() will not set the callback (return false) 43 | 44 | Serial.println("Initialization Finished."); 45 | } 46 | 47 | void loop(){ 48 | myESP.loop(); //run the loop() method as often as possible - this keeps the network services running 49 | 50 | //Put application code here 51 | 52 | yield(); 53 | } 54 | 55 | void callback(char* topic, uint8_t* payload, unsigned int length) { 56 | //put mqtt callback code here 57 | } -------------------------------------------------------------------------------- /RGBStrip/Arduino/libraries/ESPHelper-master/examples/RGBLight/RGBLight.ino: -------------------------------------------------------------------------------- 1 | /* 2 | wifiRGB.ino 3 | Copyright (c) 2016 ItKindaWorks All right reserved. 4 | github.com/ItKindaWorks 5 | 6 | This file is part of wifiRGB 7 | 8 | wifiRGB is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | wifiRGB is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with wifiRGB. If not, see . 20 | */ 21 | 22 | /* 23 | This is an MQTT RGB light controller program for the ESP8266. 24 | The light can be controlled in one of three ways. You can send 25 | an HSB update, RGB update, or moodlight mode on/off. 26 | All updates must be formatted correctly, see below: 27 | 28 | ex RGB string: "r255,050,000" (r = 255, g = 050, b = 000) 29 | ex HSB string: "h1.00,0.50,0.01" (h = 1.00, s = 0.50, b = 0.01) 30 | ex moodlight string: "m1" (moodlight activate) 31 | 32 | This program also posts a status update to the status topic 33 | which is the lightTopic plus "/status" (ex. if the lightTopic 34 | is "/home/RGBlight" then the statusTopic would be "home/RGBlight/status") 35 | */ 36 | 37 | #include "ESPHelper.h" 38 | #include 39 | #include "Metro.h" 40 | 41 | #define TOPIC "/your/mqtt/topic" 42 | #define STATUS TOPIC "/status" 43 | #define NETWORK_HOSTNAME "YOUR OTA HOSTNAME" 44 | #define OTA_PASSWORD "YOUR OTA PASSWORD" 45 | 46 | #define RED_PIN 12 47 | #define GREEN_PIN 13 48 | #define BLUE_PIN 14 49 | 50 | typedef struct lightState{ 51 | double hue; 52 | double saturation; 53 | double brightness; 54 | int red; 55 | int redRate; 56 | int green; 57 | int greenRate; 58 | int blue; 59 | int blueRate; 60 | int fadePeriod; 61 | int updateType; 62 | }; 63 | 64 | typedef struct timer { 65 | unsigned long previousTime; 66 | int interval; 67 | }; 68 | 69 | 70 | 71 | enum superModes {SET, MOOD}; 72 | enum moodColors{RED, GREEN, BLUE}; 73 | enum modes {NORMAL, FADING}; 74 | enum updateTypes{HSB, RGB, POWER}; 75 | 76 | 77 | lightState nextState; 78 | 79 | int superMode = SET; //overall mode of the light (moodlight, network controlled, etc) 80 | boolean newCommand = false; 81 | 82 | 83 | char* lightTopic = TOPIC; 84 | char* statusTopic = STATUS; 85 | char* hostnameStr = NETWORK_HOSTNAME; 86 | 87 | const int redPin = RED_PIN; 88 | const int greenPin = GREEN_PIN; 89 | const int bluePin = BLUE_PIN; 90 | 91 | char statusString[50]; //string containing the current setting for the light 92 | 93 | 94 | //set this info for your own network 95 | netInfo homeNet = {.name = "NETWORK NICKNAME", .mqtt = "YOUR MQTT-IP", .ssid = "YOUR SSID", .pass = "YOUR NETWORK PASS"}; 96 | 97 | ESPHelper myESP(&homeNet); 98 | 99 | 100 | void setup() { 101 | //initialize the light as an output and set to LOW (off) 102 | pinMode(redPin, OUTPUT); 103 | pinMode(bluePin, OUTPUT); 104 | pinMode(greenPin, OUTPUT); 105 | 106 | //all off 107 | digitalWrite(redPin, LOW); //all off 108 | digitalWrite(greenPin, LOW); 109 | digitalWrite(bluePin, LOW); 110 | 111 | delay(1000); 112 | 113 | colorTest(); 114 | 115 | //setup ota on esphelper 116 | myESP.OTA_enable(); 117 | myESP.OTA_setPassword(OTA_PASSWORD); 118 | myESP.OTA_setHostnameWithVersion(hostnameStr); 119 | 120 | //subscribe to the lighttopic 121 | myESP.addSubscription(lightTopic); 122 | myESP.begin(); 123 | myESP.setCallback(callback); 124 | } 125 | 126 | 127 | 128 | void loop(){ 129 | static bool connected = false; //keeps track of connection state to reset from MOOD to SET when network connection is made 130 | 131 | 132 | if(myESP.loop() == FULL_CONNECTION){ 133 | 134 | //if the light was previously not connected to wifi and mqtt, update the status topic with the light being off 135 | if(!connected){ 136 | connected = true; //we have reconnected so now we dont need to flag the setting anymore 137 | myESP.publish(statusTopic, "h0.00,0.00,0.00 ", true); 138 | } 139 | 140 | lightHandler(); 141 | } 142 | 143 | 144 | yield(); 145 | } 146 | 147 | 148 | void lightHandler(){ 149 | //new and current lightStates 150 | static lightState newState; 151 | static lightState currentState; 152 | 153 | static int currentMoodColor = 0; //the current moodlight chosen color 154 | 155 | static int isFading = 0; 156 | 157 | 158 | //if the super mode is mood light and the light isnt currently fading, 159 | //then change to a new color and start a new fade 160 | if(superMode == MOOD && isFading == 0){ 161 | if(currentMoodColor == RED){ 162 | nextState.red = 0; 163 | nextState.green = 1023; 164 | nextState.blue = 0; 165 | nextState.updateType = RGB; 166 | newCommand = true; 167 | currentMoodColor = GREEN; 168 | 169 | } 170 | else if(currentMoodColor == GREEN){ 171 | nextState.red = 0; 172 | nextState.green = 0; 173 | nextState.blue = 1023; 174 | nextState.updateType = RGB; 175 | newCommand = true; 176 | currentMoodColor = BLUE; 177 | } 178 | else if(currentMoodColor == BLUE){ 179 | nextState.red = 1023; 180 | nextState.green = 0; 181 | nextState.blue = 0; 182 | nextState.updateType = RGB; 183 | newCommand = true; 184 | currentMoodColor = RED; 185 | } 186 | } 187 | 188 | lightUpdater(&newState, currentState); 189 | isFading = lightChanger(newState, ¤tState); 190 | 191 | } 192 | 193 | 194 | //this function actually changes the light values and does the fading 195 | //returns 1 if fading 196 | //returns 0 if not fading 197 | //returns -1 if the timer doesnt get triggered 198 | int lightChanger(lightState newState, lightState *currentState){ 199 | static Metro changeTimer = Metro(1); 200 | 201 | static int changeMode = NORMAL; //the current mode (fading or normal) 202 | static int currentPeriod = 0; //time since starting the fade 203 | 204 | 205 | //only allow fade updates every 1ms 206 | if(changeTimer.check()){ 207 | 208 | //check to see if this is there is a new command and set the mode to FADING 209 | if(newCommand){ 210 | newCommand = false; 211 | changeMode = FADING; 212 | } 213 | 214 | 215 | 216 | if(changeMode == FADING){ 217 | 218 | //check whether or not a fade is needed - if so update the channel velues 219 | if((newState.red != currentState->red || newState.blue != currentState->blue || newState.green != currentState->green) || (currentPeriod <= currentState->fadePeriod)){ 220 | 221 | if(currentPeriod % newState.redRate == 0){ 222 | if(newState.red > currentState->red){currentState->red++;} 223 | else if (newState.red < currentState->red){currentState->red--;} 224 | } 225 | 226 | if(currentPeriod % newState.greenRate == 0){ 227 | if(newState.green > currentState->green){currentState->green++;} 228 | else if (newState.green < currentState->green){currentState->green--;} 229 | } 230 | 231 | if(currentPeriod % newState.blueRate == 0){ 232 | if(newState.blue > currentState->blue){currentState->blue++;} 233 | else if (newState.blue < currentState->blue){currentState->blue--;} 234 | } 235 | 236 | //write to the analog pins 237 | analogWrite(redPin, currentState->red); 238 | analogWrite(greenPin, currentState->green); 239 | analogWrite(bluePin, currentState->blue); 240 | 241 | //increment the period 242 | currentPeriod++; 243 | return 1; //return 1 on mode being FADING 244 | } 245 | 246 | //if no fade is needed then reset the period and set the mode to NORMAL 247 | else{ 248 | currentPeriod = 0; 249 | changeMode = NORMAL; 250 | return 0; //return 0 on mode being NORMAL 251 | } 252 | 253 | } 254 | 255 | 256 | else if (changeMode == NORMAL){ 257 | return 0; //return 0 on mode being NORMAL 258 | } 259 | 260 | } 261 | 262 | return -1; //return -1 on timer not set off 263 | 264 | } 265 | 266 | //calculates new information (color values, fade times, etc) for 267 | //new color updates 268 | void lightUpdater (lightState *newState, lightState currentState){ 269 | 270 | //calculate new vars only if there is a new command 271 | if (newCommand){ 272 | 273 | //determine which kind of update this is 274 | if(nextState.updateType == HSB){ 275 | 276 | //convert from HSB to RGB 277 | int newRGB[3]; 278 | H2R_HSBtoRGBfloat(nextState.hue, nextState.saturation, nextState.brightness, newRGB); 279 | newState->red = newRGB[0]; 280 | newState->green = newRGB[1]; 281 | newState->blue = newRGB[2]; 282 | 283 | //determine the RGB difference from the current values to new values (how far each channel needs to fade) 284 | int redDiff = abs(newState->red - currentState.red); 285 | int greenDiff = abs(newState->green - currentState.green); 286 | int blueDiff = abs(newState->blue - currentState.blue); 287 | 288 | //calculate the new fade times for each channel (how long to wait between fading up/down) 289 | if(redDiff > 0){newState->redRate = (nextState.fadePeriod / redDiff);} 290 | else{newState->redRate = nextState.fadePeriod;} 291 | 292 | if(greenDiff > 0){newState->greenRate = (nextState.fadePeriod / greenDiff);} 293 | else{newState->greenRate = nextState.fadePeriod;} 294 | 295 | if(blueDiff > 0){newState->blueRate = (nextState.fadePeriod / blueDiff);} 296 | else{newState->blueRate = nextState.fadePeriod;} 297 | 298 | //set the total time to fade 299 | newState->fadePeriod = nextState.fadePeriod; 300 | 301 | } 302 | else if(nextState.updateType == RGB){ 303 | 304 | //set new RGB values from update 305 | newState->red = nextState.red; 306 | newState->green = nextState.green; 307 | newState->blue = nextState.blue; 308 | 309 | //determine the RGB difference from the current values to new values (how far each channel needs to fade) 310 | int redDiff = abs(newState->red - currentState.red); 311 | int greenDiff = abs(newState->green - currentState.green); 312 | int blueDiff = abs(newState->blue - currentState.blue); 313 | 314 | //calculate the new fade times for each channel (how long to wait between fading up/down) 315 | if(redDiff > 0){newState->redRate = (nextState.fadePeriod / redDiff) + 1;} 316 | else{newState->redRate = nextState.fadePeriod;} 317 | 318 | if(greenDiff > 0){newState->greenRate = (nextState.fadePeriod / greenDiff) + 1;} 319 | else{newState->greenRate = nextState.fadePeriod;} 320 | 321 | if(blueDiff > 0){newState->blueRate = (nextState.fadePeriod / blueDiff) + 1;} 322 | else{newState->blueRate = nextState.fadePeriod;} 323 | 324 | //set the total time to fade 325 | newState->fadePeriod = nextState.fadePeriod; 326 | 327 | } 328 | } 329 | 330 | } 331 | 332 | 333 | 334 | //MQTT callback 335 | void callback(char* topic, byte* payload, unsigned int length) { 336 | 337 | //convert topic to string to make it easier to work with 338 | String topicStr = topic; 339 | 340 | char newPayload[40]; 341 | memcpy(newPayload, payload, length); 342 | newPayload[length] = '\0'; 343 | 344 | //handle HSB updates 345 | if(payload[0] == 'h'){ 346 | nextState.hue = atof(&newPayload[1]); 347 | nextState.saturation = atof(&newPayload[7]); 348 | nextState.brightness = atof(&newPayload[13]); 349 | 350 | nextState.updateType = HSB; 351 | nextState.fadePeriod = 2100; 352 | newCommand = true; 353 | superMode = SET; 354 | 355 | } 356 | 357 | //handle RGB updates 358 | else if (payload[0] == 'r'){ 359 | int newRed = atoi(&newPayload[1]); 360 | int newGreen = atoi(&newPayload[5]); 361 | int newBlue = atoi(&newPayload[9]); 362 | 363 | nextState.red = newRed; 364 | nextState.green = newGreen; 365 | nextState.blue = newBlue; 366 | 367 | nextState.updateType = RGB; 368 | newCommand = true; 369 | nextState.fadePeriod = 2100; 370 | superMode = SET; 371 | } 372 | 373 | //handle moodlight updates 374 | else if(payload[0] == 'm'){ 375 | 376 | if(payload[1] == '1'){ 377 | superMode = MOOD; 378 | nextState.fadePeriod = 10000; 379 | newCommand = true; 380 | } 381 | else if(payload[1] == '0'){ 382 | superMode = SET; 383 | nextState.fadePeriod = 2100; 384 | newCommand = true; 385 | } 386 | } 387 | 388 | 389 | //package up status message reply and send it back out to the status topic 390 | strcpy(statusString, newPayload); 391 | myESP.publish(statusTopic, statusString, true); 392 | } 393 | 394 | 395 | 396 | 397 | void colorTest(){ 398 | digitalWrite(redPin, HIGH); //red on 399 | delay(500); 400 | digitalWrite(redPin, LOW); //green on 401 | digitalWrite(greenPin, HIGH); 402 | delay(500); 403 | digitalWrite(greenPin, LOW); //blue on 404 | digitalWrite(bluePin, HIGH); 405 | delay(500); 406 | 407 | digitalWrite(redPin, HIGH); //all on 408 | digitalWrite(greenPin, HIGH); 409 | digitalWrite(bluePin, HIGH); 410 | delay(500); 411 | digitalWrite(redPin, LOW); //all off 412 | digitalWrite(greenPin, LOW); 413 | digitalWrite(bluePin, LOW); 414 | } 415 | 416 | 417 | char *ftoa(char *a, double f, int precision) 418 | { 419 | long p[] = {0,10,100,1000,10000,100000,1000000,10000000,100000000}; 420 | 421 | char *ret = a; 422 | long heiltal = (long)f; 423 | itoa(heiltal, a, 10); 424 | while (*a != '\0') a++; 425 | *a++ = '.'; 426 | long desimal = abs((long)((f - heiltal) * p[precision])); 427 | itoa(desimal, a, 10); 428 | return ret; 429 | } 430 | 431 | 432 | 433 | 434 | float map_double(double x, double in_min, double in_max, double out_min, double out_max) 435 | { 436 | return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; 437 | } 438 | 439 | 440 | -------------------------------------------------------------------------------- /RGBStrip/Arduino/libraries/ESPHelper-master/examples/RelayControlV2/RelayControlV2.ino: -------------------------------------------------------------------------------- 1 | #include "ESPHelper.h" 2 | 3 | #define TOPIC "/your/mqtt/topic" 4 | #define STATUS TOPIC "/status" //dont change this - this is for the status topic which is whatever your mqtt topic is plus /status (ex /home/light/status) 5 | 6 | #define NETWORK_HOSTNAME "YOUR OTA HOST NAME" 7 | #define OTA_PASSWORD "YOUR OTA PASSWORD" 8 | 9 | #define RELAY_PIN 3 //rx pin on esp 10 | #define BLINK_PIN 1 //tx/led on esp-01 11 | #define BUTTON_PIN 0 12 | 13 | 14 | char* relayTopic = TOPIC; 15 | char* statusTopic = STATUS; 16 | char* hostnameStr = NETWORK_HOSTNAME; 17 | char* otaPassword = OTA_PASSWORD; 18 | 19 | //initialized the pins 20 | const int buttonPin = BUTTON_PIN; 21 | const int relayPin = RELAY_PIN; 22 | const int blinkPin = BLINK_PIN; 23 | 24 | //this is the current state of the relay 25 | bool currentState = false; 26 | 27 | //flag to mark when a rising edge has been detected 28 | bool risingEdge = false; 29 | 30 | //keeps track of the previous button state for edge detection 31 | bool lastButtonState = false; 32 | 33 | //set this info for your own network 34 | netInfo homeNet = {.name = "NETWORK NICKNAME", .mqtt = "YOUR MQTT-IP", .ssid = "YOUR SSID", .pass = "YOUR NETWORK PASS"}; 35 | 36 | ESPHelper myESP(&homeNet); 37 | 38 | 39 | void setup() { 40 | 41 | //setup Arduino OTA 42 | myESP.OTA_enable(); 43 | myESP.OTA_setPassword(otaPassword); 44 | myESP.OTA_setHostnameWithVersion(hostnameStr); 45 | 46 | //enable the connection heartbeat 47 | myESP.enableHeartbeat(blinkPin); 48 | 49 | //add a subscription to the relatTopic 50 | myESP.addSubscription(relayTopic); 51 | 52 | //start ESPHelper 53 | myESP.begin(); 54 | 55 | //add in the MQTT callback 56 | myESP.setCallback(callback); 57 | 58 | //set the button as an input 59 | pinMode(buttonPin, INPUT); 60 | 61 | //set the relay pin as an output and set to off 62 | pinMode(relayPin, OUTPUT); 63 | digitalWrite(relayPin, LOW); 64 | } 65 | 66 | 67 | void loop(){ 68 | if(myESP.loop() == FULL_CONNECTION){ 69 | 70 | //read the state of the button (LOW is pressed) 71 | bool buttonState = digitalRead(buttonPin); 72 | 73 | //if the button is pressed (LOW) and previously was not pressed(HIGH) 74 | if(buttonState == LOW && lastButtonState == HIGH){ 75 | 76 | //debounce the signal and if the button is still pressed, mark as a rising edge 77 | delay(50); 78 | if(digitalRead(buttonPin) == LOW){ 79 | lastButtonState = LOW; 80 | risingEdge = true; 81 | } 82 | 83 | } 84 | 85 | //else if the button is not pressed and set lastButtonState to HIGH and reset the rising edge flag 86 | else if(buttonState == HIGH){ 87 | lastButtonState = HIGH; 88 | risingEdge = false; 89 | } 90 | 91 | 92 | //rising edge detected 93 | if(risingEdge){ 94 | 95 | //set the state to the opposite of the current state 96 | setState(!currentState); 97 | 98 | //reset the rising edge flag 99 | risingEdge = false; 100 | 101 | } 102 | } 103 | yield(); 104 | } 105 | 106 | 107 | void callback(char* topic, byte* payload, unsigned int length) { 108 | if(payload[0] == '1'){ 109 | setState(true); 110 | } 111 | else{ 112 | setState(false); 113 | } 114 | } 115 | 116 | //sets a new state for the relay and publishes to MQTT 117 | void setState(bool newState){ 118 | 119 | //dont do anything unless the newState and currentState are different 120 | if(newState != currentState){ 121 | 122 | //set the current state 123 | currentState = newState; 124 | 125 | //publish to the MQTT status topic 126 | if(currentState){myESP.publish(statusTopic, "1", true);} 127 | else{myESP.publish(statusTopic, "0", true);} 128 | 129 | //set the relay on or off 130 | digitalWrite(relayPin, currentState); 131 | } 132 | } 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /RGBStrip/Arduino/libraries/ESPHelper-master/examples/basicUse/basicUse.ino: -------------------------------------------------------------------------------- 1 | /* 2 | basicUse.ino 3 | Copyright (c) 2016 ItKindaWorks All right reserved. 4 | github.com/ItKindaWorks 5 | 6 | This file is part of ESPHelper 7 | 8 | ESPHelper is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | ESPHelper is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with ESPHelper. If not, see . 20 | */ 21 | 22 | #include "ESPHelper.h" 23 | 24 | netInfo homeNet = {.name = "NETWORK NICKNAME", .mqtt = "YOUR MQTT-IP", .ssid = "YOUR SSID", .pass = "YOUR NETWORK PASS"}; 25 | 26 | ESPHelper myESP(&homeNet); 27 | 28 | void setup() { 29 | 30 | Serial.begin(115200); //start the serial line 31 | delay(500); 32 | 33 | Serial.println("Starting Up, Please Wait..."); 34 | 35 | myESP.addSubscription("/test"); 36 | 37 | myESP.begin(); 38 | myESP.setCallback(callback); //can only set callback after begin method. Calling before begin() will not set the callback (return false) 39 | 40 | Serial.println("Initialization Finished."); 41 | } 42 | 43 | void loop(){ 44 | myESP.loop(); //run the loop() method as often as possible - this keeps the network services running 45 | 46 | //Put application code here 47 | 48 | yield(); 49 | } 50 | 51 | void callback(char* topic, uint8_t* payload, unsigned int length) { 52 | //put mqtt callback code here 53 | } -------------------------------------------------------------------------------- /RGBStrip/Arduino/libraries/ESPHelper-master/examples/buttonDemo/buttonDemo.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 ItKindaWorks All right reserved. 3 | github.com/ItKindaWorks 4 | 5 | This file is part of ESPHelper 6 | 7 | ESPHelper is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | ESPHelper is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with ESPHelper. If not, see . 19 | */ 20 | 21 | /* 22 | This is a simple demo of an MQTT enabled button. A button is attahed 23 | to pin 0 with a pull-up resistor and each time the button is pressed, 24 | it toggles the state and publishes the new state to the MQTT broker. 25 | It is also subscribed to the same topic that it publishes to so that 26 | the state of the toggle can be updated from the MQTT side. 27 | */ 28 | #include "ESPHelper.h" 29 | 30 | #define TOPIC "/home/vSwitch1" 31 | #define NETWORK_HOSTNAME "switch1" 32 | #define OTA_PASSWORD "ENOMIS55" 33 | 34 | #define BUTTON_PIN D0 //button on pin 0 with pull up resistor (pulled low on press) 35 | #define BLINK_PIN D4 36 | 37 | 38 | char* buttonTopic = TOPIC; 39 | char* hostnameStr = NETWORK_HOSTNAME; 40 | 41 | const int buttonPin = BUTTON_PIN; 42 | const int blinkPin = BLINK_PIN; 43 | 44 | bool currentState = false; 45 | 46 | bool lastButtonState = false; 47 | 48 | //set this info for your own network 49 | netInfo homeNet = {.name = "switch", .mqtt = "192.168.1.19", .ssid = "Telecom-19250793", .pass = "yxsplyuvMmEMlS5vbg67MPK3"}; 50 | ESPHelper myESP(&homeNet); 51 | 52 | void setup() { 53 | //setup ota on esphelper 54 | myESP.OTA_enable(); 55 | myESP.OTA_setPassword(OTA_PASSWORD); 56 | myESP.OTA_setHostnameWithVersion(hostnameStr); 57 | 58 | //enable the connection heartbeat 59 | myESP.enableHeartbeat(blinkPin); 60 | 61 | //subscribe to the button topic (this allows outside control of the state of the switch) 62 | myESP.addSubscription(buttonTopic); 63 | 64 | //start ESPHelper 65 | myESP.begin(); 66 | 67 | //setup the mqtt callback function 68 | myESP.setCallback(callback); 69 | 70 | //set the button pin as an input 71 | pinMode(buttonPin, INPUT); 72 | } 73 | 74 | 75 | void loop(){ 76 | if(myESP.loop() == FULL_CONNECTION){ 77 | 78 | //read the button (low on press, high on release) 79 | bool buttonState = digitalRead(buttonPin); 80 | 81 | //if the button is pressed (LOW) and previously was not pressed(HIGH) 82 | if(buttonState == LOW && lastButtonState == HIGH){ 83 | //invert the current state 84 | currentState = !currentState; 85 | 86 | //publish to mqtt based on current state 87 | if(currentState){ 88 | myESP.publish(buttonTopic, "1", true); 89 | } 90 | else{ 91 | myESP.publish(buttonTopic, "0", true); 92 | } 93 | 94 | //set the lastButtonState to LOW to prevent multiple triggers 95 | lastButtonState = LOW; 96 | 97 | //wait half a second (poor mans debounce) 98 | delay(500); 99 | } 100 | 101 | //else if the button is not pressed and set lastButtonState to HIGH 102 | else if(buttonState == HIGH){lastButtonState = HIGH;} 103 | } 104 | yield(); 105 | } 106 | 107 | 108 | void callback(char* topic, byte* payload, unsigned int length) { 109 | 110 | //if the payload is '1' then set the state to true 111 | if(payload[0] == '1'){ 112 | currentState = true; 113 | } 114 | 115 | //otherwise set the current state to false 116 | else{ 117 | currentState = false; 118 | } 119 | } 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /RGBStrip/Arduino/libraries/ESPHelper-master/examples/multiNetwork/multiNetwork.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MultiNetwork.ino 3 | Copyright (c) 2016 ItKindaWorks All right reserved. 4 | github.com/ItKindaWorks 5 | 6 | This file is part of ESPHelper 7 | 8 | ESPHelper is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | ESPHelper is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with ESPHelper. If not, see . 20 | */ 21 | 22 | #include "ESPHelper.h" 23 | 24 | 25 | netInfo homeNet1 = {.name = "NETWORK NICKNAME1", .mqtt = "YOUR MQTT-IP1", .ssid = "YOUR SSID1", .pass = "YOUR NETWORK PASS1"}; 26 | netInfo homeNet2 = {.name = "NETWORK NICKNAME2", .mqtt = "YOUR MQTT-IP2", .ssid = "YOUR SSID2", .pass = "YOUR NETWORK PASS2"}; 27 | netInfo homeNet3 = {.name = "NETWORK NICKNAME3", .mqtt = "YOUR MQTT-IP3", .ssid = "YOUR SSID3", .pass = "YOUR NETWORK PASS3"}; 28 | 29 | netInfo *knownNetworks[3] = { 30 | &homeNet1, 31 | &homeNet2, 32 | &homeNet3 33 | }; 34 | 35 | ESPHelper myESP(knownNetworks, 3); 36 | 37 | void setup() { 38 | 39 | Serial.begin(115200); //start the serial line 40 | delay(500); 41 | 42 | Serial.println("Starting Up, Please Wait..."); 43 | 44 | // myESP.setHopping(false); //uncomment to prevent hopping between networks in network array 45 | 46 | myESP.addSubscription("/test"); 47 | 48 | myESP.begin(); 49 | myESP.setCallback(callback); //can only set callback after begin method. Calling before begin() will not set the callback (return false) 50 | 51 | Serial.println("Initialization Finished."); 52 | } 53 | 54 | void loop(){ 55 | myESP.loop(); //run the loop() method as often as possible - this keeps the network services running 56 | 57 | //Put application code here 58 | 59 | yield(); 60 | } 61 | 62 | void callback(char* topic, uint8_t* payload, unsigned int length) { 63 | //put mqtt callback code here 64 | } -------------------------------------------------------------------------------- /RGBStrip/Arduino/libraries/ESPHelper-master/examples/relayControl/relayControl.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 ItKindaWorks All right reserved. 3 | github.com/ItKindaWorks 4 | 5 | This file is part of RelayControl 6 | 7 | RelayControl is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | RelayControl is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with RelayControl. If not, see . 19 | */ 20 | 21 | /* 22 | This is a simple MQTT relay/light controller program for the ESP8266. 23 | By sending a '1' or '0' to the relayTopic the relayPin can be toggled 24 | on or off. This program also posts a status update to the status topic 25 | which is the relayTopic plus "/status" (ex. if the relayTopic 26 | is "/home/light" then the statusTopic would be "home/light/status") 27 | */ 28 | 29 | #include "ESPHelper.h" 30 | 31 | #define TOPIC "/your/mqtt/topic" 32 | #define STATUS TOPIC "/status" //dont change this - this is for the status topic which is whatever your mqtt topic is plus /status (ex /home/light/status) 33 | 34 | #define NETWORK_HOSTNAME "YOUR OTA HOST NAME" 35 | #define OTA_PASSWORD "YOUR OTA PASSWORD" 36 | 37 | #define RELAY_PIN 3 //rx pin on esp 38 | #define BLINK_PIN 1 //tx/led on esp-01 39 | 40 | 41 | char* relayTopic = TOPIC; 42 | char* statusTopic = STATUS; 43 | char* hostnameStr = NETWORK_HOSTNAME; 44 | 45 | const int relayPin = RELAY_PIN; 46 | const int blinkPin = BLINK_PIN; //tx pin on esp 47 | 48 | //set this info for your own network 49 | netInfo homeNet = {.name = "NETWORK NICKNAME", .mqtt = "YOUR MQTT-IP", .ssid = "YOUR SSID", .pass = "YOUR NETWORK PASS"}; 50 | 51 | ESPHelper myESP(&homeNet); 52 | 53 | void setup() { 54 | //setup ota 55 | myESP.OTA_enable(); 56 | myESP.OTA_setPassword(OTA_PASSWORD); 57 | myESP.OTA_setHostnameWithVersion(hostnameStr); 58 | 59 | 60 | //setup the rest of ESPHelper 61 | myESP.enableHeartbeat(blinkPin); //comment out to disable the heartbeat 62 | myESP.addSubscription(relayTopic); //add the relay topic to the subscription list 63 | myESP.begin(); 64 | myESP.setCallback(callback); 65 | 66 | 67 | pinMode(relayPin, OUTPUT); 68 | delay(100); 69 | } 70 | 71 | 72 | void loop(){ 73 | //loop ESPHelper and wait for commands from mqtt 74 | myESP.loop(); 75 | yield(); 76 | } 77 | 78 | 79 | //mqtt callback 80 | void callback(char* topic, byte* payload, unsigned int length) { 81 | String topicStr = topic; 82 | 83 | //if the payload from mqtt was 1, turn the relay on and update the status topic with 1 84 | if(payload[0] == '1'){ 85 | digitalWrite(relayPin, HIGH); 86 | myESP.publish(statusTopic, "1",true); 87 | } 88 | 89 | //else turn the relay off and update the status topic with 0 90 | else if (payload[0] == '0'){ 91 | digitalWrite(relayPin, LOW); 92 | myESP.client.publish(statusTopic, "0", true); 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /RGBStrip/Arduino/libraries/ESPHelper-master/examples/temperatureSensor_ds18b20/temperatureSensor_ds18b20.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2016 ItKindaWorks All right reserved. 3 | github.com/ItKindaWorks 4 | 5 | This file is part of ESPHelper 6 | 7 | ESPHelper is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | ESPHelper is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with ESPHelper. If not, see . 19 | */ 20 | 21 | /* 22 | This is a simple program that periodically (10 seconds) reads a ds18b20 temperature 23 | sensor and publishes the result to an MQTT topic. Change the Topic/Hostname/OTA Password 24 | and network settings to match your system. 25 | */ 26 | 27 | #include "ESPHelper.h" 28 | #include 29 | #include 30 | #include 31 | 32 | #define TEMP_TOPIC "/your/mqtt/topic" 33 | #define NETWORK_HOSTNAME "YOUR OTA HOSTNAME" 34 | #define OTA_PASSWORD "YOUR OTA PASSWORD" 35 | 36 | #define ONE_WIRE_BUS 2 37 | #define BLINK_PIN 1 38 | 39 | char* tempTopic = TEMP_TOPIC; 40 | char* hostnameStr = NETWORK_HOSTNAME; 41 | const int wireBus = ONE_WIRE_BUS; 42 | const int blinkPin = BLINK_PIN; 43 | 44 | 45 | //the current temperature 46 | float currentTemp = 0; 47 | 48 | //timer to set how often the sensor should publish to mqtt (in ms) 49 | Metro publishTimer = Metro(10000); 50 | 51 | //ds18b20 variables 52 | OneWire oneWire(ONE_WIRE_BUS); 53 | DallasTemperature sensors(&oneWire); 54 | 55 | //set this info for your own network 56 | netInfo homeNet = {.name = "NETWORK NICKNAME", .mqtt = "YOUR MQTT-IP", .ssid = "YOUR SSID", .pass = "YOUR NETWORK PASS"}; 57 | ESPHelper myESP(&homeNet); 58 | 59 | void setup() { 60 | 61 | //setup ota on esphelper 62 | myESP.OTA_enable(); 63 | myESP.OTA_setPassword(OTA_PASSWORD); 64 | myESP.OTA_setHostnameWithVersion(hostnameStr); 65 | 66 | //enable the connection heartbeat 67 | myESP.enableHeartbeat(blinkPin); 68 | 69 | //start ESPHelper 70 | myESP.begin(); 71 | 72 | //start the dallas temperature sensor library 73 | sensors.begin(); 74 | delay(500); 75 | } 76 | 77 | void loop(){ 78 | 79 | 80 | while(1){ 81 | if(myESP.loop() == FULL_CONNECTION){ 82 | 83 | //only read/publish the temperature if the timer is up 84 | if(publishTimer.check()){ 85 | 86 | sensors.requestTemperatures(); // Send the command to get temperatures 87 | currentTemp = sensors.getTempCByIndex(0); //get the temperature 88 | 89 | //convert the float to a string 90 | char temperature[10]; 91 | dtostrf(currentTemp,4,1,temperature); 92 | 93 | //publish to mqtt 94 | myESP.publish(tempTopic,temperature, true); 95 | } 96 | } 97 | 98 | yield(); 99 | } 100 | 101 | } 102 | 103 | 104 | void callback(char* topic, uint8_t* payload, unsigned int length) { 105 | 106 | } 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /RGBStrip/Arduino/libraries/ESPHelper-master/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For ESPHelper 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | ESPHelper KEYWORD1 10 | netInfo KEYWORD1 11 | 12 | ####################################### 13 | # Methods and Functions (KEYWORD2) 14 | ####################################### 15 | 16 | begin KEYWORD2 17 | reconnect KEYWORD2 18 | end KEYWORD2 19 | loop KEYWORD2 20 | publish KEYWORD2 21 | subscribe KEYWORD2 22 | addSubscription KEYWORD2 23 | unsubscribe KEYWORD2 24 | removeSubscription KEYWORD2 25 | setCallback KEYWORD2 26 | getSSID KEYWORD2 27 | serSSID KEYWORD2 28 | getPASS KEYWORD2 29 | setPass KEYWORD2 30 | getMQTTIP KEYWORD2 31 | setMQTTIP KEYWORD2 32 | getIP KEYWORD2 33 | getNetInfo KEYWORD2 34 | setNetInfo KEYWORD2 35 | setHopping KEYWORD2 36 | heartbeat KEYWORD2 37 | enableHeartbeat KEYWORD2 38 | disableHeartbeat KEYWORD2 39 | OTA_enable KEYWORD2 40 | OTA_disable KEYWORD2 41 | OTA_begin KEYWORD2 42 | OTA_setPassword KEYWORD2 43 | OTA_setHostname KEYWORD2 44 | 45 | ####################################### 46 | # Constants (LITERAL1) 47 | ####################################### 48 | -------------------------------------------------------------------------------- /RGBStrip/Arduino/libraries/ESPHelper-master/library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ESPHelper", 3 | "keywords": "mqtt, iot, esp8266", 4 | "description": "A library to make using WiFi & MQTT on the ESP8266 easy.", 5 | "version": "1.2.5", 6 | "examples": "examples/*/*.ino", 7 | "frameworks": "arduino", 8 | "platforms": [ 9 | "espressif" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /RGBStrip/Arduino/libraries/ESPHelper-master/library.properties: -------------------------------------------------------------------------------- 1 | name=ESPHelper 2 | version=1.2.5 3 | author=It Kinda Works 4 | maintainer=It Kinda Works 5 | sentence=A library to make using WiFi & MQTT on the ESP8266 easy. 6 | paragraph=This library makes creating MQTT sketches easier on the ESP8266 as it abstracts a lot of the connection and MQTT handling away from the user so they only have to run a single function to handle automatic connection to both WiFi & MQTT and handles resubscribing to topics when the connection is lost. This library also supports auto hopping between known networks and OTA updating 7 | category=Communication 8 | url=http://github.com/ItKindaWorks/ESPHelper 9 | architectures=esp8266 10 | -------------------------------------------------------------------------------- /RGBStrip/Arduino/libraries/ESPHelper-master/src/ESPHelper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ESPHelper.cpp 3 | Copyright (c) 2016 ItKindaWorks Inc All right reserved. 4 | github.com/ItKindaWorks 5 | 6 | This file is part of ESPHelper 7 | 8 | ESPHelper is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | ESPHelper is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with ESPHelper. If not, see . 20 | */ 21 | 22 | 23 | #include "ESPHelper.h" 24 | 25 | //empy initializer 26 | ESPHelper::ESPHelper(){ } 27 | 28 | //initializer with single netInfo network 29 | ESPHelper::ESPHelper(netInfo *startingNet){ 30 | _currentNet = *startingNet; 31 | 32 | _ssidSet = true; 33 | _passSet = true; 34 | _mqttSet = true; 35 | 36 | _hoppingAllowed = false; 37 | 38 | _useOTA = false; 39 | } 40 | 41 | 42 | //initializer with netInfo array and index 43 | ESPHelper::ESPHelper(netInfo *netList[], uint8_t netCount, uint8_t startIndex){ 44 | _netList = netList; 45 | _netCount = netCount; 46 | _currentIndex = startIndex; 47 | 48 | _hoppingAllowed = true; 49 | 50 | _useOTA = false; 51 | 52 | _currentNet = *netList[constrain(_currentIndex, 0, _netCount)]; 53 | 54 | _ssidSet = true; 55 | _passSet = true; 56 | _mqttSet = true; 57 | } 58 | 59 | //initializer with single network information 60 | ESPHelper::ESPHelper(const char *ssid, const char *pass, const char *mqttIP){ 61 | _currentNet.ssid = ssid; 62 | _currentNet.pass = pass; 63 | _currentNet.mqtt = mqttIP; 64 | 65 | _hoppingAllowed = false; 66 | 67 | _useOTA = false; 68 | 69 | _ssidSet = true; 70 | _passSet = true; 71 | _mqttSet = true; 72 | } 73 | 74 | //start the wifi & mqtt systems and attempt connection (currently blocking) 75 | //true on: parameter check validated 76 | //false on: parameter check failed 77 | bool ESPHelper::begin(){ 78 | 79 | if(checkParams()){ 80 | // Generate client name based on MAC address and last 8 bits of microsecond counter 81 | _clientName += "esp8266-"; 82 | uint8_t mac[6]; 83 | WiFi.macAddress(mac); 84 | _clientName += macToStr(mac); 85 | 86 | client = PubSubClient(_currentNet.mqtt, 1883, wifiClient); 87 | 88 | WiFi.mode(WIFI_STA); 89 | WiFi.begin(_currentNet.ssid, _currentNet.pass); 90 | 91 | ArduinoOTA.onStart([]() {/* ota start code */}); 92 | ArduinoOTA.onEnd([]() { 93 | WiFi.disconnect(); 94 | int timeout = 0; 95 | while(WiFi.status() != WL_DISCONNECTED && timeout < 200){ 96 | delay(10); 97 | timeout++; 98 | } 99 | }); 100 | ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {/* ota progress code */}); 101 | ArduinoOTA.onError([](ota_error_t error) {/* ota error code */}); 102 | 103 | int timeout = 0; //counter for begin connection attempts 104 | while ((!client.connected() || WiFi.status() != WL_CONNECTED) && timeout < 200 ) { //max 2 sec before timeout 105 | reconnect(); 106 | delay(10); 107 | timeout++; 108 | } 109 | 110 | OTA_begin(); 111 | 112 | _hasBegun = true; 113 | return true; 114 | } 115 | return false; 116 | } 117 | 118 | void ESPHelper::end(){ 119 | OTA_disable(); 120 | WiFi.disconnect(); 121 | } 122 | 123 | //main loop - should be called as often as possible - handles wifi/mqtt connection and mqtt handler 124 | //true on: network/server connected 125 | //false on: network or server disconnected 126 | int ESPHelper::loop(){ 127 | if(checkParams()){ 128 | if (!client.connected() || WiFi.status() != WL_CONNECTED) { 129 | reconnect(); 130 | // return _connectionStatus; 131 | } 132 | 133 | if(_connectionStatus >= WIFI_ONLY){ 134 | 135 | if(_connectionStatus == FULL_CONNECTION){client.loop();} 136 | 137 | heartbeat(); 138 | 139 | //check for whether we want to use OTA and whether the system is running 140 | if(_useOTA && _OTArunning) {ArduinoOTA.handle();} 141 | //if we want to use OTA but its not running yet, start it up. 142 | else if(_useOTA && !_OTArunning){ 143 | OTA_begin(); 144 | ArduinoOTA.handle(); 145 | } 146 | 147 | 148 | return _connectionStatus; 149 | } 150 | } 151 | return false; 152 | } 153 | 154 | //subscribe to a speicifc topic (does not add to topic list) 155 | //true on: subscription success 156 | //false on: subscription failed (either from PubSub lib or network is disconnected) 157 | bool ESPHelper::subscribe(const char* topic, int qos){ 158 | if(_connectionStatus == FULL_CONNECTION){ 159 | bool returnVal = client.subscribe(topic, qos); 160 | client.loop(); 161 | return returnVal; 162 | } 163 | else{return false;} 164 | } 165 | 166 | //add a topic to the list of subscriptions and attempt to subscribe to the topic on the spot 167 | //true on: subscription added to list (does not guarantee that the topic was subscribed to, only that it was added to the list) 168 | //false on: subscription not added to list 169 | bool ESPHelper::addSubscription(const char* topic){ 170 | bool subscribed = false; 171 | for(int i = 0; i < MAX_SUBSCRIPTIONS; i++){ 172 | if(_subscriptions[i].isUsed == false){ 173 | _subscriptions[i].topic = topic; 174 | _subscriptions[i].isUsed = true; 175 | subscribed = true; 176 | break; 177 | } 178 | } 179 | if(subscribed){subscribe(topic, _qos);} 180 | 181 | 182 | return subscribed; 183 | } 184 | 185 | //loops through list of subscriptions and attempts to subscribe to all topics 186 | void ESPHelper::resubscribe(){ 187 | for(int i = 0; i < MAX_SUBSCRIPTIONS; i++){ 188 | if(_subscriptions[i].isUsed){ 189 | subscribe(_subscriptions[i].topic, _qos); 190 | yield(); 191 | } 192 | } 193 | } 194 | 195 | //attempts to remove a topic from the topic list 196 | //true on: subscription removed from list (does not guarantee that the topic was unsubscribed from, only that it was removed from the list) 197 | //false on: topic was not found in list and therefore cannot be removed 198 | bool ESPHelper::removeSubscription(const char* topic){ 199 | bool returnVal = false; 200 | String topicStr = topic; 201 | for(int i = 0; i < MAX_SUBSCRIPTIONS; i++){ 202 | if(_subscriptions[i].isUsed){ 203 | String subStr = _subscriptions[i].topic; 204 | if(subStr.equals(topicStr)){ 205 | _subscriptions[i].isUsed = false; 206 | client.unsubscribe(_subscriptions[i].topic); 207 | returnVal = true; 208 | break; 209 | } 210 | } 211 | } 212 | 213 | return returnVal; 214 | } 215 | 216 | //publish to a specified topic 217 | void ESPHelper::publish(const char* topic, const char* payload){ 218 | publish(topic, payload, false); 219 | } 220 | 221 | //publish to a specified topic with a given retain level 222 | void ESPHelper::publish(const char* topic, const char* payload, bool retain){ 223 | client.publish(topic, payload, retain); 224 | } 225 | 226 | //set the callback function for MQTT 227 | //true on: mqtt has been initialized 228 | //false on: mqtt not been inistialized 229 | bool ESPHelper::setCallback(MQTT_CALLBACK_SIGNATURE){ 230 | if(_hasBegun) { 231 | client.setCallback(callback); 232 | return true; 233 | } 234 | else{ 235 | return false; 236 | } 237 | } 238 | 239 | //attempts to connect to wifi & mqtt server if not connected 240 | void ESPHelper::reconnect() { 241 | static int tryCount = 0; 242 | 243 | if(reconnectMetro.check()){ 244 | //attempt to connect to the wifi if connection is lost 245 | if(WiFi.status() != WL_CONNECTED){ 246 | _connectionStatus = NO_CONNECTION; 247 | // _connected = false; 248 | debugPrint("."); 249 | tryCount++; 250 | if(tryCount == 20){ 251 | changeNetwork(); 252 | tryCount = 0; 253 | return; 254 | } 255 | } 256 | 257 | // make sure we are connected to WIFI before attemping to reconnect to MQTT 258 | //----note---- maybe want to reset tryCount whenever we succeed at getting wifi connection? 259 | if(WiFi.status() == WL_CONNECTED){ 260 | debugPrintln("\n---WIFI Connected!---"); 261 | _connectionStatus = WIFI_ONLY; 262 | 263 | int timeout = 0; //allow a max of 10 mqtt connection attempts before timing out 264 | while (!client.connected() && timeout < 10) { 265 | debugPrint("Attemping MQTT connection"); 266 | 267 | //if connected, subscribe to the topic(s) we want to be notified about 268 | if (client.connect((char*) _clientName.c_str())) { 269 | debugPrintln(" -- Connected"); 270 | // _connected = true; 271 | _connectionStatus = FULL_CONNECTION; 272 | resubscribe(); 273 | } 274 | else{ 275 | debugPrintln(" -- Failed"); 276 | // _connected = false; 277 | } 278 | timeout++; 279 | } 280 | 281 | if(timeout >= 10 && !client.connected()){ //if we still cant connect to mqtt after 10 attempts increment the try count 282 | tryCount++; 283 | if(tryCount == 20){ 284 | changeNetwork(); 285 | tryCount = 0; 286 | return; 287 | } 288 | } 289 | } 290 | 291 | reconnectMetro.reset(); 292 | } 293 | } 294 | 295 | //changes the current network settings to the next listed network if network hopping is allowed 296 | void ESPHelper::changeNetwork(){ 297 | 298 | if(_hoppingAllowed){ 299 | _currentIndex++; 300 | if(_currentIndex >= _netCount){_currentIndex = 0;} 301 | 302 | _currentNet = *_netList[_currentIndex]; 303 | 304 | debugPrint("Trying next network: "); 305 | debugPrintln(_currentNet.ssid); 306 | 307 | updateNetwork(); 308 | } 309 | 310 | 311 | // debugPrintln("\tDisconnecting from WiFi"); 312 | // WiFi.disconnect(); 313 | // debugPrintln("\tAttempting to begin on new network"); 314 | // WiFi.begin(_currentNet.ssid, _currentNet.pass); 315 | // debugPrintln("\tSetting new MQTT server"); 316 | // client.setServer(_currentNet.mqtt, 1883); 317 | // debugPrintln("\tDone - Ready for next reconnect attempt"); 318 | //ALL THIS COMMENTED CODE IS HANDLED BY updateNetwork() 319 | } 320 | 321 | void ESPHelper::updateNetwork(){ 322 | debugPrintln("\tDisconnecting from WiFi"); 323 | WiFi.disconnect(); 324 | debugPrintln("\tAttempting to begin on new network"); 325 | WiFi.begin(_currentNet.ssid, _currentNet.pass); 326 | debugPrintln("\tSetting new MQTT server"); 327 | client.setServer(_currentNet.mqtt, 1883); 328 | debugPrintln("\tDone - Ready for next reconnect attempt"); 329 | } 330 | 331 | //generate unique MQTT name from MAC addr 332 | String ESPHelper::macToStr(const uint8_t* mac){ 333 | 334 | String result; 335 | 336 | for (int i = 0; i < 6; ++i) { 337 | result += String(mac[i], 16); 338 | 339 | if (i < 5){ 340 | result += ':'; 341 | } 342 | } 343 | 344 | return result; 345 | } 346 | 347 | //change the current network info to a new netInfo - does not automatically disconnect from current network if already connected 348 | void ESPHelper::setNetInfo(netInfo newNetwork){ 349 | _currentNet = newNetwork; 350 | _ssidSet = true; 351 | _passSet = true; 352 | _mqttSet = true; 353 | } 354 | 355 | //change the current network info to a new *netInfo - does not automatically disconnect from current network if already connected 356 | void ESPHelper::setNetInfo(netInfo *newNetwork){ 357 | _currentNet = *newNetwork; 358 | _ssidSet = true; 359 | _passSet = true; 360 | _mqttSet = true; 361 | } 362 | 363 | //return the current netInfo state 364 | netInfo* ESPHelper::getNetInfo(){ 365 | return &_currentNet; 366 | } 367 | 368 | //return the current SSID 369 | const char* ESPHelper::getSSID(){ 370 | if(_ssidSet){return _currentNet.ssid;} 371 | return "SSID NOT SET"; 372 | } 373 | //set a new SSID - does not automatically disconnect from current network if already connected 374 | void ESPHelper::setSSID(const char* ssid){ 375 | _currentNet.ssid = ssid; 376 | _ssidSet = true; 377 | } 378 | 379 | //return the current network password 380 | const char* ESPHelper::getPASS(){ 381 | if(_passSet){return _currentNet.pass;} 382 | return "PASS NOT SET"; 383 | } 384 | //set a new network password - does not automatically disconnect from current network if already connected 385 | void ESPHelper::setPASS(const char* pass){ 386 | _currentNet.pass = pass; 387 | _passSet = true; 388 | } 389 | 390 | //return the current MQTT server IP 391 | const char* ESPHelper::getMQTTIP(){ 392 | if(_mqttSet){return _currentNet.mqtt;} 393 | return "MQTT IP NOT SET"; 394 | } 395 | //set a new MQTT server IP - does not automatically disconnect from current network/server if already connected 396 | void ESPHelper::setMQTTIP(const char* mqttIP){ 397 | _currentNet.mqtt = mqttIP; 398 | _mqttSet = true; 399 | } 400 | 401 | 402 | int ESPHelper::getMQTTQOS(){ 403 | return _qos; 404 | 405 | } 406 | void ESPHelper::setMQTTQOS(int qos){ 407 | _qos = qos; 408 | } 409 | 410 | 411 | String ESPHelper::getIP(){ 412 | return WiFi.localIP().toString(); 413 | } 414 | 415 | 416 | int ESPHelper::getStatus(){ 417 | return _connectionStatus; 418 | } 419 | 420 | 421 | 422 | //make sure all network parameters are set 423 | //true on: all network parameters have been set 424 | //false on: not all network parameters have been set 425 | bool ESPHelper::checkParams(){ 426 | if(_ssidSet && _passSet && _mqttSet){return true;} 427 | return false; 428 | } 429 | 430 | //enable or disable hopping - generally set automatically by initializer 431 | void ESPHelper::setHopping(bool canHop){ 432 | _hoppingAllowed = canHop; 433 | } 434 | 435 | //DEBUG ONLY - print the subscribed topics list to the serial line 436 | void ESPHelper::listSubscriptions(){ 437 | for(int i = 0; i < MAX_SUBSCRIPTIONS; i++){ 438 | if(_subscriptions[i].isUsed){ 439 | debugPrintln(_subscriptions[i].topic); 440 | } 441 | } 442 | } 443 | 444 | 445 | 446 | //enable the connection heartbeat on a given pin 447 | void ESPHelper::enableHeartbeat(int16_t pin){ 448 | #ifdef DEBUG 449 | if(pin == 1){_heartbeatEnabled = false;} 450 | else{ 451 | _heartbeatEnabled = true; 452 | _ledPin = pin; 453 | pinMode(_ledPin, OUTPUT); 454 | digitalWrite(_ledPin, HIGH); 455 | } 456 | #else 457 | _heartbeatEnabled = true; 458 | _ledPin = pin; 459 | pinMode(_ledPin, OUTPUT); 460 | digitalWrite(_ledPin, HIGH); 461 | #endif 462 | } 463 | 464 | //disable the connection heartbeat 465 | void ESPHelper::disableHeartbeat(){ 466 | _heartbeatEnabled = false; 467 | } 468 | 469 | //heartbeat to indicate network/mqtt connection 470 | void ESPHelper::heartbeat(){ 471 | static Metro heartbeatMetro = Metro(10); 472 | static int counter = 0; 473 | 474 | static bool ledState = true; 475 | 476 | if(heartbeatMetro.check() && _heartbeatEnabled){ 477 | if(counter == 1){ 478 | digitalWrite(_ledPin, ledState); 479 | heartbeatMetro.interval(10); 480 | ledState = !ledState; 481 | } 482 | else if(counter == 2){ 483 | digitalWrite(_ledPin, ledState); 484 | heartbeatMetro.interval(300); 485 | ledState = !ledState; 486 | } 487 | else if(counter == 3){ 488 | digitalWrite(_ledPin, ledState); 489 | heartbeatMetro.interval(10); 490 | ledState = !ledState; 491 | } 492 | else{ 493 | digitalWrite(_ledPin, ledState); 494 | heartbeatMetro.interval(1000); 495 | ledState = !ledState; 496 | counter = 0; 497 | } 498 | counter++; 499 | } 500 | } 501 | 502 | //enable use of OTA updates 503 | void ESPHelper::OTA_enable(){ 504 | _useOTA = true; 505 | OTA_begin(); 506 | } 507 | 508 | //begin the OTA subsystem but with a check for connectivity and enabled use of OTA 509 | void ESPHelper::OTA_begin(){ 510 | if(_connectionStatus >= WIFI_ONLY && _useOTA){ 511 | ArduinoOTA.begin(); 512 | _OTArunning = true; 513 | } 514 | } 515 | 516 | //disable use of OTA updates 517 | void ESPHelper::OTA_disable(){ 518 | _useOTA = false; 519 | _OTArunning = false; 520 | } 521 | 522 | //set a password for OTA updates 523 | void ESPHelper::OTA_setPassword(const char* pass){ 524 | ArduinoOTA.setPassword(pass); 525 | } 526 | 527 | void ESPHelper::OTA_setHostname(const char* hostname){ 528 | strcpy(_hostname, hostname); 529 | ArduinoOTA.setHostname(_hostname); 530 | } 531 | 532 | void ESPHelper::OTA_setHostnameWithVersion(const char* hostname){ 533 | strcpy(_hostname, hostname); 534 | strcat(_hostname, "----"); 535 | strcat(_hostname, VERSION); 536 | 537 | ArduinoOTA.setHostname(_hostname); 538 | } 539 | 540 | 541 | -------------------------------------------------------------------------------- /RGBStrip/Arduino/libraries/ESPHelper-master/src/ESPHelper.h: -------------------------------------------------------------------------------- 1 | /* 2 | ESPHelper.h 3 | Copyright (c) 2016 ItKindaWorks Inc All right reserved. 4 | github.com/ItKindaWorks 5 | 6 | This file is part of ESPHelper 7 | 8 | ESPHelper is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | ESPHelper is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with ESPHelper. If not, see . 20 | */ 21 | 22 | 23 | 24 | #ifndef ESP_HELPER_H 25 | #define ESP_HELPER_H 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #include "PubSubClient.h" 32 | #include 33 | #include "Metro.h" 34 | 35 | #define MAX_SUBSCRIPTIONS 25 //feel free to change this if you need more subsciptions 36 | 37 | #define VERSION "1-2-5" 38 | 39 | #define DEFAULT_QOS 1; //at least once - devices are garunteed to get a message. 40 | 41 | // #define DEBUG 42 | 43 | enum connStatus {NO_CONNECTION, WIFI_ONLY, FULL_CONNECTION}; 44 | 45 | 46 | #ifdef DEBUG 47 | #define debugPrint(x) Serial.print(x) //debug on 48 | #define debugPrintln(x) Serial.println(x) //debug on 49 | #else 50 | #define debugPrint(x) {;} //debug off 51 | #define debugPrintln(x) {;} //debug off 52 | #endif 53 | 54 | struct netInfo { 55 | const char* name; 56 | const char* mqtt; 57 | const char* ssid; 58 | const char* pass; 59 | }; 60 | typedef struct netInfo netInfo; 61 | 62 | struct subscription{ 63 | bool isUsed = false; 64 | const char* topic; 65 | }; 66 | typedef struct subscription subscription; 67 | 68 | 69 | class ESPHelper{ 70 | 71 | public: 72 | int16_t _hoppingAllowed = false; 73 | bool _fullyConnected = false; 74 | 75 | netInfo _currentNet; 76 | netInfo *_currentNetwork; 77 | 78 | Metro reconnectMetro = Metro(500); 79 | 80 | PubSubClient client; 81 | 82 | ESPHelper(); 83 | ESPHelper(netInfo *startingNet); 84 | ESPHelper(netInfo **startingNet, uint8_t netCount, uint8_t startIndex = 0); 85 | ESPHelper(const char *ssid, const char *pass, const char *mqttIP); 86 | 87 | bool begin(); 88 | void end(); 89 | 90 | int loop(); 91 | 92 | bool subscribe(const char* topic, int qos); 93 | bool addSubscription(const char* topic); 94 | bool removeSubscription(const char* topic); 95 | 96 | void publish(const char* topic, const char* payload); 97 | void publish(const char* topic, const char* payload, bool retain); 98 | 99 | bool setCallback(MQTT_CALLBACK_SIGNATURE); 100 | 101 | void reconnect(); 102 | 103 | void updateNetwork(); //manually disconnect and reconnecting to network/mqtt using current values (generally called after setting new network values) 104 | 105 | const char* getSSID(); 106 | void setSSID(const char *ssid); 107 | 108 | const char* getPASS(); 109 | void setPASS(const char *pass); 110 | 111 | const char* getMQTTIP(); 112 | void setMQTTIP(const char *mqttIP); 113 | 114 | int getMQTTQOS(); 115 | void setMQTTQOS(int qos); 116 | 117 | String getIP(); 118 | 119 | int getStatus(); 120 | 121 | void setNetInfo(netInfo newNetwork); 122 | void setNetInfo(netInfo *newNetwork); 123 | netInfo* getNetInfo(); 124 | 125 | void setHopping(bool canHop); 126 | 127 | void listSubscriptions(); 128 | 129 | void enableHeartbeat(int16_t pin); 130 | void disableHeartbeat(); 131 | void heartbeat(); 132 | 133 | void OTA_enable(); 134 | void OTA_disable(); 135 | void OTA_begin(); 136 | void OTA_setPassword(const char* pass); 137 | void OTA_setHostname(const char* hostname); 138 | void OTA_setHostnameWithVersion(const char* hostname); 139 | 140 | private: 141 | WiFiClient wifiClient; 142 | 143 | String _clientName; 144 | 145 | int _connectionStatus = NO_CONNECTION; 146 | 147 | uint8_t _netCount = 0; 148 | uint8_t _currentIndex = 0; 149 | 150 | bool _ssidSet = false; 151 | bool _passSet = false; 152 | bool _mqttSet = false; 153 | 154 | bool _useOTA = false; 155 | bool _OTArunning = false; 156 | 157 | bool _hasBegun = false; 158 | 159 | netInfo **_netList; 160 | 161 | int16_t _ledPin = 2; 162 | bool _heartbeatEnabled = false; 163 | 164 | subscription _subscriptions[MAX_SUBSCRIPTIONS]; 165 | 166 | char _hostname[64]; 167 | 168 | int _qos = DEFAULT_QOS; 169 | 170 | 171 | void changeNetwork(); 172 | 173 | String macToStr(const uint8_t* mac); 174 | 175 | bool checkParams(); 176 | 177 | void resubscribe(); 178 | }; 179 | 180 | #endif 181 | 182 | 183 | -------------------------------------------------------------------------------- /RGBStrip/Arduino/libraries/ESPHelper-master/src/PubSubClient.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | PubSubClient.cpp - A simple client for MQTT. 3 | Nick O'Leary 4 | http://knolleary.net 5 | */ 6 | 7 | #include "PubSubClient.h" 8 | #include "Arduino.h" 9 | 10 | PubSubClient::PubSubClient() { 11 | this->_state = MQTT_DISCONNECTED; 12 | this->_client = NULL; 13 | this->stream = NULL; 14 | setCallback(NULL); 15 | } 16 | 17 | PubSubClient::PubSubClient(Client& client) { 18 | this->_state = MQTT_DISCONNECTED; 19 | setClient(client); 20 | this->stream = NULL; 21 | } 22 | 23 | PubSubClient::PubSubClient(IPAddress addr, uint16_t port, Client& client) { 24 | this->_state = MQTT_DISCONNECTED; 25 | setServer(addr, port); 26 | setClient(client); 27 | this->stream = NULL; 28 | } 29 | PubSubClient::PubSubClient(IPAddress addr, uint16_t port, Client& client, Stream& stream) { 30 | this->_state = MQTT_DISCONNECTED; 31 | setServer(addr,port); 32 | setClient(client); 33 | setStream(stream); 34 | } 35 | PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) { 36 | this->_state = MQTT_DISCONNECTED; 37 | setServer(addr, port); 38 | setCallback(callback); 39 | setClient(client); 40 | this->stream = NULL; 41 | } 42 | PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) { 43 | this->_state = MQTT_DISCONNECTED; 44 | setServer(addr,port); 45 | setCallback(callback); 46 | setClient(client); 47 | setStream(stream); 48 | } 49 | 50 | PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, Client& client) { 51 | this->_state = MQTT_DISCONNECTED; 52 | setServer(ip, port); 53 | setClient(client); 54 | this->stream = NULL; 55 | } 56 | PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, Client& client, Stream& stream) { 57 | this->_state = MQTT_DISCONNECTED; 58 | setServer(ip,port); 59 | setClient(client); 60 | setStream(stream); 61 | } 62 | PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) { 63 | this->_state = MQTT_DISCONNECTED; 64 | setServer(ip, port); 65 | setCallback(callback); 66 | setClient(client); 67 | this->stream = NULL; 68 | } 69 | PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) { 70 | this->_state = MQTT_DISCONNECTED; 71 | setServer(ip,port); 72 | setCallback(callback); 73 | setClient(client); 74 | setStream(stream); 75 | } 76 | 77 | PubSubClient::PubSubClient(const char* domain, uint16_t port, Client& client) { 78 | this->_state = MQTT_DISCONNECTED; 79 | setServer(domain,port); 80 | setClient(client); 81 | this->stream = NULL; 82 | } 83 | PubSubClient::PubSubClient(const char* domain, uint16_t port, Client& client, Stream& stream) { 84 | this->_state = MQTT_DISCONNECTED; 85 | setServer(domain,port); 86 | setClient(client); 87 | setStream(stream); 88 | } 89 | PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) { 90 | this->_state = MQTT_DISCONNECTED; 91 | setServer(domain,port); 92 | setCallback(callback); 93 | setClient(client); 94 | this->stream = NULL; 95 | } 96 | PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) { 97 | this->_state = MQTT_DISCONNECTED; 98 | setServer(domain,port); 99 | setCallback(callback); 100 | setClient(client); 101 | setStream(stream); 102 | } 103 | 104 | boolean PubSubClient::connect(const char *id) { 105 | return connect(id,NULL,NULL,0,0,0,0); 106 | } 107 | 108 | boolean PubSubClient::connect(const char *id, const char *user, const char *pass) { 109 | return connect(id,user,pass,0,0,0,0); 110 | } 111 | 112 | boolean PubSubClient::connect(const char *id, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage) { 113 | return connect(id,NULL,NULL,willTopic,willQos,willRetain,willMessage); 114 | } 115 | 116 | boolean PubSubClient::connect(const char *id, const char *user, const char *pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage) { 117 | if (!connected()) { 118 | int result = 0; 119 | 120 | if (domain != NULL) { 121 | result = _client->connect(this->domain, this->port); 122 | } else { 123 | result = _client->connect(this->ip, this->port); 124 | } 125 | if (result == 1) { 126 | nextMsgId = 1; 127 | // Leave room in the buffer for header and variable length field 128 | uint16_t length = 5; 129 | unsigned int j; 130 | 131 | #if MQTT_VERSION == MQTT_VERSION_3_1 132 | uint8_t d[9] = {0x00,0x06,'M','Q','I','s','d','p', MQTT_VERSION}; 133 | #define MQTT_HEADER_VERSION_LENGTH 9 134 | #elif MQTT_VERSION == MQTT_VERSION_3_1_1 135 | uint8_t d[7] = {0x00,0x04,'M','Q','T','T',MQTT_VERSION}; 136 | #define MQTT_HEADER_VERSION_LENGTH 7 137 | #endif 138 | for (j = 0;j>1); 154 | } 155 | } 156 | 157 | buffer[length++] = v; 158 | 159 | buffer[length++] = ((MQTT_KEEPALIVE) >> 8); 160 | buffer[length++] = ((MQTT_KEEPALIVE) & 0xFF); 161 | length = writeString(id,buffer,length); 162 | if (willTopic) { 163 | length = writeString(willTopic,buffer,length); 164 | length = writeString(willMessage,buffer,length); 165 | } 166 | 167 | if(user != NULL) { 168 | length = writeString(user,buffer,length); 169 | if(pass != NULL) { 170 | length = writeString(pass,buffer,length); 171 | } 172 | } 173 | 174 | write(MQTTCONNECT,buffer,length-5); 175 | 176 | lastInActivity = lastOutActivity = millis(); 177 | 178 | while (!_client->available()) { 179 | unsigned long t = millis(); 180 | if (t-lastInActivity >= ((int32_t) MQTT_SOCKET_TIMEOUT*1000UL)) { 181 | _state = MQTT_CONNECTION_TIMEOUT; 182 | _client->stop(); 183 | return false; 184 | } 185 | } 186 | uint8_t llen; 187 | uint16_t len = readPacket(&llen); 188 | 189 | if (len == 4) { 190 | if (buffer[3] == 0) { 191 | lastInActivity = millis(); 192 | pingOutstanding = false; 193 | _state = MQTT_CONNECTED; 194 | return true; 195 | } else { 196 | _state = buffer[3]; 197 | } 198 | } 199 | _client->stop(); 200 | } else { 201 | _state = MQTT_CONNECT_FAILED; 202 | } 203 | return false; 204 | } 205 | return true; 206 | } 207 | 208 | // reads a byte into result 209 | boolean PubSubClient::readByte(uint8_t * result) { 210 | uint32_t previousMillis = millis(); 211 | while(!_client->available()) { 212 | uint32_t currentMillis = millis(); 213 | if(currentMillis - previousMillis >= ((int32_t) MQTT_SOCKET_TIMEOUT * 1000)){ 214 | return false; 215 | } 216 | } 217 | *result = _client->read(); 218 | return true; 219 | } 220 | 221 | // reads a byte into result[*index] and increments index 222 | boolean PubSubClient::readByte(uint8_t * result, uint16_t * index){ 223 | uint16_t current_index = *index; 224 | uint8_t * write_address = &(result[current_index]); 225 | if(readByte(write_address)){ 226 | *index = current_index + 1; 227 | return true; 228 | } 229 | return false; 230 | } 231 | 232 | uint16_t PubSubClient::readPacket(uint8_t* lengthLength) { 233 | uint16_t len = 0; 234 | if(!readByte(buffer, &len)) return 0; 235 | bool isPublish = (buffer[0]&0xF0) == MQTTPUBLISH; 236 | uint32_t multiplier = 1; 237 | uint16_t length = 0; 238 | uint8_t digit = 0; 239 | uint16_t skip = 0; 240 | uint8_t start = 0; 241 | 242 | do { 243 | if(!readByte(&digit)) return 0; 244 | buffer[len++] = digit; 245 | length += (digit & 127) * multiplier; 246 | multiplier *= 128; 247 | } while ((digit & 128) != 0); 248 | *lengthLength = len-1; 249 | 250 | if (isPublish) { 251 | // Read in topic length to calculate bytes to skip over for Stream writing 252 | if(!readByte(buffer, &len)) return 0; 253 | if(!readByte(buffer, &len)) return 0; 254 | skip = (buffer[*lengthLength+1]<<8)+buffer[*lengthLength+2]; 255 | start = 2; 256 | if (buffer[0]&MQTTQOS1) { 257 | // skip message id 258 | skip += 2; 259 | } 260 | } 261 | 262 | for (uint16_t i = start;istream) { 265 | if (isPublish && len-*lengthLength-2>skip) { 266 | this->stream->write(digit); 267 | } 268 | } 269 | if (len < MQTT_MAX_PACKET_SIZE) { 270 | buffer[len] = digit; 271 | } 272 | len++; 273 | } 274 | 275 | if (!this->stream && len > MQTT_MAX_PACKET_SIZE) { 276 | len = 0; // This will cause the packet to be ignored. 277 | } 278 | 279 | return len; 280 | } 281 | 282 | boolean PubSubClient::loop() { 283 | if (connected()) { 284 | unsigned long t = millis(); 285 | if ((t - lastInActivity > MQTT_KEEPALIVE*1000UL) || (t - lastOutActivity > MQTT_KEEPALIVE*1000UL)) { 286 | if (pingOutstanding) { 287 | this->_state = MQTT_CONNECTION_TIMEOUT; 288 | _client->stop(); 289 | return false; 290 | } else { 291 | buffer[0] = MQTTPINGREQ; 292 | buffer[1] = 0; 293 | _client->write(buffer,2); 294 | lastOutActivity = t; 295 | lastInActivity = t; 296 | pingOutstanding = true; 297 | } 298 | } 299 | if (_client->available()) { 300 | uint8_t llen; 301 | uint16_t len = readPacket(&llen); 302 | uint16_t msgId = 0; 303 | uint8_t *payload; 304 | if (len > 0) { 305 | lastInActivity = t; 306 | uint8_t type = buffer[0]&0xF0; 307 | if (type == MQTTPUBLISH) { 308 | if (callback) { 309 | uint16_t tl = (buffer[llen+1]<<8)+buffer[llen+2]; /* topic length in bytes */ 310 | memmove(buffer+llen+2,buffer+llen+3,tl); /* move topic inside buffer 1 byte to front */ 311 | buffer[llen+2+tl] = 0; /* end the topic as a 'C' string with \x00 */ 312 | char *topic = (char*) buffer+llen+2; 313 | // msgId only present for QOS>0 314 | if ((buffer[0]&0x06) == MQTTQOS1) { 315 | msgId = (buffer[llen+3+tl]<<8)+buffer[llen+3+tl+1]; 316 | payload = buffer+llen+3+tl+2; 317 | callback(topic,payload,len-llen-3-tl-2); 318 | 319 | buffer[0] = MQTTPUBACK; 320 | buffer[1] = 2; 321 | buffer[2] = (msgId >> 8); 322 | buffer[3] = (msgId & 0xFF); 323 | _client->write(buffer,4); 324 | lastOutActivity = t; 325 | 326 | } else { 327 | payload = buffer+llen+3+tl; 328 | callback(topic,payload,len-llen-3-tl); 329 | } 330 | } 331 | } else if (type == MQTTPINGREQ) { 332 | buffer[0] = MQTTPINGRESP; 333 | buffer[1] = 0; 334 | _client->write(buffer,2); 335 | } else if (type == MQTTPINGRESP) { 336 | pingOutstanding = false; 337 | } 338 | } 339 | } 340 | return true; 341 | } 342 | return false; 343 | } 344 | 345 | boolean PubSubClient::publish(const char* topic, const char* payload) { 346 | return publish(topic,(const uint8_t*)payload,strlen(payload),false); 347 | } 348 | 349 | boolean PubSubClient::publish(const char* topic, const char* payload, boolean retained) { 350 | return publish(topic,(const uint8_t*)payload,strlen(payload),retained); 351 | } 352 | 353 | boolean PubSubClient::publish(const char* topic, const uint8_t* payload, unsigned int plength) { 354 | return publish(topic, payload, plength, false); 355 | } 356 | 357 | boolean PubSubClient::publish(const char* topic, const uint8_t* payload, unsigned int plength, boolean retained) { 358 | if (connected()) { 359 | if (MQTT_MAX_PACKET_SIZE < 5 + 2+strlen(topic) + plength) { 360 | // Too long 361 | return false; 362 | } 363 | // Leave room in the buffer for header and variable length field 364 | uint16_t length = 5; 365 | length = writeString(topic,buffer,length); 366 | uint16_t i; 367 | for (i=0;i 0) { 405 | digit |= 0x80; 406 | } 407 | buffer[pos++] = digit; 408 | llen++; 409 | } while(len>0); 410 | 411 | pos = writeString(topic,buffer,pos); 412 | 413 | rc += _client->write(buffer,pos); 414 | 415 | for (i=0;iwrite((char)pgm_read_byte_near(payload + i)); 417 | } 418 | 419 | lastOutActivity = millis(); 420 | 421 | return rc == tlen + 4 + plength; 422 | } 423 | 424 | boolean PubSubClient::write(uint8_t header, uint8_t* buf, uint16_t length) { 425 | uint8_t lenBuf[4]; 426 | uint8_t llen = 0; 427 | uint8_t digit; 428 | uint8_t pos = 0; 429 | uint16_t rc; 430 | uint16_t len = length; 431 | do { 432 | digit = len % 128; 433 | len = len / 128; 434 | if (len > 0) { 435 | digit |= 0x80; 436 | } 437 | lenBuf[pos++] = digit; 438 | llen++; 439 | } while(len>0); 440 | 441 | buf[4-llen] = header; 442 | for (int i=0;i 0) && result) { 452 | bytesToWrite = (bytesRemaining > MQTT_MAX_TRANSFER_SIZE)?MQTT_MAX_TRANSFER_SIZE:bytesRemaining; 453 | rc = _client->write(writeBuf,bytesToWrite); 454 | result = (rc == bytesToWrite); 455 | bytesRemaining -= rc; 456 | writeBuf += rc; 457 | } 458 | return result; 459 | #else 460 | rc = _client->write(buf+(4-llen),length+1+llen); 461 | lastOutActivity = millis(); 462 | return (rc == 1+llen+length); 463 | #endif 464 | } 465 | 466 | boolean PubSubClient::subscribe(const char* topic) { 467 | return subscribe(topic, 0); 468 | } 469 | 470 | boolean PubSubClient::subscribe(const char* topic, uint8_t qos) { 471 | if (qos < 0 || qos > 1) { 472 | return false; 473 | } 474 | if (MQTT_MAX_PACKET_SIZE < 9 + strlen(topic)) { 475 | // Too long 476 | return false; 477 | } 478 | if (connected()) { 479 | // Leave room in the buffer for header and variable length field 480 | uint16_t length = 5; 481 | nextMsgId++; 482 | if (nextMsgId == 0) { 483 | nextMsgId = 1; 484 | } 485 | buffer[length++] = (nextMsgId >> 8); 486 | buffer[length++] = (nextMsgId & 0xFF); 487 | length = writeString((char*)topic, buffer,length); 488 | buffer[length++] = qos; 489 | return write(MQTTSUBSCRIBE|MQTTQOS1,buffer,length-5); 490 | } 491 | return false; 492 | } 493 | 494 | boolean PubSubClient::unsubscribe(const char* topic) { 495 | if (MQTT_MAX_PACKET_SIZE < 9 + strlen(topic)) { 496 | // Too long 497 | return false; 498 | } 499 | if (connected()) { 500 | uint16_t length = 5; 501 | nextMsgId++; 502 | if (nextMsgId == 0) { 503 | nextMsgId = 1; 504 | } 505 | buffer[length++] = (nextMsgId >> 8); 506 | buffer[length++] = (nextMsgId & 0xFF); 507 | length = writeString(topic, buffer,length); 508 | return write(MQTTUNSUBSCRIBE|MQTTQOS1,buffer,length-5); 509 | } 510 | return false; 511 | } 512 | 513 | void PubSubClient::disconnect() { 514 | buffer[0] = MQTTDISCONNECT; 515 | buffer[1] = 0; 516 | _client->write(buffer,2); 517 | _state = MQTT_DISCONNECTED; 518 | _client->stop(); 519 | lastInActivity = lastOutActivity = millis(); 520 | } 521 | 522 | uint16_t PubSubClient::writeString(const char* string, uint8_t* buf, uint16_t pos) { 523 | const char* idp = string; 524 | uint16_t i = 0; 525 | pos += 2; 526 | while (*idp) { 527 | buf[pos++] = *idp++; 528 | i++; 529 | } 530 | buf[pos-i-2] = (i >> 8); 531 | buf[pos-i-1] = (i & 0xFF); 532 | return pos; 533 | } 534 | 535 | 536 | boolean PubSubClient::connected() { 537 | boolean rc; 538 | if (_client == NULL ) { 539 | rc = false; 540 | } else { 541 | rc = (int)_client->connected(); 542 | if (!rc) { 543 | if (this->_state == MQTT_CONNECTED) { 544 | this->_state = MQTT_CONNECTION_LOST; 545 | _client->flush(); 546 | _client->stop(); 547 | } 548 | } 549 | } 550 | return rc; 551 | } 552 | 553 | PubSubClient& PubSubClient::setServer(uint8_t * ip, uint16_t port) { 554 | IPAddress addr(ip[0],ip[1],ip[2],ip[3]); 555 | return setServer(addr,port); 556 | } 557 | 558 | PubSubClient& PubSubClient::setServer(IPAddress ip, uint16_t port) { 559 | this->ip = ip; 560 | this->port = port; 561 | this->domain = NULL; 562 | return *this; 563 | } 564 | 565 | PubSubClient& PubSubClient::setServer(const char * domain, uint16_t port) { 566 | this->domain = domain; 567 | this->port = port; 568 | return *this; 569 | } 570 | 571 | PubSubClient& PubSubClient::setCallback(MQTT_CALLBACK_SIGNATURE) { 572 | this->callback = callback; 573 | return *this; 574 | } 575 | 576 | PubSubClient& PubSubClient::setClient(Client& client){ 577 | this->_client = &client; 578 | return *this; 579 | } 580 | 581 | PubSubClient& PubSubClient::setStream(Stream& stream){ 582 | this->stream = &stream; 583 | return *this; 584 | } 585 | 586 | int PubSubClient::state() { 587 | return this->_state; 588 | } 589 | -------------------------------------------------------------------------------- /RGBStrip/Arduino/libraries/ESPHelper-master/src/PubSubClient.h: -------------------------------------------------------------------------------- 1 | /* 2 | PubSubClient.h - A simple client for MQTT. 3 | Nick O'Leary 4 | http://knolleary.net 5 | */ 6 | 7 | #ifndef PubSubClient_h 8 | #define PubSubClient_h 9 | 10 | #include 11 | #include "IPAddress.h" 12 | #include "Client.h" 13 | #include "Stream.h" 14 | 15 | #define MQTT_VERSION_3_1 3 16 | #define MQTT_VERSION_3_1_1 4 17 | 18 | // MQTT_VERSION : Pick the version 19 | //#define MQTT_VERSION MQTT_VERSION_3_1 20 | #ifndef MQTT_VERSION 21 | #define MQTT_VERSION MQTT_VERSION_3_1_1 22 | #endif 23 | 24 | // MQTT_MAX_PACKET_SIZE : Maximum packet size 25 | #ifndef MQTT_MAX_PACKET_SIZE 26 | #define MQTT_MAX_PACKET_SIZE 128 27 | #endif 28 | 29 | // MQTT_KEEPALIVE : keepAlive interval in Seconds 30 | #ifndef MQTT_KEEPALIVE 31 | #define MQTT_KEEPALIVE 15 32 | #endif 33 | 34 | // MQTT_SOCKET_TIMEOUT: socket timeout interval in Seconds 35 | #ifndef MQTT_SOCKET_TIMEOUT 36 | #define MQTT_SOCKET_TIMEOUT 15 37 | #endif 38 | 39 | // MQTT_MAX_TRANSFER_SIZE : limit how much data is passed to the network client 40 | // in each write call. Needed for the Arduino Wifi Shield. Leave undefined to 41 | // pass the entire MQTT packet in each write call. 42 | //#define MQTT_MAX_TRANSFER_SIZE 80 43 | 44 | // Possible values for client.state() 45 | #define MQTT_CONNECTION_TIMEOUT -4 46 | #define MQTT_CONNECTION_LOST -3 47 | #define MQTT_CONNECT_FAILED -2 48 | #define MQTT_DISCONNECTED -1 49 | #define MQTT_CONNECTED 0 50 | #define MQTT_CONNECT_BAD_PROTOCOL 1 51 | #define MQTT_CONNECT_BAD_CLIENT_ID 2 52 | #define MQTT_CONNECT_UNAVAILABLE 3 53 | #define MQTT_CONNECT_BAD_CREDENTIALS 4 54 | #define MQTT_CONNECT_UNAUTHORIZED 5 55 | 56 | #define MQTTCONNECT 1 << 4 // Client request to connect to Server 57 | #define MQTTCONNACK 2 << 4 // Connect Acknowledgment 58 | #define MQTTPUBLISH 3 << 4 // Publish message 59 | #define MQTTPUBACK 4 << 4 // Publish Acknowledgment 60 | #define MQTTPUBREC 5 << 4 // Publish Received (assured delivery part 1) 61 | #define MQTTPUBREL 6 << 4 // Publish Release (assured delivery part 2) 62 | #define MQTTPUBCOMP 7 << 4 // Publish Complete (assured delivery part 3) 63 | #define MQTTSUBSCRIBE 8 << 4 // Client Subscribe request 64 | #define MQTTSUBACK 9 << 4 // Subscribe Acknowledgment 65 | #define MQTTUNSUBSCRIBE 10 << 4 // Client Unsubscribe request 66 | #define MQTTUNSUBACK 11 << 4 // Unsubscribe Acknowledgment 67 | #define MQTTPINGREQ 12 << 4 // PING Request 68 | #define MQTTPINGRESP 13 << 4 // PING Response 69 | #define MQTTDISCONNECT 14 << 4 // Client is Disconnecting 70 | #define MQTTReserved 15 << 4 // Reserved 71 | 72 | #define MQTTQOS0 (0 << 1) 73 | #define MQTTQOS1 (1 << 1) 74 | #define MQTTQOS2 (2 << 1) 75 | 76 | #ifdef ESP8266 77 | #include 78 | #define MQTT_CALLBACK_SIGNATURE std::function callback 79 | #else 80 | #define MQTT_CALLBACK_SIGNATURE void (*callback)(char*, uint8_t*, unsigned int) 81 | #endif 82 | 83 | class PubSubClient { 84 | private: 85 | Client* _client; 86 | uint8_t buffer[MQTT_MAX_PACKET_SIZE]; 87 | uint16_t nextMsgId; 88 | unsigned long lastOutActivity; 89 | unsigned long lastInActivity; 90 | bool pingOutstanding; 91 | MQTT_CALLBACK_SIGNATURE; 92 | uint16_t readPacket(uint8_t*); 93 | boolean readByte(uint8_t * result); 94 | boolean readByte(uint8_t * result, uint16_t * index); 95 | boolean write(uint8_t header, uint8_t* buf, uint16_t length); 96 | uint16_t writeString(const char* string, uint8_t* buf, uint16_t pos); 97 | IPAddress ip; 98 | const char* domain; 99 | uint16_t port; 100 | Stream* stream; 101 | int _state; 102 | public: 103 | PubSubClient(); 104 | PubSubClient(Client& client); 105 | PubSubClient(IPAddress, uint16_t, Client& client); 106 | PubSubClient(IPAddress, uint16_t, Client& client, Stream&); 107 | PubSubClient(IPAddress, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client); 108 | PubSubClient(IPAddress, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&); 109 | PubSubClient(uint8_t *, uint16_t, Client& client); 110 | PubSubClient(uint8_t *, uint16_t, Client& client, Stream&); 111 | PubSubClient(uint8_t *, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client); 112 | PubSubClient(uint8_t *, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&); 113 | PubSubClient(const char*, uint16_t, Client& client); 114 | PubSubClient(const char*, uint16_t, Client& client, Stream&); 115 | PubSubClient(const char*, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client); 116 | PubSubClient(const char*, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&); 117 | 118 | PubSubClient& setServer(IPAddress ip, uint16_t port); 119 | PubSubClient& setServer(uint8_t * ip, uint16_t port); 120 | PubSubClient& setServer(const char * domain, uint16_t port); 121 | PubSubClient& setCallback(MQTT_CALLBACK_SIGNATURE); 122 | PubSubClient& setClient(Client& client); 123 | PubSubClient& setStream(Stream& stream); 124 | 125 | boolean connect(const char* id); 126 | boolean connect(const char* id, const char* user, const char* pass); 127 | boolean connect(const char* id, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage); 128 | boolean connect(const char* id, const char* user, const char* pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage); 129 | void disconnect(); 130 | boolean publish(const char* topic, const char* payload); 131 | boolean publish(const char* topic, const char* payload, boolean retained); 132 | boolean publish(const char* topic, const uint8_t * payload, unsigned int plength); 133 | boolean publish(const char* topic, const uint8_t * payload, unsigned int plength, boolean retained); 134 | boolean publish_P(const char* topic, const uint8_t * payload, unsigned int plength, boolean retained); 135 | boolean subscribe(const char* topic); 136 | boolean subscribe(const char* topic, uint8_t qos); 137 | boolean unsubscribe(const char* topic); 138 | boolean loop(); 139 | boolean connected(); 140 | int state(); 141 | }; 142 | 143 | 144 | #endif 145 | -------------------------------------------------------------------------------- /RGBStrip/Arduino/libraries/HSB_Color-master/HSBColor.cpp: -------------------------------------------------------------------------------- 1 | #include "HSBColor.h" 2 | 3 | 4 | /* HSB to RGB conversion function 5 | INPUT PARAMETERS: Hue values should range from 0 to 360, Saturation and Brightness values should range from 0 to 100 6 | Colors pointer should resolve to an array with 3 elements 7 | RGB values are passed back using via the array. Each value will range between 0 and 255 8 | */ 9 | void H2R_HSBtoRGB(int hue, int sat, int bright, int* colors) { 10 | 11 | // constrain all input variables to expected range 12 | hue = constrain(hue, 0, 360); 13 | sat = constrain(sat, 0, 100); 14 | bright = constrain(bright, 0, 100); 15 | 16 | // define maximum value for RGB array elements 17 | float max_rgb_val = H2R_MAX_RGB_val; 18 | 19 | // convert saturation and brightness value to decimals and init r, g, b variables 20 | float sat_f = float(sat) / 100.0; 21 | float bright_f = float(bright) / 100.0; 22 | int r, g, b; 23 | 24 | // If brightness is 0 then color is black (achromatic) 25 | // therefore, R, G and B values will all equal to 0 26 | if (bright <= 0) { 27 | colors[0] = 0; 28 | colors[1] = 0; 29 | colors[2] = 0; 30 | } 31 | 32 | // If saturation is 0 then color is gray (achromatic) 33 | // therefore, R, G and B values will all equal the current brightness 34 | if (sat <= 0) { 35 | colors[0] = bright_f * max_rgb_val; 36 | colors[1] = bright_f * max_rgb_val; 37 | colors[2] = bright_f * max_rgb_val; 38 | } 39 | 40 | // if saturation and brightness are greater than 0 then calculate 41 | // R, G and B values based on the current hue and brightness 42 | else { 43 | 44 | if (hue >= 0 && hue < 120) { 45 | float hue_primary = 1.0 - (float(hue) / 120.0); 46 | float hue_secondary = float(hue) / 120.0; 47 | float sat_primary = (1.0 - hue_primary) * (1.0 - sat_f); 48 | float sat_secondary = (1.0 - hue_secondary) * (1.0 - sat_f); 49 | float sat_tertiary = 1.0 - sat_f; 50 | r = (bright_f * max_rgb_val) * (hue_primary + sat_primary); 51 | g = (bright_f * max_rgb_val) * (hue_secondary + sat_secondary); 52 | b = (bright_f * max_rgb_val) * sat_tertiary; 53 | } 54 | 55 | else if (hue >= 120 && hue < 240) { 56 | float hue_primary = 1.0 - ((float(hue)-120.0) / 120.0); 57 | float hue_secondary = (float(hue)-120.0) / 120.0; 58 | float sat_primary = (1.0 - hue_primary) * (1.0 - sat_f); 59 | float sat_secondary = (1.0 - hue_secondary) * (1.0 - sat_f); 60 | float sat_tertiary = 1.0 - sat_f; 61 | r = (bright_f * max_rgb_val) * sat_tertiary; 62 | g = (bright_f * max_rgb_val) * (hue_primary + sat_primary); 63 | b = (bright_f * max_rgb_val) * (hue_secondary + sat_secondary); 64 | } 65 | 66 | else if (hue >= 240 && hue <= 360) { 67 | float hue_primary = 1.0 - ((float(hue)-240.0) / 120.0); 68 | float hue_secondary = (float(hue)-240.0) / 120.0; 69 | float sat_primary = (1.0 - hue_primary) * (1.0 - sat_f); 70 | float sat_secondary = (1.0 - hue_secondary) * (1.0 - sat_f); 71 | float sat_tertiary = 1.0 - sat_f; 72 | r = (bright_f * max_rgb_val) * (hue_secondary + sat_secondary); 73 | g = (bright_f * max_rgb_val) * sat_tertiary; 74 | b = (bright_f * max_rgb_val) * (hue_primary + sat_primary); 75 | } 76 | 77 | colors[0]=r; 78 | colors[1]=g; 79 | colors[2]=b; 80 | 81 | } 82 | } 83 | 84 | void H2R_HSBtoRGBfloat(float hue, float sat, float bright, int* colors) { 85 | if (hue > 1) hue = 1.0; 86 | if (sat > 1) sat = 1.0; 87 | if (bright > 1) bright = 1.0; 88 | H2R_HSBtoRGB(hue*360.0, sat*100.0, bright*100.0, colors); 89 | } 90 | 91 | 92 | /* This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. 93 | To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send 94 | a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. 95 | */ -------------------------------------------------------------------------------- /RGBStrip/Arduino/libraries/HSB_Color-master/HSBColor.h: -------------------------------------------------------------------------------- 1 | /* 2 | HSB Color, 3 | Library that converts HSB color values to RGB colors. 4 | Created by Julio Terra, June 4, 2011. 5 | 6 | Header File Name: HSBColor.h 7 | Implementation File Name: HSBColor.h 8 | 9 | */ 10 | 11 | #ifndef HSBColor_h 12 | #define HSBColor_h 13 | 14 | #if defined(ARDUINO) && ARDUINO >= 100 15 | #include "Arduino.h" 16 | #else 17 | #include "WProgram.h" 18 | #endif 19 | 20 | #define H2R_MAX_RGB_val 255.0 21 | 22 | void H2R_HSBtoRGB(int, int, int, int*); 23 | void H2R_HSBtoRGBfloat(float, float, float, int*); 24 | 25 | #endif 26 | 27 | /* This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. 28 | To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/ or send 29 | a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA. 30 | */ -------------------------------------------------------------------------------- /RGBStrip/Arduino/libraries/HSB_Color-master/README.md: -------------------------------------------------------------------------------- 1 | HSB_Color 2 | ========= 3 | 4 | The HSB Color library converts HSB colors values to RGB color values. It was designed to drive rgb leds using hue, saturation and brightness values. 5 | 6 | Installing the Library 7 | ---------------------- 8 | 9 | * Download the library zip file from Github 10 | * Unzip the downloaded file 11 | * Copy HSB_Color folder into Arduino libraries folder 12 | * Launch (or restart) the Arduino IDE 13 | 14 | Using the Library 15 | ----------------- 16 | 17 | The HSB library provides two different methods that convert HSB to RGB values. They both accept the 4 parameters, three number values and a pointer to an integer array. They differ in that one of them accepts three integers, while the other accepts three float. 18 | 19 | The RGB values are saved into the integer array that is passed as the fourth parameter of each method. RGB values will range between 0 and 255. Make sure the array can accommodate three integers, otherwise the sketch won't work (though it may compile). 20 | 21 | **Integer Method** 22 | ``` 23 | void H2R_HSBtoRGB(int hue, int saturation, int brightness, int* rbg_array); 24 | ``` 25 | Value Range: 26 | * hue: 0 - 359 27 | * saturation: 0 - 99 28 | * brightness: 0 - 99 29 | 30 | **Float Method** 31 | ``` 32 | void H2R_HSBtoRGBfloat(float hue, float saturation, float brightness, int* rbg_array); 33 | ``` 34 | Float Value Range: 35 | * hue: 0.0 - 1.0 36 | * saturation: 0.0 - 1.0 37 | * brightness: 0.0 - 1.0 38 | -------------------------------------------------------------------------------- /RGBStrip/HAP-NodeJS/accessories/RGBLight_accessory.js: -------------------------------------------------------------------------------- 1 | var Accessory = require('../').Accessory; 2 | var Service = require('../').Service; 3 | var Characteristic = require('../').Characteristic; 4 | var uuid = require('../').uuid; 5 | var lightState = 0; 6 | 7 | 8 | ////////////////CHANGE THESE SETTINGS TO MATCH YOUR SETUP BEFORE RUNNING!!!!!!!!!!!!!////////////////////////// 9 | ////////////////CHANGE THESE SETTINGS TO MATCH YOUR SETUP BEFORE RUNNING!!!!!!!!!!!!!////////////////////////// 10 | var name = "RGB Light"; //Name to Show to IOS 11 | var UUID = "hap-nodejs:accessories:RGBLight"; //Change the RGBLight to something unique for each light - this should be unique for each node on your system 12 | var USERNAME = "AC:AF:AC:2C:5D:FB"; //This must also be unique for each node - make sure you change it! 13 | 14 | var MQTT_IP = '127.0.0.1' 15 | var lightTopic = '/light/rgb' 16 | ////////////////CHANGE THESE SETTINGS TO MATCH YOUR SETUP BEFORE RUNNING!!!!!!!!!!!!!////////////////////////// 17 | ////////////////CHANGE THESE SETTINGS TO MATCH YOUR SETUP BEFORE RUNNING!!!!!!!!!!!!!////////////////////////// 18 | 19 | 20 | // MQTT Setup 21 | var mqtt = require('mqtt'); 22 | var options = { 23 | port: 1883, 24 | host: MQTT_IP, 25 | clientId: 'FGAK35243' 26 | }; 27 | var client = mqtt.connect(options); 28 | client.on('message', function(topic, message) { 29 | 30 | }); 31 | 32 | //setup HK light object 33 | var lightUUID = uuid.generate(UUID); 34 | var light = exports.accessory = new Accessory(name, lightUUID); 35 | 36 | // Add properties for publishing (in case we're using Core.js and not BridgedCore.js) 37 | light.username = USERNAME; 38 | light.pincode = "031-45-154"; 39 | 40 | //add a light service and setup the On Characteristic 41 | light 42 | .addService(Service.Lightbulb) 43 | .getCharacteristic(Characteristic.On) 44 | .on('get', function(callback) { 45 | callback(null, lightAction.getState()); 46 | }); 47 | 48 | light 49 | .getService(Service.Lightbulb) 50 | .getCharacteristic(Characteristic.On) 51 | .on('set', function(value, callback) { 52 | lightAction.setState(value); 53 | callback(); 54 | }); 55 | 56 | //Add and setup Brightness 57 | light 58 | .getService(Service.Lightbulb) 59 | .addCharacteristic(Characteristic.Brightness) 60 | .on('set', function(value, callback){ 61 | lightAction.setBrightness(value); 62 | callback() 63 | }); 64 | 65 | light 66 | .getService(Service.Lightbulb) 67 | .getCharacteristic(Characteristic.Brightness) 68 | .on('get', function(callback){ 69 | callback(null, lightAction.getBrightness()) 70 | }); 71 | 72 | //Add and setup Saturation 73 | light 74 | .getService(Service.Lightbulb) 75 | .addCharacteristic(Characteristic.Saturation) 76 | .on('set', function(value, callback){ 77 | lightAction.setSaturation(value); 78 | callback() 79 | }); 80 | 81 | light 82 | .getService(Service.Lightbulb) 83 | .getCharacteristic(Characteristic.Saturation) 84 | .on('get', function(callback){ 85 | callback(null, lightAction.getSaturation()) 86 | }); 87 | 88 | //Add and setup Hue 89 | light 90 | .getService(Service.Lightbulb) 91 | .addCharacteristic(Characteristic.Hue) 92 | .on('set', function(value, callback){ 93 | lightAction.setHue(value); 94 | callback() 95 | }); 96 | 97 | light 98 | .getService(Service.Lightbulb) 99 | .getCharacteristic(Characteristic.Hue) 100 | .on('get', function(callback){ 101 | callback(null, lightAction.getHue()) 102 | }); 103 | 104 | 105 | 106 | // here's a fake temperature sensor device that we'll expose to HomeKit 107 | var lightAction = { 108 | 109 | //initialize the various state variables 110 | currentState: 0, 111 | currentBrightness: 0, 112 | currentHue: 0, 113 | currentSaturation: 0, 114 | 115 | lastBrightness: 0, 116 | lastHue: 0, 117 | lastSaturation: 0, 118 | 119 | 120 | //On Characteristic set/get 121 | getState: function() { return this.currentState;}, 122 | setState: function(newState){ 123 | 124 | if((newState == true && this.currentState == 0) || (newState == false && this.currentState == 1) ){ 125 | console.log("Setting new outlet state: " + newState.toString()); 126 | if(newState == true){ 127 | 128 | pubBrightness = this.currentBrightness / 100; 129 | pubHue = this.currentHue / 360; 130 | pubSaturation = this.currentSaturation / 100; 131 | toPublish = 'h' + pubHue.toFixed(3).toString() + ',' + pubSaturation.toFixed(3).toString() + ',' + pubBrightness.toFixed(3).toString() 132 | client.publish(lightTopic, toPublish); 133 | 134 | this.currentState = 1; 135 | } 136 | else{ 137 | client.publish(lightTopic, 'h0.00,0.00,0.00'); 138 | this.currentState = 0; 139 | } 140 | } 141 | 142 | }, 143 | 144 | //Brightness Characteristic set/get 145 | getBrightness: function(){return this.currentBrightness;}, 146 | setBrightness: function(newBrightness){ 147 | this.currentBrightness = newBrightness; 148 | this.updateLight(); 149 | }, 150 | 151 | 152 | //Saturation Characteristic set/get 153 | getSaturation: function(){return this.currentSaturation;}, 154 | setSaturation: function(newSaturation){ 155 | this.currentSaturation = newSaturation; 156 | this.updateLight(); 157 | }, 158 | 159 | 160 | //Hue Characteristic set/get 161 | getHue: function(){return this.currentHue;}, 162 | setHue: function(newHue){ 163 | this.currentHue = newHue; 164 | this.updateLight(); 165 | }, 166 | 167 | 168 | //other light setting functions 169 | updateState: function() { 170 | this.currentState = lightState; 171 | }, 172 | 173 | updateLight: function(){ 174 | if(this.lastSaturation != this.currentSaturation || this.lastHue != this.currentHue || this.lastBrightness != this.currentBrightness){ 175 | pubBrightness = this.currentBrightness / 100; 176 | pubHue = this.currentHue / 360; 177 | pubSaturation = this.currentSaturation / 100; 178 | toPublish = 'h' + pubHue.toFixed(3).toString() + ',' + pubSaturation.toFixed(3).toString() + ',' + pubBrightness.toFixed(3).toString() 179 | client.publish(lightTopic, toPublish); 180 | 181 | this.lastBrightness = this.currentBrightness; 182 | this.lastHue = this.currentHue; 183 | this.lastSaturation = this.currentSaturation; 184 | } 185 | } 186 | 187 | } 188 | 189 | 190 | 191 | // update the characteristic values so interested iOS devices can get notified 192 | setInterval(function() { 193 | light 194 | .getService(Service.Lightbulb) 195 | .setCharacteristic(Characteristic.On, lightAction.currentState); 196 | light 197 | .getService(Service.Lightbulb) 198 | .setCharacteristic(Characteristic.Brightness, lightAction.getBrightness()); 199 | light 200 | .getService(Service.Lightbulb) 201 | .setCharacteristic(Characteristic.Hue, lightAction.getHue()); 202 | light 203 | .getService(Service.Lightbulb) 204 | .setCharacteristic(Characteristic.Saturation, lightAction.getSaturation()); 205 | 206 | }, 2000); 207 | -------------------------------------------------------------------------------- /RGBStrip/README.md: -------------------------------------------------------------------------------- 1 | # Philips HUE clone using standard non addressable RGB strip 2 | 3 | Use 3 npn transistor (2n2222 or similar) and 3 1Kohm resistor 4 | 5 | ![scheme](https://github.com/Supersimo88/Arduino-ESP8266-HomeKit/blob/master/RGBStrip/resources/RGBStrip.jpg) 6 | -------------------------------------------------------------------------------- /RGBStrip/RGBStrip.ino: -------------------------------------------------------------------------------- 1 | //This is a Philips HUE light clone using standard non addressable RGB strip 2 | //it need 3 npn transistor (2n2222 or similar) and 3 1Khom reistor 3 | //use this ESPHelper library https://github.com/Supersimo88/Arduino-1.8.1/tree/master/libraries/ESPHelper-master 4 | //and this HSBColor library https://github.com/Supersimo88/Arduino-1.8.1/tree/master/libraries/HSB_Color-master 5 | #include 6 | #include 7 | 8 | #define TOPIC "/light/rgb" 9 | #define STATUS TOPIC "/status" 10 | #define NETWORK_HOSTNAME "rgblight" 11 | #define OTA_PASSWORD "_____" //set you OTA password 12 | 13 | #define RED_PIN D1 //set the r,g,b, pin for your esp8266 14 | #define GREEN_PIN D2 15 | #define BLUE_PIN D3 16 | #define BLINK_PIN D4 17 | 18 | typedef struct lightState{ 19 | double hue; 20 | double saturation; 21 | double brightness; 22 | int red; 23 | int redRate; 24 | int green; 25 | int greenRate; 26 | int blue; 27 | int blueRate; 28 | int fadePeriod; 29 | int updateType; 30 | }; 31 | 32 | 33 | lightState nextState; 34 | 35 | boolean newCommand = false; 36 | 37 | 38 | char* lightTopic = TOPIC; 39 | char* statusTopic = STATUS; 40 | char* hostnameStr = NETWORK_HOSTNAME; 41 | 42 | const int redPin = RED_PIN; 43 | const int greenPin = GREEN_PIN; 44 | const int bluePin = BLUE_PIN; 45 | const int blinkPin = BLINK_PIN; 46 | 47 | char statusString[50]; //string containing the current setting for the light 48 | 49 | 50 | //set this info for your own network 51 | netInfo homeNet = {.name = "___", .mqtt = "___", .ssid = "___", .pass = "___"}; 52 | 53 | ESPHelper myESP(&homeNet); 54 | 55 | void setup() { 56 | //initialize the light as an output and set to LOW (off) 57 | pinMode(redPin, OUTPUT); 58 | pinMode(bluePin, OUTPUT); 59 | pinMode(greenPin, OUTPUT); 60 | 61 | //all off 62 | digitalWrite(redPin, LOW); //all off 63 | digitalWrite(greenPin, LOW); 64 | digitalWrite(bluePin, LOW); 65 | 66 | delay(1000); 67 | 68 | 69 | //setup ota on esphelper 70 | myESP.OTA_enable(); 71 | myESP.OTA_setPassword(OTA_PASSWORD); 72 | myESP.OTA_setHostnameWithVersion(hostnameStr); 73 | 74 | myESP.enableHeartbeat(blinkPin); 75 | //subscribe to the lighttopic 76 | myESP.addSubscription(lightTopic); 77 | myESP.begin(); 78 | myESP.setCallback(callback); 79 | } 80 | 81 | 82 | void loop() { 83 | 84 | static bool connected = false; //keeps track of connection state 85 | 86 | 87 | if(myESP.loop() == FULL_CONNECTION){ 88 | 89 | //if the light was previously not connected to wifi and mqtt, update the status topic with the light being off 90 | if(!connected){ 91 | connected = true; //we have reconnected so now we dont need to flag the setting anymore 92 | myESP.publish(statusTopic, "h0.00,0.00,0.00", true); 93 | } 94 | 95 | lightHandler(); 96 | } 97 | 98 | 99 | yield(); 100 | } 101 | 102 | void lightHandler(){ 103 | //new and current lightStates 104 | static lightState newState; 105 | static lightState currentState; 106 | 107 | lightUpdater(&newState, currentState); 108 | lightChanger(newState, ¤tState); 109 | } 110 | 111 | void lightChanger(lightState newState, lightState *currentState){ 112 | 113 | currentState->red =newState.red; 114 | currentState->green =newState.green; 115 | currentState->blue =newState.blue; 116 | analogWrite(redPin, currentState->red); 117 | analogWrite(greenPin, currentState->green); 118 | analogWrite(bluePin, currentState->blue); 119 | } 120 | 121 | void lightUpdater (lightState *newState, lightState currentState){ 122 | 123 | //calculate new vars only if there is a new command 124 | if (newCommand){ 125 | 126 | //convert from HSB to RGB 127 | int newRGB[3]; 128 | H2R_HSBtoRGBfloat(nextState.hue, nextState.saturation, nextState.brightness, newRGB); 129 | newState->red = newRGB[0]; 130 | newState->green = newRGB[1]; 131 | newState->blue = newRGB[2]; 132 | } 133 | } 134 | 135 | //MQTT callback 136 | void callback(char* topic, byte* payload, unsigned int length) { 137 | 138 | //convert topic to string to make it easier to work with 139 | String topicStr = topic; 140 | 141 | char newPayload[40]; 142 | memcpy(newPayload, payload, length); 143 | newPayload[length] = '\0'; 144 | 145 | //handle HSB updates 146 | if(payload[0] == 'h'){ 147 | nextState.hue = atof(&newPayload[1]); 148 | nextState.saturation = atof(&newPayload[7]); 149 | nextState.brightness = atof(&newPayload[13]); 150 | 151 | newCommand = true; 152 | 153 | } 154 | //package up status message reply and send it back out to the status topic 155 | strcpy(statusString, newPayload); 156 | myESP.publish(statusTopic, statusString, true); 157 | } 158 | -------------------------------------------------------------------------------- /RGBStrip/resources/RGBStrip.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Supersimo88/Arduino-ESP8266-HomeKit/8dce60573587cb245d3ca042adf26854feb60ecb/RGBStrip/resources/RGBStrip.jpg -------------------------------------------------------------------------------- /esp8266-weather-station-oled-DST-master/esp8266-weather-station-oled-DST/DSEG7Classic-BoldFont.h: -------------------------------------------------------------------------------- 1 | /****************************************************** 2 | [Name] 7-segment Font DSEG7 Family 3 | [Version] 0.30(2015.07.20) 4 | [File Type] Derived from TTF(True Type Font) 5 | [License] Free(See link for details) 6 | [Copyrights] Keshikan(http://www.keshikan.net/fonts-e.html) 7 | ******************************************************/ 8 | 9 | // Converted by FontConverterV3.java written by Squix78 http://oleddisplay.squix.ch/ Consider a donation 10 | // In case of problems make sure that you are using the font file with the correct version! 11 | const char DSEG7_Classic_Bold_21[] PROGMEM = { 12 | 0x11, // Width: 17 13 | 0x17, // Height: 23 14 | 0x20, // First Char: 32 15 | 0x1B, // Numbers of Chars: 27 16 | 17 | // Jump Table: 18 | 0xFF, 0xFF, 0x00, 0x04, // 32:65535 19 | 0x00, 0x00, 0x15, 0x08, // 33:0 20 | 0x00, 0x15, 0x15, 0x08, // 34:21 21 | 0x00, 0x2A, 0x15, 0x08, // 35:42 22 | 0x00, 0x3F, 0x15, 0x08, // 36:63 23 | 0x00, 0x54, 0x15, 0x08, // 37:84 24 | 0x00, 0x69, 0x15, 0x08, // 38:105 25 | 0x00, 0x7E, 0x15, 0x08, // 39:126 26 | 0x00, 0x93, 0x15, 0x08, // 40:147 27 | 0x00, 0xA8, 0x15, 0x08, // 41:168 28 | 0x00, 0xBD, 0x15, 0x08, // 42:189 29 | 0x00, 0xD2, 0x15, 0x08, // 43:210 30 | 0x00, 0xE7, 0x15, 0x08, // 44:231 31 | 0x00, 0xFC, 0x26, 0x11, // 45:252 32 | 0xFF, 0xFF, 0x00, 0x00, // 46:65535 33 | 0x01, 0x22, 0x15, 0x08, // 47:290 34 | 0x01, 0x37, 0x2D, 0x11, // 48:311 35 | 0x01, 0x64, 0x2D, 0x11, // 49:356 36 | 0x01, 0x91, 0x2C, 0x11, // 50:401 37 | 0x01, 0xBD, 0x2D, 0x11, // 51:445 38 | 0x01, 0xEA, 0x2D, 0x11, // 52:490 39 | 0x02, 0x17, 0x2D, 0x11, // 53:535 40 | 0x02, 0x44, 0x2D, 0x11, // 54:580 41 | 0x02, 0x71, 0x2D, 0x11, // 55:625 42 | 0x02, 0x9E, 0x2D, 0x11, // 56:670 43 | 0x02, 0xCB, 0x2D, 0x11, // 57:715 44 | 0x02, 0xF8, 0x09, 0x04, // 58:760 45 | 46 | // Font Data: 47 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 33 48 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 34 49 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 35 50 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 36 51 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 37 52 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 38 53 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 39 54 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 40 55 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 41 56 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 42 57 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 43 58 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 44 59 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x10, // 45 60 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 47 61 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xEF,0x3F,0xF4,0xEF,0x5F,0xEC,0xC7,0x6F,0x1C,0x00,0x70,0x1C,0x00,0x70,0x1C,0x00,0x70,0x1C,0x00,0x70,0x1C,0x00,0x70,0x1C,0x00,0x70,0x1C,0x00,0x70,0xEC,0xC7,0x6F,0xF4,0xEF,0x5F,0xF8,0xEF,0x3F, // 48 62 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xC7,0x0F,0xF0,0xEF,0x1F,0xF8,0xEF,0x3F, // 49 63 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x3F,0x04,0xE0,0x5F,0x0C,0xD0,0x6F,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0xEC,0x17,0x60,0xF4,0x0F,0x40,0xF8,0x0F, // 50 64 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x40,0x0C,0x10,0x60,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0xEC,0xD7,0x6F,0xF4,0xEF,0x5F,0xF8,0xEF,0x3F, // 51 65 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0xF0,0x0F,0x00,0xE0,0x17,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0xE0,0xD7,0x0F,0xF0,0xEF,0x1F,0xF8,0xEF,0x3F, // 52 66 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0xF4,0x0F,0x40,0xEC,0x17,0x60,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x0C,0xD0,0x6F,0x04,0xE0,0x5F,0x00,0xE0,0x3F, // 53 67 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xEF,0x3F,0xF4,0xEF,0x5F,0xEC,0xD7,0x6F,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x0C,0xD0,0x6F,0x04,0xE0,0x5F,0x00,0xE0,0x3F, // 54 68 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0xF4,0x0F,0x00,0xEC,0x07,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0xEC,0xC7,0x0F,0xF4,0xEF,0x1F,0xF8,0xEF,0x3F, // 55 69 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xEF,0x3F,0xF4,0xEF,0x5F,0xEC,0xD7,0x6F,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0xEC,0xD7,0x6F,0xF4,0xEF,0x5F,0xF8,0xEF,0x3F, // 56 70 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0xF4,0x0F,0x40,0xEC,0x17,0x60,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0x1C,0x38,0x70,0xEC,0xD7,0x6F,0xF4,0xEF,0x5F,0xF8,0xEF,0x3F, // 57 71 | 0x00,0x00,0x00,0x80,0x03,0x03,0x80,0x03,0x03 // 58 72 | }; 73 | 74 | // Created by http://oleddisplay.squix.ch/ Consider a donation 75 | // In case of problems make sure that you are using the font file with the correct version! 76 | const char DSEG7_Classic_Regular_21[] PROGMEM = { 77 | 0x11, // Width: 17 78 | 0x17, // Height: 23 79 | 0x20, // First Char: 32 80 | 0x1B, // Numbers of Chars: 27 81 | 82 | // Jump Table: 83 | 0xFF, 0xFF, 0x00, 0x04, // 32:65535 84 | 0x00, 0x00, 0x15, 0x08, // 33:0 85 | 0x00, 0x15, 0x15, 0x08, // 34:21 86 | 0x00, 0x2A, 0x15, 0x08, // 35:42 87 | 0x00, 0x3F, 0x15, 0x08, // 36:63 88 | 0x00, 0x54, 0x15, 0x08, // 37:84 89 | 0x00, 0x69, 0x15, 0x08, // 38:105 90 | 0x00, 0x7E, 0x15, 0x08, // 39:126 91 | 0x00, 0x93, 0x15, 0x08, // 40:147 92 | 0x00, 0xA8, 0x15, 0x08, // 41:168 93 | 0x00, 0xBD, 0x15, 0x08, // 42:189 94 | 0x00, 0xD2, 0x15, 0x08, // 43:210 95 | 0x00, 0xE7, 0x15, 0x08, // 44:231 96 | 0x00, 0xFC, 0x29, 0x11, // 45:252 97 | 0xFF, 0xFF, 0x00, 0x00, // 46:65535 98 | 0x01, 0x25, 0x15, 0x08, // 47:293 99 | 0x01, 0x3A, 0x2D, 0x11, // 48:314 100 | 0x01, 0x67, 0x2D, 0x11, // 49:359 101 | 0x01, 0x94, 0x2C, 0x11, // 50:404 102 | 0x01, 0xC0, 0x2D, 0x11, // 51:448 103 | 0x01, 0xED, 0x2D, 0x11, // 52:493 104 | 0x02, 0x1A, 0x2D, 0x11, // 53:538 105 | 0x02, 0x47, 0x2D, 0x11, // 54:583 106 | 0x02, 0x74, 0x2D, 0x11, // 55:628 107 | 0x02, 0xA1, 0x2D, 0x11, // 56:673 108 | 0x02, 0xCE, 0x2D, 0x11, // 57:718 109 | 0x02, 0xFB, 0x09, 0x04, // 58:763 110 | 111 | // Font Data: 112 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 33 113 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 34 114 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 35 115 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 36 116 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 37 117 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 38 118 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 39 119 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 40 120 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 41 121 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 42 122 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 43 123 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 44 124 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10, // 45 125 | 0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0x02,0x40,0x00,0xFE,0x7F, // 47 126 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xEF,0x3F,0xF4,0xC7,0x5F,0x0C,0x00,0x60,0x0C,0x00,0x60,0x0C,0x00,0x60,0x0C,0x00,0x60,0x0C,0x00,0x60,0x0C,0x00,0x60,0x0C,0x00,0x60,0x0C,0x00,0x60,0x0C,0x00,0x60,0xF4,0xC7,0x5F,0xF8,0xEF,0x3F, // 48 127 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xC7,0x1F,0xF8,0xEF,0x3F, // 49 128 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x3F,0x04,0xD0,0x5F,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0xF4,0x17,0x40,0xF8,0x0F, // 50 129 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x10,0x40,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0xF4,0xD7,0x5F,0xF8,0xEF,0x3F, // 51 130 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0xF0,0x17,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0xF0,0xD7,0x1F,0xF8,0xEF,0x3F, // 52 131 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0xF4,0x17,0x40,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x04,0xD0,0x5F,0x00,0xE0,0x3F, // 53 132 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xEF,0x3F,0xF4,0xD7,0x5F,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x04,0xD0,0x5F,0x00,0xE0,0x3F, // 54 133 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0xF4,0x07,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0xF4,0xC7,0x1F,0xF8,0xEF,0x3F, // 55 134 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xEF,0x3F,0xF4,0xD7,0x5F,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0xF4,0xD7,0x5F,0xF8,0xEF,0x3F, // 56 135 | 0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0x00,0xF4,0x17,0x40,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0x0C,0x10,0x60,0xF4,0xD7,0x5F,0xF8,0xEF,0x3F, // 57 136 | 0x00,0x00,0x00,0x80,0x03,0x03,0x80,0x03,0x03 // 58 137 | }; 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /esp8266-weather-station-oled-DST-master/esp8266-weather-station-oled-DST/README.md: -------------------------------------------------------------------------------- 1 | # esp8266-weather-station-OLED-DST 2 | 3 | Daylight Saving Time and other customizations of Squix78 ESP8266 OLED Weather Station. 4 | Uses SSD1306 128x64 OLED display with with either SPI or I2C interface 5 | 6 | | New Splash Screen | DHT22 Update | 7 | |:-----------------:|:------------:| 8 | | ![cover](https://github.com/neptune2/esp8266-weather-station-oled-DST/raw/master/resources/splash.jpg) | ![DHT22 Update](https://github.com/neptune2/esp8266-weather-station-oled-DST/raw/master/resources/DHT22_update.jpg) | 9 | 10 | | Zurich Standard Time | Boston Daylight Saving Time | Conditions Screen | 11 | |:--------------------:|:---------------------------:|:-----------------:| 12 | | ![Zurich CET](https://github.com/neptune2/esp8266-weather-station-oled-DST/raw/master/resources/Zurich_CET.jpg) | ![Boston EDT](https://github.com/neptune2/esp8266-weather-station-oled-DST/raw/master/resources/Boston_EDT.jpg) | ![Conditions](https://github.com/neptune2/esp8266-weather-station-oled-DST/raw/master/resources/conditions.jpg) | 13 | 14 | | DHT Sensor | Thingspeak Sensor | 1 to 3 Day Forecast | 4 to 6 Day Forecast | 15 | |:----------:|:-----------------:|:-------------------:|:-------------------:| 16 | | ![DHT Sensor](https://github.com/neptune2/esp8266-weather-station-oled-DST/raw/master/resources/DHT22_sensor.jpg) | ![ThingSpeak Sensor](https://github.com/neptune2/esp8266-weather-station-oled-DST/raw/master/resources/thingspeak.jpg) | ![DHT Sensor](https://github.com/neptune2/esp8266-weather-station-oled-DST/raw/master/resources/1-3_day_forecast.jpg) | ![ThingSpeak Sensor](https://github.com/neptune2/esp8266-weather-station-oled-DST/raw/master/resources/4-6_day_forecast.jpg) | 17 | 18 | ## Specific customizations include: 19 | 20 | * Added Wifi Splash screen and credit to Squix78 21 | * Modified progress bar to a thicker and symmetrical shape 22 | * Replaced TimeClient with built-in lwip sntp client (no need for external ntp client library) 23 | * Added Daylight Saving Time Auto adjuster with DST rules using simpleDSTadjust library 24 | * https://github.com/neptune2/simpleDSTadjust 25 | * Added Locale Setting examples for Boston, Zurich and Sydney 26 | * Selectable NTP servers for each locale 27 | * DST rules and timezone settings customizable for each locale 28 | * See https://www.timeanddate.com/time/change/ for DST rules 29 | * Added AM/PM or 24-hour option for each locale 30 | * Changed Clock screen to 7-segment font from http://www.keshikan.net/fonts-e.html 31 | * Added Forecast screen for days 4-6 32 | * **>>> Need to change WundergroundClient.h in ESP8266_Weather_Station library** 33 | * `#define MAX_FORECAST_PERIODS 12 // Was 7` 34 | * Added support for DHT22 Indoor Temperature and Humidity 35 | * Fixed bug preventing display.flipScreenVertically() from working 36 | * Slight adjustment to overlay 37 | 38 | 39 | ## Hardware Requirements 40 | 41 | This code is made for an 128x64 SSD1603 OLED display with code running on an ESP8266. 42 | Either the SPI or I2C version can be used. 43 | You can buy the original Squix78 Weather Station Kit here: 44 | [Squix Shop](https://shop.squix.ch/index.php/esp8266.html) or here: [US Amazon store](https://www.amazon.com/gp/product/B01KE7BA3O) 45 | 46 | ## Software Requirements/ Libraries 47 | 48 | * [Arduino IDE with ESP8266 platform installed](https://github.com/esp8266/Arduino) 49 | * [Weather Station Library](https://github.com/squix78/esp8266-weather-station) or through Library Manager 50 | * [ESP8266 OLED SSD1306 Library](https://github.com/squix78/esp8266-oled-ssd1306) 51 | * [WifiManager Library](https://github.com/tzapu/WiFiManager) 52 | 53 | ### Additional required library for automatic Daylight Saving Time adjust 54 | * [simpleDSTadjust Library](https://github.com/neptune2/simpleDSTadjust) 55 | 56 | You also need to get an API key for the Wunderground data: https://www.wunderground.com/ 57 | 58 | ## Wemos D1R2 Wiring 59 | ![Wemos D1R2 and DHT22 sensor](https://github.com/neptune2/esp8266-weather-station-oled-DST/raw/master/resources/cover.jpg) 60 | 61 | See code for pin configurations 62 | 63 | | SSD1306 SPI | Wemos D1R2 | 64 | | ----------- |:----------:| 65 | | CS | D8 | 66 | | DC | D2 | 67 | | RST | D0 | 68 | | D1 | D7 | 69 | | D0 | D5 | 70 | | GND | GND | 71 | | VCC | 3V3 | 72 | 73 | | DHT22 | Wemos D1R2 | 74 | | ----- |:----------:| 75 | | DATA | D4 | 76 | | GND | GND | 77 | | VCC | 3V3 | 78 | -------------------------------------------------------------------------------- /esp8266-weather-station-oled-DST-master/esp8266-weather-station-oled-DST/WeatherStationImages.h: -------------------------------------------------------------------------------- 1 | #define WiFi_Logo_width 60 2 | #define WiFi_Logo_height 36 3 | const char WiFi_Logo_bits[] PROGMEM = { 4 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 5 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 6 | 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 7 | 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 8 | 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 9 | 0xFF, 0x03, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 10 | 0x00, 0xFF, 0xFF, 0xFF, 0x07, 0xC0, 0x83, 0x01, 0x80, 0xFF, 0xFF, 0xFF, 11 | 0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0C, 0x00, 12 | 0xC0, 0xFF, 0xFF, 0x7C, 0x00, 0x60, 0x0C, 0x00, 0xC0, 0x31, 0x46, 0x7C, 13 | 0xFC, 0x77, 0x08, 0x00, 0xE0, 0x23, 0xC6, 0x3C, 0xFC, 0x67, 0x18, 0x00, 14 | 0xE0, 0x23, 0xE4, 0x3F, 0x1C, 0x00, 0x18, 0x00, 0xE0, 0x23, 0x60, 0x3C, 15 | 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x03, 0x60, 0x3C, 0x1C, 0x70, 0x18, 0x00, 16 | 0xE0, 0x07, 0x60, 0x3C, 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 17 | 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 18 | 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x8F, 0x71, 0x3C, 19 | 0x1C, 0x70, 0x18, 0x00, 0xC0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x08, 0x00, 20 | 0xC0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x0C, 0x00, 0x80, 0xFF, 0xFF, 0x1F, 21 | 0x00, 0x00, 0x06, 0x00, 0x80, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x07, 0x00, 22 | 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 23 | 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 24 | 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 25 | 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 26 | 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28 | }; 29 | 30 | const char emptySymbol[] PROGMEM = { 31 | B00000000, 32 | B00000000, 33 | B00000000, 34 | B00000000, 35 | B00000000, 36 | B00000000, 37 | B00000000, 38 | B00000000 39 | }; 40 | 41 | const char activeSymbol[] PROGMEM = { 42 | B00000000, 43 | B00000000, 44 | B00011000, 45 | B00100100, 46 | B01000010, 47 | B01000010, 48 | B00100100, 49 | B00011000 50 | }; 51 | 52 | const char inactiveSymbol[] PROGMEM = { 53 | B00000000, 54 | B00000000, 55 | B00000000, 56 | B00000000, 57 | B00011000, 58 | B00011000, 59 | B00000000, 60 | B00000000 61 | }; 62 | -------------------------------------------------------------------------------- /esp8266-weather-station-oled-DST-master/esp8266-weather-station-oled-DST/esp8266-weather-station-oled-DST.ino: -------------------------------------------------------------------------------- 1 | /**The MIT License (MIT) 2 | 3 | Copyright (c) 2016 by Daniel Eichhorn 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 | 23 | See more at http://blog.squix.ch 24 | */ 25 | 26 | /* Customizations by Neptune (NeptuneEng on Twitter, Neptune2 on Github) 27 | * 28 | * Added Wifi Splash screen and credit to Squix78 29 | * Modified progress bar to a thicker and symmetrical shape 30 | * Replaced TimeClient with built-in lwip sntp client (no need for external ntp client library) 31 | * Added Daylight Saving Time Auto adjuster with DST rules using simpleDSTadjust library 32 | * https://github.com/neptune2/simpleDSTadjust 33 | * Added Setting examples for Boston, Zurich and Sydney 34 | * Selectable NTP servers for each locale 35 | * DST rules and timezone settings customizable for each locale 36 | * See https://www.timeanddate.com/time/change/ for DST rules 37 | * Added AM/PM or 24-hour option for each locale 38 | * Changed to 7-segment Clock font from http://www.keshikan.net/fonts-e.html 39 | * Added Forecast screen for days 4-6 40 | * >>> Need to change WundergroundClient.h in ESP8266_Weather_Station library 41 | * #define MAX_FORECAST_PERIODS 12 // Was 7 42 | * Added support for DHT22 Indoor Temperature and Humidity 43 | * Fixed bug preventing display.flipScreenVertically() from working 44 | * Slight adjustment to overlay 45 | */ 46 | 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | 53 | #include 54 | #include 55 | #include 56 | 57 | #include "SSD1306.h" 58 | //#include "SSD1306Wire.h" 59 | // #include // Only needed for Arduino 1.6.5 and earlier 60 | //#include "SSD1306Spi.h" 61 | #include "OLEDDisplayUi.h" 62 | #include "Wire.h" 63 | #include "WundergroundClient.h" 64 | #include "WeatherStationFonts.h" 65 | #include "WeatherStationImages.h" 66 | #include "DSEG7Classic-BoldFont.h" 67 | #include 68 | #include "DHT.h" 69 | #include "ThingspeakClient.h" 70 | #include 71 | #include 72 | 73 | /*************************** 74 | * Begin Settings 75 | **************************/ 76 | // Please read http://blog.squix.org/weatherstation-getting-code-adapting-it 77 | // for setup instructions 78 | 79 | #define HOSTNAME "ESP8266-OTA-WEATHER-" 80 | 81 | // Setup 82 | const int UPDATE_INTERVAL_SECS = 10 * 60; // Update every 10 minutes 83 | 84 | // Display Settings 85 | // Pin definitions for SPI OLED 86 | //#define OLED_CS D8 // Chip select 87 | //#define OLED_DC D2 // Data/Command 88 | //#define OLED_RESET D0 // RESET 89 | // Pin definitions for i2c 90 | const int I2C_DISPLAY_ADDRESS = 0x3c; 91 | //const int SDA_PIN = D3; // NodeMCU 92 | //const int SDC_PIN = D4; // NodeMCU 93 | const int SDA_PIN = D2; // Wemos D1 Mini 94 | const int SDC_PIN = D3; // Wemos D1 Mini 95 | 96 | 97 | 98 | // DHT Settings 99 | // #define DHTPIN D2 // NodeMCU 100 | #define DHTPIN D4 // Wemos D1R2 Mini 101 | #define DHTTYPE 22 // DHT22 (AM2302), AM2321 102 | char FormattedTemperature[10]; 103 | char FormattedHumidity[10]; 104 | 105 | //MQTT / HomeKit 106 | // Update these with values suitable for your network. 107 | IPAddress MQTTserver(192, 168, 1, 1); 108 | WiFiClient wclient; 109 | PubSubClient client(wclient, MQTTserver); 110 | 111 | // ----------------------------------- 112 | // Locales (uncomment only 1) 113 | #define Genova 114 | //#define Boston 115 | // #define Sydney 116 | //------------------------------------ 117 | 118 | #ifdef Genova 119 | //DST rules for Central European Time Zone 120 | #define UTC_OFFSET +1 121 | struct dstRule StartRule = {"CEST", Last, Sun, Mar, 2, 3600}; // Central European Summer Time = UTC/GMT +2 hours 122 | struct dstRule EndRule = {"CET", Last, Sun, Oct, 2, 0}; // Central European Time = UTC/GMT +1 hour 123 | 124 | // Uncomment for 24 Hour style clock 125 | #define STYLE_24HR 126 | 127 | #define NTP_SERVERS "0.ch.pool.ntp.org", "1.ch.pool.ntp.org", "2.ch.pool.ntp.org" 128 | 129 | // Wunderground Settings 130 | const boolean IS_METRIC = true; 131 | const String WUNDERGRROUND_API_KEY = "___"; 132 | const String WUNDERGRROUND_LANGUAGE = "IT"; 133 | const String WUNDERGROUND_COUNTRY = "IT"; 134 | const String WUNDERGROUND_CITY = "Genova"; 135 | const String WUNDERGROUND_PWS = "IGENOVA170"; 136 | #endif 137 | 138 | /*#ifdef Boston 139 | //DST rules for US Eastern Time Zone (New York, Boston) 140 | #define UTC_OFFSET -5 141 | struct dstRule StartRule = {"EDT", Second, Sun, Mar, 2, 3600}; // Eastern Daylight time = UTC/GMT -4 hours 142 | struct dstRule EndRule = {"EST", First, Sun, Nov, 1, 0}; // Eastern Standard time = UTC/GMT -5 hour 143 | 144 | // Uncomment for 24 Hour style clock 145 | #define STYLE_24HR 146 | 147 | #define NTP_SERVERS "us.pool.ntp.org", "time.nist.gov", "pool.ntp.org" 148 | 149 | // Wunderground Settings 150 | const boolean IS_METRIC = false; 151 | const String WUNDERGRROUND_API_KEY = ""; 152 | const String WUNDERGRROUND_LANGUAGE = "EN"; 153 | const String WUNDERGROUND_COUNTRY = "MA"; 154 | const String WUNDERGROUND_CITY = "Boston"; 155 | #endif 156 | 157 | #ifdef Sydney 158 | //DST Rules for Australia Eastern Time Zone (Sydney) 159 | #define UTC_OFFSET +10 160 | struct dstRule StartRule = {"AEDT", First, Sun, Oct, 2, 3600}; // Australia Eastern Daylight time = UTC/GMT +11 hours 161 | struct dstRule EndRule = {"AEST", First, Sun, Apr, 2, 0}; // Australia Eastern Standard time = UTC/GMT +10 hour 162 | 163 | // Uncomment for 24 Hour style clock 164 | //#define STYLE_24HR 165 | 166 | #define NTP_SERVERS "0.au.pool.ntp.org", "1.au.pool.ntp.org", "2.au.pool.ntp.org" 167 | 168 | // Wunderground Settings 169 | const boolean IS_METRIC = true; 170 | const String WUNDERGRROUND_API_KEY = ""; 171 | const String WUNDERGRROUND_LANGUAGE = "EN"; 172 | const String WUNDERGROUND_COUNTRY = "AU"; 173 | const String WUNDERGROUND_CITY = "Sydney"; 174 | #endif*/ 175 | 176 | #define italiano 177 | 178 | #ifdef english 179 | String str_mon[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; 180 | String str_wday[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}; 181 | #endif 182 | 183 | #ifdef italiano 184 | String str_mon[] = {"Gen", "Feb", "Marzo", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"}; 185 | String str_wday[] = {"Dom", "lun", "Mar", "Mer", "Gio", "Ven", "Sab"}; // 3 letras 186 | // String str_wday[] = {"lu", "ma", "mi", "ju", "vi", "sa", "do"}; // 2 letras 187 | #endif 188 | 189 | 190 | 191 | void HomeKit(){ 192 | if (WiFi.status() == WL_CONNECTED) { 193 | if (!client.connected()) { 194 | if (client.connect("ESPNurseryTemperatureSensor")) { 195 | client.publish("HomeKit","Nursery Temperature Sensor Online!"); 196 | } 197 | } 198 | 199 | if (client.connected()){ 200 | Serial.println("publishing"); 201 | client.publish("NurseryTemperature",String(FormattedTemperature)); 202 | client.loop(); 203 | } 204 | 205 | } 206 | } 207 | 208 | //Thingspeak Settings 209 | const String THINGSPEAK_CHANNEL_ID = "67284"; 210 | const String THINGSPEAK_API_READ_KEY = "L2VIW20QVNZJBLAK"; 211 | 212 | // Initialize the I2 oled display for address 0x3c 213 | // sda-pin=14 and sdc-pin=12 214 | SSD1306Wire display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN); 215 | 216 | // SPI OLED 217 | //SSD1306Spi display(OLED_RESET, OLED_DC, OLED_CS); 218 | 219 | OLEDDisplayUi ui( &display ); 220 | 221 | // Setup simpleDSTadjust Library rules 222 | simpleDSTadjust dstAdjusted(StartRule, EndRule); 223 | 224 | /*************************** 225 | * End Settings 226 | **************************/ 227 | 228 | // TimeClient timeClient(UTC_OFFSET); 229 | 230 | // Set to false, if you prefere imperial/inches, Fahrenheit 231 | WundergroundClient wunderground(IS_METRIC); 232 | 233 | // Initialize the temperature/ humidity sensor 234 | DHT dht(DHTPIN, DHTTYPE); 235 | float humidity = 0.0; 236 | float temperature = 0.0; 237 | 238 | ThingspeakClient thingspeak; 239 | 240 | // flag changed in the ticker function every 10 minutes 241 | bool readyForWeatherUpdate = false; 242 | // flag changed in the ticker function every 1 minute 243 | bool readyForDHTUpdate = false; 244 | 245 | String lastUpdate = "--"; 246 | 247 | Ticker ticker; 248 | Ticker weathertick; 249 | 250 | //declaring prototypes 251 | void configModeCallback (WiFiManager *myWiFiManager); 252 | void drawProgress(OLEDDisplay *display, int percentage, String label); 253 | void drawOtaProgress(unsigned int, unsigned int); 254 | void updateData(OLEDDisplay *display); 255 | void drawDateTime(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); 256 | void drawCurrentWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); 257 | void drawForecast(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); 258 | void drawForecast2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); 259 | void drawIndoor(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); 260 | void drawThingspeak(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y); 261 | void drawForecastDetails(OLEDDisplay *display, int x, int y, int dayIndex); 262 | void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state); 263 | void setReadyForWeatherUpdate(); 264 | int8_t getWifiQuality(); 265 | 266 | 267 | // Add frames 268 | // this array keeps function pointers to all frames 269 | // frames are the single views that slide from right to left 270 | FrameCallback frames[] = { drawDateTime, drawCurrentWeather, drawIndoor, drawForecast }; 271 | //FrameCallback frames[] = { drawDateTime, drawCurrentWeather, drawIndoor, drawThingspeak, drawForecast, drawForecast2 }; 272 | int numberOfFrames = 4; 273 | 274 | OverlayCallback overlays[] = { drawHeaderOverlay }; 275 | int numberOfOverlays = 1; 276 | 277 | 278 | 279 | void setup() { 280 | // Turn On VCC 281 | // pinMode(D4, OUTPUT); 282 | // digitalWrite(D4, HIGH); 283 | Serial.begin(115200); 284 | 285 | // initialize dispaly 286 | display.init(); 287 | display.clear(); 288 | display.display(); 289 | 290 | display.flipScreenVertically(); // Comment out to flip display 180deg 291 | display.setFont(ArialMT_Plain_10); 292 | display.setTextAlignment(TEXT_ALIGN_CENTER); 293 | display.setContrast(255); 294 | 295 | // Credit where credit is due 296 | display.drawXbm(-6, 5, WiFi_Logo_width, WiFi_Logo_height, WiFi_Logo_bits); 297 | display.drawString(88, 18, "Weather Station\nBy Simone"); 298 | display.display(); 299 | 300 | //WiFiManager 301 | //Local intialization. Once its business is done, there is no need to keep it around 302 | WiFiManager wifiManager; 303 | // Uncomment for testing wifi manager 304 | // wifiManager.resetSettings(); 305 | wifiManager.setAPCallback(configModeCallback); 306 | 307 | //or use this for auto generated name ESP + ChipID 308 | // wifiManager.autoConnect(); 309 | 310 | //Manual Wifi 311 | const char* SSID = "___"; 312 | const char* PASSWORD = "___"; 313 | WiFi.begin(SSID, PASSWORD); 314 | String hostname(HOSTNAME); 315 | hostname += String(ESP.getChipId(), HEX); 316 | WiFi.hostname(hostname); 317 | 318 | 319 | int counter = 0; 320 | while (WiFi.status() != WL_CONNECTED) { 321 | delay(500); 322 | Serial.print("."); 323 | display.clear(); 324 | display.drawString(64, 10, "Connessione alla WiFi"); 325 | display.drawXbm(46, 30, 8, 8, counter % 3 == 0 ? activeSymbol : inactiveSymbol); 326 | display.drawXbm(60, 30, 8, 8, counter % 3 == 1 ? activeSymbol : inactiveSymbol); 327 | display.drawXbm(74, 30, 8, 8, counter % 3 == 2 ? activeSymbol : inactiveSymbol); 328 | display.display(); 329 | 330 | counter++; 331 | } 332 | 333 | ui.setTargetFPS(30); 334 | ui.setTimePerFrame(10*1000); // Setup frame display time to 10 sec 335 | 336 | //Hack until disableIndicator works: 337 | //Set an empty symbol 338 | ui.setActiveSymbol(emptySymbol); 339 | ui.setInactiveSymbol(emptySymbol); 340 | 341 | ui.disableIndicator(); 342 | 343 | // You can change the transition that is used 344 | // SLIDE_LEFT, SLIDE_RIGHT, SLIDE_TOP, SLIDE_DOWN 345 | ui.setFrameAnimation(SLIDE_LEFT); 346 | 347 | ui.setFrames(frames, numberOfFrames); 348 | 349 | ui.setOverlays(overlays, numberOfOverlays); 350 | 351 | // Inital UI takes care of initalising the display too. 352 | // ui.init(); // not necessary - already done above, breaks flipScreenVertically() 353 | 354 | // Setup OTA 355 | Serial.println("Hostname: " + hostname); 356 | ArduinoOTA.setHostname((const char *)hostname.c_str()); 357 | ArduinoOTA.onProgress(drawOtaProgress); 358 | ArduinoOTA.begin(); 359 | 360 | updateData(&display); 361 | 362 | //ticker.attach(UPDATE_INTERVAL_SECS, setReadyForWeatherUpdate); 363 | ticker.attach(60, setReadyForDHTUpdate); 364 | weathertick.attach(UPDATE_INTERVAL_SECS, setReadyForWeatherUpdate); 365 | } 366 | 367 | void loop() { 368 | 369 | if (readyForWeatherUpdate && ui.getUiState()->frameState == FIXED) { 370 | updateData(&display); 371 | } 372 | 373 | if (readyForDHTUpdate && ui.getUiState()->frameState == FIXED) 374 | updateDHT(); 375 | 376 | int remainingTimeBudget = ui.update(); 377 | 378 | if (remainingTimeBudget > 0) { 379 | // You can do some work here 380 | // Don't do stuff if you are below your 381 | // time budget. 382 | ArduinoOTA.handle(); 383 | delay(remainingTimeBudget); 384 | } 385 | } 386 | 387 | void configModeCallback (WiFiManager *myWiFiManager) { 388 | Serial.println("Entered config mode"); 389 | Serial.println(WiFi.softAPIP()); 390 | //if you used auto generated SSID, print it 391 | Serial.println(myWiFiManager->getConfigPortalSSID()); 392 | display.clear(); 393 | display.setTextAlignment(TEXT_ALIGN_CENTER); 394 | display.setFont(ArialMT_Plain_10); 395 | display.drawString(64, 10, "Wifi Manager"); 396 | display.drawString(64, 20, "Please connect to AP"); 397 | display.drawString(64, 30, myWiFiManager->getConfigPortalSSID()); 398 | display.drawString(64, 40, "To setup Wifi Configuration"); 399 | display.display(); 400 | } 401 | 402 | void drawProgress(OLEDDisplay *display, int percentage, String label) { 403 | display->clear(); 404 | display->setTextAlignment(TEXT_ALIGN_CENTER); 405 | display->setFont(ArialMT_Plain_10); 406 | display->drawString(64, 10, label); 407 | display->drawProgressBar(2, 28, 124, 12, percentage); 408 | display->display(); 409 | } 410 | 411 | void drawOtaProgress(unsigned int progress, unsigned int total) { 412 | display.clear(); 413 | display.setTextAlignment(TEXT_ALIGN_CENTER); 414 | display.setFont(ArialMT_Plain_10); 415 | display.drawString(64, 10, "OTA Update"); 416 | display.drawProgressBar(2, 28, 124, 12, progress / (total / 100)); 417 | display.display(); 418 | } 419 | 420 | void updateData(OLEDDisplay *display) { 421 | drawProgress(display, 10, "Aggiornamento data..."); 422 | configTime(UTC_OFFSET * 3600, 0, NTP_SERVERS); 423 | drawProgress(display, 30, "Aggiornamento meteo..."); 424 | //wunderground.updateConditions(WUNDERGRROUND_API_KEY, WUNDERGRROUND_LANGUAGE, WUNDERGROUND_COUNTRY, WUNDERGROUND_CITY); 425 | wunderground.updateConditionsPws(WUNDERGRROUND_API_KEY, WUNDERGRROUND_LANGUAGE, WUNDERGROUND_PWS); 426 | drawProgress(display, 50, "Aggiornamento previsioni..."); 427 | //wunderground.updateForecast(WUNDERGRROUND_API_KEY, WUNDERGRROUND_LANGUAGE, WUNDERGROUND_COUNTRY, WUNDERGROUND_CITY); 428 | wunderground.updateForecast(WUNDERGRROUND_API_KEY, WUNDERGRROUND_LANGUAGE, WUNDERGROUND_PWS); 429 | drawProgress(display, 70, "Aggiornamento Hum DHT..."); 430 | humidity = dht.readHumidity(); 431 | drawProgress(display, 80, "Aggiornamento Temp DHT..."); 432 | temperature = dht.readTemperature(!IS_METRIC); 433 | delay(500); 434 | 435 | drawProgress(display, 90, "Fine aggiornamento..."); 436 | thingspeak.getLastChannelItem(THINGSPEAK_CHANNEL_ID, THINGSPEAK_API_READ_KEY); 437 | readyForWeatherUpdate = false; 438 | drawProgress(display, 100, "Fatto..."); 439 | delay(1000); 440 | } 441 | 442 | // Called every 1 minute 443 | void updateDHT() { 444 | humidity = dht.readHumidity(); 445 | temperature = dht.readTemperature(!IS_METRIC); 446 | readyForDHTUpdate = false; 447 | // MQTT 448 | HomeKit(); 449 | } 450 | 451 | 452 | void drawDateTime(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 453 | char *dstAbbrev; 454 | char time_str[11]; 455 | time_t now = dstAdjusted.time(&dstAbbrev); 456 | struct tm * timeinfo = localtime (&now); 457 | 458 | display->setTextAlignment(TEXT_ALIGN_CENTER); 459 | display->setFont(ArialMT_Plain_10); 460 | String date = ctime(&now); 461 | date = str_wday[timeinfo->tm_wday] + " " + String(timeinfo->tm_mday) + " " + str_mon[timeinfo->tm_mon] + " " + String(1900+timeinfo->tm_year); 462 | //date = date.substring(0,4) + String(timeinfo->tm_mday) + date.substring(3,8) + String(1900+timeinfo->tm_year); 463 | //date = date.substring(0,11) + String(1900+timeinfo->tm_year); 464 | int textWidth = display->getStringWidth(date); 465 | display->drawString(64 + x, 5 + y, date); 466 | display->setFont(DSEG7_Classic_Bold_21); 467 | display->setTextAlignment(TEXT_ALIGN_RIGHT); 468 | 469 | #ifdef STYLE_24HR 470 | sprintf(time_str, "%02d:%02d:%02d\n",timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); 471 | display->drawString(108 + x, 19 + y, time_str); 472 | #else 473 | int hour = (timeinfo->tm_hour+11)%12+1; // take care of noon and midnight 474 | sprintf(time_str, "%2d:%02d:%02d\n",hour, timeinfo->tm_min, timeinfo->tm_sec); 475 | display->drawString(101 + x, 19 + y, time_str); 476 | #endif 477 | 478 | display->setTextAlignment(TEXT_ALIGN_LEFT); 479 | display->setFont(ArialMT_Plain_10); 480 | #ifdef STYLE_24HR 481 | sprintf(time_str, "%s", dstAbbrev); 482 | display->drawString(108 + x, 27 + y, time_str); // Known bug: Cuts off 4th character of timezone abbreviation 483 | #else 484 | sprintf(time_str, "%s\n%s", dstAbbrev, timeinfo->tm_hour>=12?"pm":"am"); 485 | display->drawString(102 + x, 18 + y, time_str); 486 | #endif 487 | 488 | } 489 | 490 | void drawCurrentWeather(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 491 | display->setFont(ArialMT_Plain_10); 492 | display->setTextAlignment(TEXT_ALIGN_LEFT); 493 | display->drawString(50 + x, 5 + y, wunderground.getWeatherText()); 494 | 495 | display->setFont(ArialMT_Plain_24); 496 | String temp = wunderground.getCurrentTemp() + (IS_METRIC ? "°C": "°F"); 497 | 498 | display->drawString(50 + x, 15 + y, temp); 499 | int tempWidth = display->getStringWidth(temp); 500 | 501 | display->setFont(Meteocons_Plain_42); 502 | String weatherIcon = wunderground.getTodayIcon(); 503 | int weatherIconWidth = display->getStringWidth(weatherIcon); 504 | display->drawString(28 + x - weatherIconWidth / 2, 05 + y, weatherIcon); 505 | } 506 | 507 | 508 | void drawForecast(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 509 | drawForecastDetails(display, x, y, 0); 510 | drawForecastDetails(display, x + 44, y, 2); 511 | drawForecastDetails(display, x + 88, y, 4); 512 | } 513 | 514 | void drawForecast2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 515 | drawForecastDetails(display, x, y, 6); 516 | drawForecastDetails(display, x + 44, y, 8); 517 | drawForecastDetails(display, x + 88, y, 10); 518 | } 519 | 520 | void drawIndoor(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 521 | display->setTextAlignment(TEXT_ALIGN_CENTER); 522 | display->setFont(ArialMT_Plain_10); 523 | display->drawString(64 + x, 0, "Sensore interno"); 524 | display->setFont(ArialMT_Plain_16); 525 | dtostrf(temperature,4, 1, FormattedTemperature); 526 | display->drawString(64+x, 12, "Temp: " + String(FormattedTemperature) + (IS_METRIC ? "°C": "°F")); 527 | dtostrf(humidity,4, 1, FormattedHumidity); 528 | display->drawString(64+x, 30, "Hum: " + String(FormattedHumidity) + "%"); 529 | 530 | } 531 | 532 | void drawThingspeak(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) { 533 | display->setTextAlignment(TEXT_ALIGN_CENTER); 534 | display->setFont(ArialMT_Plain_10); 535 | display->drawString(64 + x, 0 + y, "Thingspeak Sensor"); 536 | display->setFont(ArialMT_Plain_16); 537 | display->drawString(64 + x, 12 + y, thingspeak.getFieldValue(0) + "°C"); 538 | // display->drawString(64 + x, 12 + y, thingspeak.getFieldValue(0) + (IS_METRIC ? "°C": "°F")); // Needs code to convert Thingspeak temperature string 539 | display->drawString(64 + x, 30 + y, thingspeak.getFieldValue(1) + "%"); 540 | } 541 | 542 | void drawForecastDetails(OLEDDisplay *display, int x, int y, int dayIndex) { 543 | display->setTextAlignment(TEXT_ALIGN_CENTER); 544 | display->setFont(ArialMT_Plain_10); 545 | String day = wunderground.getForecastTitle(dayIndex).substring(0, 3); 546 | day.toUpperCase(); 547 | display->drawString(x + 20, y, day); 548 | 549 | display->setFont(Meteocons_Plain_21); 550 | display->drawString(x + 20, y + 12, wunderground.getForecastIcon(dayIndex)); 551 | 552 | display->setFont(ArialMT_Plain_10); 553 | display->drawString(x + 20, y + 34, wunderground.getForecastLowTemp(dayIndex) + " - " + wunderground.getForecastHighTemp(dayIndex)); 554 | display->setTextAlignment(TEXT_ALIGN_LEFT); 555 | } 556 | 557 | void drawHeaderOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) { 558 | char time_str[11]; 559 | time_t now = dstAdjusted.time(nullptr); 560 | struct tm * timeinfo = localtime (&now); 561 | 562 | display->setFont(ArialMT_Plain_10); 563 | 564 | #ifdef STYLE_24HR 565 | sprintf(time_str, "%02d:%02d:%02d\n",timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); 566 | #else 567 | int hour = (timeinfo->tm_hour+11)%12+1; // take care of noon and midnight 568 | sprintf(time_str, "%2d:%02d:%02d%s\n",hour, timeinfo->tm_min, timeinfo->tm_sec, timeinfo->tm_hour>=12?"pm":"am"); 569 | #endif 570 | 571 | display->setTextAlignment(TEXT_ALIGN_LEFT); 572 | display->drawString(5, 52, time_str); 573 | 574 | display->setTextAlignment(TEXT_ALIGN_CENTER); 575 | String temp = wunderground.getCurrentTemp() + (IS_METRIC ? "°C": "°F"); 576 | display->drawString(101, 52, temp); 577 | 578 | int8_t quality = getWifiQuality(); 579 | for (int8_t i = 0; i < 4; i++) { 580 | for (int8_t j = 0; j < 2 * (i + 1); j++) { 581 | if (quality > i * 25 || j == 0) { 582 | display->setPixel(120 + 2 * i, 61 - j); 583 | } 584 | } 585 | } 586 | 587 | 588 | display->setTextAlignment(TEXT_ALIGN_CENTER); 589 | display->setFont(Meteocons_Plain_10); 590 | String weatherIcon = wunderground.getTodayIcon(); 591 | int weatherIconWidth = display->getStringWidth(weatherIcon); 592 | // display->drawString(64, 55, weatherIcon); 593 | display->drawString(77, 53, weatherIcon); 594 | 595 | display->drawHorizontalLine(0, 51, 128); 596 | 597 | } 598 | 599 | // converts the dBm to a range between 0 and 100% 600 | int8_t getWifiQuality() { 601 | int32_t dbm = WiFi.RSSI(); 602 | if(dbm <= -100) { 603 | return 0; 604 | } else if(dbm >= -50) { 605 | return 100; 606 | } else { 607 | return 2 * (dbm + 100); 608 | } 609 | } 610 | 611 | void setReadyForWeatherUpdate() { 612 | Serial.println("Setting readyForUpdate to true"); 613 | readyForWeatherUpdate = true; 614 | } 615 | 616 | void setReadyForDHTUpdate() { 617 | Serial.println("Setting readyForDHTUpdate to true"); 618 | readyForDHTUpdate = true; 619 | } 620 | 621 | -------------------------------------------------------------------------------- /esp8266-weather-station-oled-DST-master/resources/1-3_day_forecast.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Supersimo88/Arduino-ESP8266-HomeKit/8dce60573587cb245d3ca042adf26854feb60ecb/esp8266-weather-station-oled-DST-master/resources/1-3_day_forecast.jpg -------------------------------------------------------------------------------- /esp8266-weather-station-oled-DST-master/resources/4-6_day_forecast.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Supersimo88/Arduino-ESP8266-HomeKit/8dce60573587cb245d3ca042adf26854feb60ecb/esp8266-weather-station-oled-DST-master/resources/4-6_day_forecast.jpg -------------------------------------------------------------------------------- /esp8266-weather-station-oled-DST-master/resources/Boston_EDT.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Supersimo88/Arduino-ESP8266-HomeKit/8dce60573587cb245d3ca042adf26854feb60ecb/esp8266-weather-station-oled-DST-master/resources/Boston_EDT.jpg -------------------------------------------------------------------------------- /esp8266-weather-station-oled-DST-master/resources/DHT22_sensor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Supersimo88/Arduino-ESP8266-HomeKit/8dce60573587cb245d3ca042adf26854feb60ecb/esp8266-weather-station-oled-DST-master/resources/DHT22_sensor.jpg -------------------------------------------------------------------------------- /esp8266-weather-station-oled-DST-master/resources/DHT22_update.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Supersimo88/Arduino-ESP8266-HomeKit/8dce60573587cb245d3ca042adf26854feb60ecb/esp8266-weather-station-oled-DST-master/resources/DHT22_update.jpg -------------------------------------------------------------------------------- /esp8266-weather-station-oled-DST-master/resources/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Supersimo88/Arduino-ESP8266-HomeKit/8dce60573587cb245d3ca042adf26854feb60ecb/esp8266-weather-station-oled-DST-master/resources/Thumbs.db -------------------------------------------------------------------------------- /esp8266-weather-station-oled-DST-master/resources/Zurich_CET.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Supersimo88/Arduino-ESP8266-HomeKit/8dce60573587cb245d3ca042adf26854feb60ecb/esp8266-weather-station-oled-DST-master/resources/Zurich_CET.jpg -------------------------------------------------------------------------------- /esp8266-weather-station-oled-DST-master/resources/conditions.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Supersimo88/Arduino-ESP8266-HomeKit/8dce60573587cb245d3ca042adf26854feb60ecb/esp8266-weather-station-oled-DST-master/resources/conditions.jpg -------------------------------------------------------------------------------- /esp8266-weather-station-oled-DST-master/resources/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Supersimo88/Arduino-ESP8266-HomeKit/8dce60573587cb245d3ca042adf26854feb60ecb/esp8266-weather-station-oled-DST-master/resources/cover.jpg -------------------------------------------------------------------------------- /esp8266-weather-station-oled-DST-master/resources/splash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Supersimo88/Arduino-ESP8266-HomeKit/8dce60573587cb245d3ca042adf26854feb60ecb/esp8266-weather-station-oled-DST-master/resources/splash.jpg -------------------------------------------------------------------------------- /esp8266-weather-station-oled-DST-master/resources/thingspeak.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Supersimo88/Arduino-ESP8266-HomeKit/8dce60573587cb245d3ca042adf26854feb60ecb/esp8266-weather-station-oled-DST-master/resources/thingspeak.jpg --------------------------------------------------------------------------------