直接上代码

💡 Tips:需要修改点灯设备key和钉钉通知的token

  1. #include <ESP8266WiFi.h>
  2. #include <DNSServer.h>
  3. #include <ESP8266WebServer.h>
  4. #include <WiFiManager.h>
  5. #include <ESP8266HTTPClient.h>
  6. #include <ArduinoJson.h>
  7. #include <EEPROM.h>
  8. #define BLINKER_WIFI //定义wifi模块
  9. #define BLINKER_MIOT_SENSOR //小爱同学定义为传感器设备
  10. #define BLINKER_WITHOUT_SSL //非SSL加密通信接入,省堆栈
  11. #include <Blinker.h>//包含Blinker头文件
  12. #include <DHT.h>//包含DHT头文件
  13. #include <TM1637Display.h> //数显库
  14. #define CLK 4 //数显的CLK D2
  15. #define DIO 0 //数显的DIN D3
  16. TM1637Display display(CLK,DIO);
  17. uint8_t data[] = { 0xff, 0xff, 0xff, 0xff };
  18. uint8_t blank[] = { 0x00, 0x00, 0x00, 0x00 };
  19. int temp_int = 0;
  20. int humi_int = 0;
  21. int AlarmRate = 50;
  22. int AlarmInt = 1;
  23. union int_value{
  24. int i; //int类型成员变量
  25. byte b[2]; //byte类型数组成员
  26. };
  27. //温度阈值
  28. int_value temp_threshold;
  29. //湿度阈值
  30. int_value humi_threshold;
  31. BlinkerSlider SliderTemp("ran-temp");
  32. BlinkerSlider SliderHumi("ran-humi");
  33. #define DHTPIN 2 //定义DHT11模块连接管脚io2 (D4)
  34. #define DHTTYPE DHT11 // 使用温度湿度模块的类型为DHT11
  35. //#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
  36. //#define DHTTYPE DHT21 // DHT 21 (AM2301)
  37. //char auth[] = "********"; //点灯app中获取到的Secret Key(新建设备的秘钥)
  38. String DingDingURL = "https://oapi.dingtalk.com/robot/send?access_token=*****";
  39. boolean DingDingSwitch = true;
  40. //新建数据类型组件对象,作用:将数据传输到手机blinker app
  41. BlinkerNumber HUMI("humi"); //定义湿度数据键名
  42. BlinkerNumber TEMP("temp"); //定义温度数据键名
  43. DHT dht(DHTPIN, DHTTYPE); //定义dht
  44. float humi_read = 0, temp_read = 0; //定义浮点型全局变量 储存传感器读取的温湿度数据
  45. //小米小爱状态回调函数
  46. void miotQuery(int32_t queryCode)
  47. {
  48. BLINKER_LOG("MIOT Query codes: ", queryCode);
  49. int hVal = humi_read; //多次测试湿度须为整数型
  50. switch (queryCode)
  51. {
  52. case BLINKER_CMD_QUERY_ALL_NUMBER :
  53. BLINKER_LOG("MIOT Query All");
  54. BlinkerMIOT.temp(temp_read);
  55. BlinkerMIOT.humi(hVal);
  56. BlinkerMIOT.print();
  57. break;
  58. case BLINKER_CMD_QUERY_HUMI_NUMBER :
  59. BLINKER_LOG("MIOT Query HUMI");
  60. BlinkerMIOT.humi(hVal);
  61. BlinkerMIOT.print();
  62. break;
  63. case BLINKER_CMD_QUERY_TEMP_NUMBER :
  64. BLINKER_LOG("MIOT Query TEMP");
  65. BlinkerMIOT.temp(temp_read);
  66. BlinkerMIOT.print();
  67. break;
  68. default :
  69. BlinkerMIOT.temp(20);
  70. BlinkerMIOT.humi(20);
  71. BlinkerMIOT.pm25(20);
  72. BlinkerMIOT.co2(20);
  73. BlinkerMIOT.print();
  74. break;
  75. }
  76. }
  77. void heartbeat()
  78. {
  79. //反馈温度数据
  80. HUMI.print(humi_read);
  81. //设置ui组件图标和颜色
  82. HUMI.icon("fas fa-thermometer-2");
  83. HUMI.color("#fddb10");
  84. //反馈湿度数据
  85. TEMP.print(temp_read);
  86. TEMP.icon("fas fa-heart");
  87. HUMI.color("#fddb01");
  88. SliderTemp.print(temp_threshold.i);
  89. SliderHumi.print(humi_threshold.i);
  90. }
  91. void dataStorage()
  92. {
  93. Blinker.dataStorage("temp", temp_read);
  94. Blinker.dataStorage("humi", humi_read);
  95. }
  96. void setup()
  97. {
  98. //初始化串口
  99. Serial.begin(115200);
  100. WiFiManager wifiManager;
  101. wifiManager.autoConnect("AutoConnectAP");
  102. // 如果您希望该WiFi添加密码,可以使用以下语句:
  103. // wifiManager.autoConnect("AutoConnectAP", "12345678");
  104. // 以上语句中的12345678是连接AutoConnectAP的密码
  105. // WiFi连接成功后将通过串口监视器输出连接成功信息
  106. Serial.println("");
  107. Serial.print("ESP8266 Connected to ");
  108. Serial.println(WiFi.SSID()); // WiFi名称
  109. Serial.print("IP address:\t");
  110. Serial.println(WiFi.localIP()); // IP
  111. Blinker.begin(auth, WiFi.SSID().c_str(), WiFi.psk().c_str());
  112. BLINKER_DEBUG.stream(Serial);
  113. BLINKER_DEBUG.debugAll();
  114. //LED灯闪动
  115. pinMode(LED_BUILTIN, OUTPUT);
  116. digitalWrite(LED_BUILTIN, LOW);
  117. dht.begin();//初始化DHT传感器
  118. //Blinker.begin(auth, ssid, pswd); // // 初始化blinker
  119. Blinker.attachHeartbeat(heartbeat);//将传感器获取的数据传给blinker app上
  120. Blinker.attachDataStorage(dataStorage);//调用云函数
  121. //在回调函数中反馈该控制状态
  122. BlinkerMIOT.attachQuery(miotQuery);//每次呼出小爱同学,就会调用miotQuery()函数
  123. //注册滑块回调
  124. SliderTemp.attach(slidertemp_callback);
  125. SliderHumi.attach(sliderhumi_callback);
  126. display.setBrightness(0x0f);
  127. // All segments on
  128. display.setSegments(data);
  129. delay(2000);
  130. EEPROM.begin(1024); //开启EEPROM,开辟1024个位空间
  131. byte a1=EEPROM.read(0); //a1获取EEPROM 0 位的值
  132. byte a2=EEPROM.read(1); //a2获取EEPROM 1 位的值
  133. int_value tt;
  134. tt.b[0] = a1;
  135. tt.b[1] = a2;
  136. if(tt.i < 1 || tt.i>50){
  137. temp_threshold.i = 27;
  138. }else{
  139. temp_threshold.i = tt.i;
  140. }
  141. byte b1=EEPROM.read(2); //a1获取EEPROM 0 位的值
  142. byte b2=EEPROM.read(3); //a2获取EEPROM 1 位的值
  143. int_value hh;
  144. hh.b[0] = b1;
  145. hh.b[1] = b2;
  146. if(hh.i>100 || hh.i<1 ){
  147. humi_threshold.i = 70;
  148. }else{
  149. humi_threshold.i = hh.i;
  150. }
  151. Serial.println("End read");
  152. }
  153. void slidertemp_callback(int32_t value)
  154. {
  155. Blinker.vibrate();///震动
  156. BLINKER_LOG("Get temp slider value: ", value);
  157. int_value tt;
  158. tt.i = value;
  159. EEPROM.begin(1024);
  160. EEPROM.write(0,tt.b[0]); //给EEPROM 第0位写入temp_threshold.b[0]的值
  161. EEPROM.write(1,tt.b[1]); //给EEPROM 第1位写入temp_threshold.b[1]的值
  162. EEPROM.commit();
  163. temp_threshold.i = tt.i;
  164. }
  165. void sliderhumi_callback(int32_t value)
  166. {
  167. Blinker.vibrate();///震动
  168. BLINKER_LOG("Get humi slider value: ", value);
  169. int_value hh;
  170. hh.i = value;
  171. EEPROM.begin(1024);
  172. EEPROM.write(2,hh.b[0]); //给EEPROM 第0位写入temp_threshold.b[0]的值
  173. EEPROM.write(3,hh.b[1]); //给EEPROM 第1位写入temp_threshold.b[1]的值
  174. EEPROM.commit();
  175. humi_threshold.i = hh.i;
  176. }
  177. //通过循环不断读取温湿度传感器获取的数据
  178. void loop()
  179. {
  180. Blinker.run();
  181. float h = dht.readHumidity(true);//读取DHT11传感器的湿度 并赋值给h
  182. float t = dht.readTemperature(true);//读取传感器的温度 并赋值给t
  183. if (isnan(h) || isnan(t))//判断是否成功读取到温湿度数据
  184. {
  185. BLINKER_LOG("Failed to read from DHT sensor!");//读取温湿度失败!
  186. }
  187. else
  188. {
  189. t = dht.convertFtoC(t);//将华氏度转换为摄氏度
  190. BLINKER_LOG("Humidity: ", h, " %");
  191. BLINKER_LOG("Temperature: ", t, " *C");
  192. AlarmInt += 1;
  193. if(AlarmInt>AlarmRate){
  194. AlarmInt = 1;
  195. }
  196. if(AlarmInt == 5){
  197. if(DingDingSwitch){
  198. if( t>temp_threshold.i || h>humi_threshold.i){
  199. BLINKER_LOG("发送钉钉告警通知");
  200. httpClientRequest(h,t);
  201. }
  202. }
  203. }
  204. humi_read = h;//将读取到的湿度赋值给全局变量humi_read
  205. temp_read = t;//将读取到的温度赋值给全局变量temp_read
  206. }
  207. //TM1637_SHOW(temp_read,humi_read);
  208. Blinker.delay(1000);//1秒延时(超过2s 小爱同学可能取不到数据)
  209. }
  210. void httpClientRequest(float h,float t){
  211. WiFiClientSecure client;
  212. client.setInsecure();
  213. client.connect("oapi.dingtalk.com",443);
  214. String jsonRaw = rootJson(h,t);
  215. client.print(String("POST ") + DingDingURL + " HTTP/1.1\r\n" +
  216. "Host: " + "oapi.dingtalk.com" + "\r\n" +
  217. "Content-Type: application/json\r\n" +
  218. "Content-Length: " +
  219. String(jsonRaw.length()) + "\r\n\r\n");
  220. client.print(jsonRaw);
  221. delay(6000);
  222. //操作结束,断开服务器连接
  223. client.stop();
  224. Serial.println("closing connection");
  225. }
  226. String rootJson(float h,float t){
  227. //const size_t capacity = JSON_OBJECT_SIZE(1) + 3*JSON_OBJECT_SIZE(3)+140;
  228. const size_t capacity = 1*JSON_OBJECT_SIZE(1)+140;
  229. DynamicJsonDocument doc(capacity);
  230. doc["msgtype"] = "text";
  231. JsonObject info = doc.createNestedObject("text");
  232. String content = "【温湿度】,温度:";
  233. content.concat(t);
  234. content.concat(" 湿度:");
  235. content.concat(h);
  236. info["content"] = content;
  237. String jsonCode;
  238. serializeJson(doc,jsonCode);
  239. return jsonCode;
  240. }
  241. void TM1637_SHOW(float t,float h){
  242. if(temp_int == int(t*10)){
  243. BLINKER_LOG("数据未变");
  244. return;
  245. }else{
  246. display.clear();
  247. temp_int = int(t*10);
  248. int bai = temp_int/100;
  249. int shi = (temp_int-100*bai)/10;
  250. int ge = temp_int%10;
  251. BLINKER_LOG("temp_int:", temp_int, " ");
  252. BLINKER_LOG("数据变:", bai, " 百");
  253. data[0] = display.encodeDigit(bai);
  254. data[1] = display.encodeDigit(shi);
  255. data[2] = display.encodeDigit(ge);
  256. data[3] = display.encodeDigit(12);
  257. display.setSegments(data);
  258. }
  259. //humi_int = int(h);
  260. //display.showNumberDec(t, true, 3, 2); // Expect: 04__
  261. //display.showNumberHexEx(0x2c); // Expect: __2C
  262. }

