├── 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 | 
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 | 
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 | |  |  |
9 |
10 | | Zurich Standard Time | Boston Daylight Saving Time | Conditions Screen |
11 | |:--------------------:|:---------------------------:|:-----------------:|
12 | |  |  |  |
13 |
14 | | DHT Sensor | Thingspeak Sensor | 1 to 3 Day Forecast | 4 to 6 Day Forecast |
15 | |:----------:|:-----------------:|:-------------------:|:-------------------:|
16 | |  |  |  |  |
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 | 
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
--------------------------------------------------------------------------------