前言
- 先理清单片机接收并执行RPC指令的流程
- 现在的构思是计算量比较大的环节用服务器处理,单片机只负责采集数据和执行服务器下发的RPC指令
- 暂时只控制灯光颜色,实施时是要控制电脑能否开机,当然那是很简单的io控制了
进度
- 人坐下或离开发送一次数据给服务器,没人灯灭,有人下一步
- 判断是否周末,非周末亮红灯,周末下一步
- 判断是否9:30 – 21:30,时段符合亮绿灯,不符亮蓝灯
待解决
- 统计使用时长,判断休息时长,清洗误报(便宜嘛,难免的)
- 清洗误报比较简单,但thingsboard统计时间的功能没找到相关的文档,路长有点长……
设备代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
#include <ESP8266WiFi.h> #include <PubSubClient.h> #include <ArduinoJson.h> <em>// 设置wifi信息</em> const char* ssid = "*****"; const char* password = "*******"; const char* mqttServer = "www.weishadian.com"; <em>// 建立wifi和mqtt对象</em> WiFiClient wifiClient; PubSubClient mqttClient(wifiClient); const char* client_ID = "any20211128145527"; <em>// id可以任意</em> const char* mqttUserName = "QidRRk3****UtfvQMW"; <em>// 设备令牌,token</em> const char* mqttPassword = ""; <em>// 密码为空</em> char dataTemplate[] = "{\"distance\": %.2f}"; <em>// 简单信息模板</em> char attrData[] = "{\"deviceName\": \"boyPC\"}"; <em>// 简单信息模板</em> char postData[50]; <em>// 报文</em> <em>// 主题</em> char topic[] = "v1/devices/me/telemetry"; <em>// 发布遥测数据的主题</em> char rpcTopic[] = "v1/devices/me/rpc/request/+"; <em>// rpc主题</em> <em>// 超声波引脚</em> #define trigPin D1 #define echoPin D2 <em>// rgb灯引脚</em> #define r D5 #define g D6 #define b D7 <em>// 声明时间和距离的变量</em> float duration; float distance; float lastDistance = 0; long lastMsg = 0; <em>// 记录最后发送的时间</em> DynamicJsonDocument doc(200); <em>// 存储服务器rpc报文</em> void setup(){ pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); pinMode(r, OUTPUT); pinMode(g, OUTPUT); pinMode(b, OUTPUT); Serial.begin(9600); wifiAndMqtt(); } void loop(){ <em>// 检查MQTT连接状态</em> if (!mqttClient.connected()) { WiFi.disconnect(); <em>// 断开wifi</em> Serial.println("掉线啦!5秒后尝试重新连接..."); delay(5000); wifiAndMqtt(); Serial.println("重新连接成功!"); } <em>// 处理信息以及心跳</em> mqttClient.loop(); ranging(); <em>// 测距</em> if ((lastDistance > 50 && distance < 50) || (lastDistance < 50 && distance > 50)){ lastDistance = distance; snprintf(postData, 50, dataTemplate, distance); <em>// 格式化报文</em> Serial.print("上报数据!"); Serial.println(distance); mqttClient.publish(topic, (uint8_t *)postData, strlen(postData)); <em>// 发送报文</em> } Serial.println(distance); delay(1000); } <em>// 超声波测距函数</em> void ranging(){ <em>// 这里不需要返回值,因为使用的都是全局变量</em> <em>// 清除trig的任务,防止trig处于高电平状态</em> digitalWrite(trigPin, LOW); delayMicroseconds(2); <em>// 拉高trig发射一个持续10微秒的超声波</em> digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); <em>// 读取echo的检测HIGH脉冲信号,返回持续时间,单位是微秒</em> duration = pulseIn(echoPin, HIGH); <em>// 计算距离,设置声速为0.034262 cm/s</em> distance= duration*0.034262/2.0; } <em>// 收到信息后的回调函数</em> void receiveCallback(char* topic, byte* payload, unsigned int length) { Serial.print("报文 ["); Serial.print(topic); Serial.print("] "); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(""); Serial.print("报文长度(Bytes) "); Serial.println(length); <em>// 反序列化报文</em> deserializeJson(doc, payload); int r_val = doc["params"]["D5"].as<int>(); int g_val = doc["params"]["D6"].as<int>(); int b_val = doc["params"]["D7"].as<int>(); analogWrite(r, r_val); analogWrite(g, g_val); analogWrite(b, b_val); } <em>// wifi和mqtt连接</em> void wifiAndMqtt(){ <em>//设置为无线终端模式</em> WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); <em>// 连接WiFi</em> <em>//等待WiFi连接,成功连接后输出成功信息</em> while (WiFi.status() != WL_CONNECTED) { delay(1000); } <em>// 设置MQTT服务器和端口号</em> mqttClient.setServer(mqttServer, 1883); <em>// 明文模式</em> mqttClient.setCallback(receiveCallback); <em>// 收到报文的回调函数</em> mqttClient.connect(client_ID, mqttUserName, mqttPassword); <em>// 连接mqtt服务器</em> while (!mqttClient.connected()){ delay(1000); } mqttClient.subscribe(rpcTopic, 0); <em>// 订阅主题</em> } |
TB规则链
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
{ "ruleChain": { "additionalInfo": { "description": "" }, "name": "电脑限时", "type": "CORE", "firstRuleNodeId": null, "root": false, "debugMode": true, "configuration": null }, "metadata": { "firstNodeIndex": 7, "nodes": [ { "additionalInfo": { "description": "", "layoutX": 884, "layoutY": 377 }, "type": "org.thingsboard.rule.engine.transform.TbTransformMsgNode", "name": "非周末", "debugMode": true, "configuration": { "jsScript": "msg = {\n \"method\": \"setGpio\",\n \"params\": {\n \"D5\": 1024,\n \"D6\": 0,\n \"D7\": 0\n }\n}\n\nreturn {msg: msg, metadata: metadata, msgType: msgType};" } }, { "additionalInfo": { "description": "", "layoutX": 886, "layoutY": 268 }, "type": "org.thingsboard.rule.engine.transform.TbTransformMsgNode", "name": "时段不符", "debugMode": true, "configuration": { "jsScript": "msg = {\n \"method\": \"setGpio\",\n \"params\": {\n \"D5\": 0,\n \"D6\": 0,\n \"D7\": 1024\n }\n}\n\nreturn {msg: msg, metadata: metadata, msgType: msgType};" } }, { "additionalInfo": { "description": "", "layoutX": 888, "layoutY": 141 }, "type": "org.thingsboard.rule.engine.transform.TbTransformMsgNode", "name": "可以使用", "debugMode": true, "configuration": { "jsScript": "msg = {\n \"method\": \"setGpio\",\n \"params\": {\n \"D5\": 0,\n \"D6\": 1024,\n \"D7\": 0\n }\n}\n\nreturn {msg: msg, metadata: metadata, msgType: msgType};" } }, { "additionalInfo": { "description": "", "layoutX": 890, "layoutY": 481 }, "type": "org.thingsboard.rule.engine.transform.TbTransformMsgNode", "name": "转换数据", "debugMode": true, "configuration": { "jsScript": "msg = {\n \"method\": \"setGpio\",\n \"params\": {\n \"D5\": 0,\n \"D6\": 0,\n \"D7\": 0\n }\n}\n\nreturn {msg: msg, metadata: metadata, msgType: msgType};" } }, { "additionalInfo": { "description": "", "layoutX": 1198, "layoutY": 255 }, "type": "org.thingsboard.rule.engine.rpc.TbSendRPCRequestNode", "name": "发送指令给8266", "debugMode": true, "configuration": { "timeoutInSeconds": 60 } }, { "additionalInfo": { "description": "", "layoutX": 604, "layoutY": 254 }, "type": "org.thingsboard.rule.engine.filter.TbJsFilterNode", "name": "判断时间段", "debugMode": true, "configuration": { "jsScript": "var myDate = new Date();\nvar h = myDate.getHours();\nvar m = myDate.getMinutes();\nvar result = true;\nif (h > 8 && h < 22){\n if (h == 9 && m < 30){\n result = false;\n }else if (h == 21 && m > 30){\n result = false;\n }else{\n result = true;\n }\n}else{\n result = false;\n}\n\nreturn result;" } }, { "additionalInfo": { "description": "", "layoutX": 332, "layoutY": 252 }, "type": "org.thingsboard.rule.engine.filter.TbJsFilterNode", "name": "判断是否周末", "debugMode": true, "configuration": { "jsScript": "var now = new Date();\nvar day = now.getDay();\nvar weeks = new Array(7, 1, 2, 3, 4, 5, 6);\nvar week = weeks[day];\nreturn week > 5;" } }, { "additionalInfo": { "description": "", "layoutX": 46, "layoutY": 253 }, "type": "org.thingsboard.rule.engine.filter.TbJsFilterNode", "name": "检测是否有人", "debugMode": true, "configuration": { "jsScript": "return msg.distance < 50;" } } ], "connections": [ { "fromIndex": 0, "toIndex": 4, "type": "Success" }, { "fromIndex": 1, "toIndex": 4, "type": "Success" }, { "fromIndex": 2, "toIndex": 4, "type": "Success" }, { "fromIndex": 3, "toIndex": 4, "type": "Success" }, { "fromIndex": 5, "toIndex": 2, "type": "True" }, { "fromIndex": 5, "toIndex": 1, "type": "False" }, { "fromIndex": 6, "toIndex": 5, "type": "True" }, { "fromIndex": 6, "toIndex": 0, "type": "False" }, { "fromIndex": 7, "toIndex": 6, "type": "True" }, { "fromIndex": 7, "toIndex": 3, "type": "False" } ], "ruleChainConnections": null } } |
近期评论