点灯界面配置

  1. config¨{¨headerColor¨¨transparent¨¨headerStyle¨¨dark¨¨background¨{¨img¨¨assets/img/headerbg.jpg¨¨isFull¨«}}¨dashboard¨|{¨type¨¨num¨¨t0¨¨湿度¨¨ico¨¨fad fa-humidity¨¨clr¨¨#076EEF¨¨min¨É¨max¨¢1c¨uni¨´%´¨bg¨É¨cols¨Í¨rows¨Ë¨key¨¨humi¨´x´É´y´É¨speech¨|÷¨lstyle¨Ë}{ßAßBßC¨温度¨ßE¨fas fa-thermometer-three-quarters¨ßGßHßIÉßJº0ßK´℃´ßLÉßMÍßNËßO¨temp¨´x´Í´y´ÉßQ|÷ßRÊ}{ßA¨cha¨ßLɨsty¨¨line¨ßGßH¨sty1¨ßX¨clr1¨¨#EA0909¨¨sty2¨ßX¨clr2¨¨#389BEE¨ßMÑßNÌßOßD´x´É´y´ËßQ|÷ßRɨkey0¨ßPßC¨湿度%¨¨key1¨´´¨t1¨´´}{ßAßVßLÉßWßXßG¨#00A90C¨ßYßXßZßdßbßXßcßdßMÑßNÌßOßS´x´É´y´ÎßQ|÷ßeßUßC¨温度℃¨ßRÉ}{ßA¨deb¨¨mode¨ÉßLÉßMÑßNÌßO¨debug¨´x´É´y´¤C}{ßA¨ran¨ßC¨湿度阈值¨ßGßdßJº0ßIÉßLÉßMÑßNËßO¨ran-humi¨´x´É´y´ÑßQ|÷}{ßAßnßC¨温度阈值¨ßGßdßJ¤oßIÉßLÉßMÑßNËßO¨ran-temp¨´x´É´y´¤AßQ|÷}÷¨actions¨|÷¨triggers¨|÷}