WeatherMatrix.ino 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. #include <FastLED.h>
  2. #include <ArduinoJson.h>
  3. #include <ESP8266HTTPClient.h>
  4. #include <ESP8266WiFi.h>
  5. #include <ESP8266WiFiMulti.h>
  6. #include <WiFiClient.h>
  7. #define LED_PIN 0
  8. #define COLOR_ORDER GRB
  9. #define CHIPSET WS2811
  10. #define BRIGHTNESS 10
  11. #ifndef STASSID
  12. #define STASSID "FNT-Gast"
  13. #define STAPSK "Laserjet09"
  14. #endif
  15. const char* ssid = STASSID;
  16. const char* password = STAPSK;
  17. // networking and json
  18. String apiUrl;
  19. int status = WL_IDLE_STATUS;
  20. ESP8266WiFiMulti WiFiMulti;
  21. WiFiClient client;
  22. HTTPClient http;
  23. unsigned long millisTime;
  24. boolean firstIteration = true;
  25. void connectWiFi() {
  26. // We start by connecting to a WiFi network
  27. WiFi.mode(WIFI_STA);
  28. WiFiMulti.addAP(ssid, password);
  29. Serial.println();
  30. Serial.println();
  31. Serial.print("Wait for WiFi... ");
  32. while (WiFiMulti.run() != WL_CONNECTED) {
  33. Serial.print(".");
  34. delay(500);
  35. }
  36. Serial.println("");
  37. Serial.println("WiFi connected");
  38. Serial.println("IP address: ");
  39. Serial.println(WiFi.localIP());
  40. delay(500);
  41. }
  42. String buildAPIUrl (double lat, double lon, const String& apiKey) {
  43. const String latStr(lat, 4);
  44. const String lonStr(lon, 4);
  45. return String("http://api.openweathermap.org/data/2.5/weather?lat=" +
  46. latStr + "&lon=" + lonStr + "&appid=" + apiKey);
  47. }
  48. // Params for width and height
  49. const uint8_t kMatrixWidth = 16;
  50. const uint8_t kMatrixHeight = 16;
  51. uint16_t XY( uint8_t x, uint8_t y)
  52. {
  53. uint16_t i;
  54. if ( x & 0x01) {
  55. i = kMatrixHeight * (kMatrixWidth - (x + 1)) + y;
  56. } else {
  57. i = kMatrixHeight * (kMatrixWidth - x) - (y + 1);
  58. }
  59. return i;
  60. }
  61. #define NUM_LEDS (kMatrixWidth * kMatrixHeight)
  62. CRGB leds_plus_safety_pixel[ NUM_LEDS + 1];
  63. CRGB* const leds( leds_plus_safety_pixel + 1);
  64. uint16_t XYsafe( uint8_t x, uint8_t y)
  65. {
  66. if ( x >= kMatrixWidth) return -1;
  67. if ( y >= kMatrixHeight) return -1;
  68. return XY(x, y);
  69. }
  70. uint8_t sun_yx[16][16] = {
  71. {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  72. {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
  73. {0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0},
  74. {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
  75. {1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1},
  76. {0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0},
  77. {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
  78. {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0},
  79. {0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
  80. {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
  81. {0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0},
  82. {1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1},
  83. {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
  84. {0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0},
  85. {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
  86. {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
  87. };
  88. uint8_t cloud_yx[16][16] = {
  89. {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  90. {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  91. {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
  92. {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0},
  93. {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0},
  94. {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0},
  95. {0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0},
  96. {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
  97. {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
  98. {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
  99. {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
  100. {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0},
  101. {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  102. {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  103. {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  104. {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
  105. };
  106. uint8_t rain_yx[16][16] = {
  107. {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
  108. {0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0},
  109. {0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0},
  110. {0,0,0,0,1,1,1,0,0,0,0,0,1,0,0,0},
  111. {0,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0},
  112. {0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0},
  113. {0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0},
  114. {0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
  115. {0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
  116. {0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
  117. {0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
  118. {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
  119. {0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,0},
  120. {0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,0},
  121. {0,0,0,0,0,1,0,1,0,1,0,0,0,0,0,0},
  122. {0,0,0,1,0,1,0,0,0,1,0,0,0,1,0,0}
  123. };
  124. uint8_t cloudSun_yx[16][16] = {
  125. {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
  126. {0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0},
  127. {0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0},
  128. {0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0},
  129. {0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0},
  130. {0,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0},
  131. {0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0},
  132. {0,1,0,0,1,1,1,0,0,0,0,0,1,0,0,0},
  133. {0,1,0,1,0,0,0,1,0,0,0,0,1,0,0,0},
  134. {0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0},
  135. {0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0},
  136. {0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
  137. {0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
  138. {0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
  139. {0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
  140. {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
  141. };
  142. void DrawFrame(uint8_t arr[][16], String identifier)
  143. {
  144. FastLED.clear();
  145. FastLED.show();
  146. for (int i = 0; i < 16; i++) {
  147. for (int j = 0; j < 16; j++) {
  148. uint8_t elem = arr[i][j];
  149. if (elem == 1) {
  150. if (identifier == "Rain") {
  151. if (i >= 12) {
  152. leds[ XYsafe(i, j)] = CRGB::Blue;
  153. } else {
  154. leds[ XYsafe(i, j)] = CRGB::WhiteSmoke;
  155. }
  156. } else if (identifier == "Clouds") {
  157. leds[ XYsafe(i, j)] = CRGB::WhiteSmoke;
  158. } else if (identifier == "Sun") {
  159. leds[ XYsafe(i, j)] = CRGB::Yellow;
  160. } else if (identifier == "CloudSun") {
  161. if ((((i >= 0) && (i <= 8))
  162. && ((j >= 0) && (j <= 2)))
  163. ||
  164. (((i >= 0) && (i <= 4))
  165. && ((j >= 0) && (j <= 15)))) {
  166. leds[ XYsafe(i, j)] = CRGB::Yellow;
  167. Serial.println("Yellow!");
  168. } else {
  169. leds[ XYsafe(i, j)] = CRGB::WhiteSmoke;
  170. Serial.println("White!");
  171. }
  172. }
  173. }
  174. }
  175. }
  176. FastLED.show();
  177. }
  178. void loop()
  179. {
  180. millisTime = millis();
  181. if (firstIteration || millisTime % 60000 == 0) {
  182. int respCode = http.GET();
  183. JsonDocument payload;
  184. if(respCode > 0){
  185. const String response = http.getString();
  186. deserializeJson(payload, response);
  187. if (String("Clouds") == String(payload["weather"][0]["main"])) {
  188. if (payload["weather"][0]["id"] >= 803) {
  189. DrawFrame(cloud_yx, "Clouds");
  190. } else {
  191. DrawFrame(cloudSun_yx, "CloudSun");
  192. }
  193. } else if (String("Rain") == String(payload["weather"][0]["main"]) || String("Drizzle") == String(payload["weather"][0]["main"])) {
  194. DrawFrame(rain_yx, "Rain");
  195. } else if (String("Clear") == String(payload["weather"][0]["main"])) {
  196. DrawFrame(sun_yx, "Sun");
  197. } else {
  198. DrawFrame(cloudSun_yx, "CloudSun");
  199. }
  200. } else {
  201. Serial.print("error ");
  202. Serial.println(respCode);
  203. }
  204. firstIteration = false;
  205. }
  206. }
  207. void setup() {
  208. Serial.begin(115200);
  209. // weather api
  210. const float lat = 48.9517;
  211. const float lon = 10.1703;
  212. const String apiKey = "e471293b25fdb6697c0a862f2695df5f";
  213. apiUrl = buildAPIUrl(lat, lon, apiKey);
  214. connectWiFi();
  215. if (WiFi.status() != WL_CONNECTED) {
  216. Serial.println(WiFi.status());
  217. }
  218. http.begin(client, apiUrl);
  219. FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalSMD5050);
  220. FastLED.setBrightness( BRIGHTNESS );
  221. }