2023年8月17日 星期四

ESP32 NFC PN532 + Node-red +SQLite Database

 ESP32 NFC PN532 + Node-red +SQLite Database

// MQTT Broker
const char *mqtt_broker = "broker.mqtt-dashboard.com";
const char *topic2 = "alex9ufo/esp32/RFID";
const char *topic = "alex9ufo/esp32/Starting";



[{"id":"f23cc1f751d5b24b","type":"ui_button","z":"a3634e48ac6f0f7a","name":"","group":"9eb91d4467c6eec5","order":22,"width":3,"height":1,"passthru":false,"label":"建立資料庫","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"建立資料庫","payloadType":"str","topic":"topic","topicType":"msg","x":150,"y":280,"wires":[["d03d687a7710b075","903b4023a525c76d"]]},{"id":"930633c1f6ba9656","type":"ui_button","z":"a3634e48ac6f0f7a","name":"","group":"9eb91d4467c6eec5","order":24,"width":8,"height":2,"passthru":false,"label":"檢視資料庫資料","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"檢視資料","payloadType":"str","topic":"topic","topicType":"msg","x":160,"y":700,"wires":[["f515571476a927bb","ad03f7000e15a6bf","06e06c6465863700"]]},{"id":"19ae616adc92ffb1","type":"ui_button","z":"a3634e48ac6f0f7a","name":"","group":"9eb91d4467c6eec5","order":21,"width":3,"height":1,"passthru":false,"label":"刪除所有資料","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"刪除所有資料","payloadType":"str","topic":"topic","topicType":"msg","x":160,"y":1000,"wires":[["40915de1f76f8c80","41d056989233b92f"]]},{"id":"c1e51da0165079d3","type":"sqlite","z":"a3634e48ac6f0f7a","mydb":"8d99f15e50a51fcd","sqlquery":"msg.topic","sql":"","name":"My_RFID_database","x":700,"y":360,"wires":[["40ee306f782e4e04","d812694deae81cda"]]},{"id":"d03d687a7710b075","type":"function","z":"a3634e48ac6f0f7a","name":"CREATE DATABASE","func":"\n\n//CREATE TABLE \"RFIDtable\" (\n//\t\"id\"\tINT NOT NULL,\n//  \"uidname\"  TEXT,\n//  \"currentdate\" DATE, \n//  \"currenttime\" TIME\n//\tPRIMARY KEY(\"id\")\n//);\nmsg.topic = \"CREATE TABLE RFIDtable(id INTEGER PRIMARY KEY AUTOINCREMENT, uidname TEXT, currentdate DATE, currenttime TIME)\";\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":340,"y":280,"wires":[["b99db4867081faa8"]]},{"id":"40ee306f782e4e04","type":"debug","z":"a3634e48ac6f0f7a","name":"debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":950,"y":360,"wires":[]},{"id":"0f50b06aa25d9a27","type":"function","z":"a3634e48ac6f0f7a","name":"INSERT","func":"var Today = new Date();\nvar yyyy = Today.getFullYear(); //年\nvar MM = Today.getMonth()+1;    //月\nvar dd = Today.getDate();       //日\nvar h = Today.getHours();       //時\nvar m = Today.getMinutes();     //分\nvar s = Today.getSeconds();     //秒\nif(MM<10)\n{\n   MM = '0'+MM;\n}\n\nif(dd<10)\n{\n   dd = '0'+dd;\n}\n\nif(h<10)\n{\n   h = '0'+h;\n}\n\nif(m<10)\n{\n  m = '0' + m;\n}\n\nif(s<10)\n{\n  s = '0' + s;\n}\nvar var_date = yyyy+'/'+MM+'/'+dd;\nvar var_time = h+':'+m+':'+s;\n\nvar myRFID = flow.get('uid_temp');\n\n\nmsg.topic = \"INSERT INTO RFIDtable ( uidname , currentdate, currenttime ) VALUES ($myRFID,  $var_date ,  $var_time ) \" ;\nmsg.payload = [myRFID, var_date , var_time ]\nreturn msg;\n\n//CREATE TABLE \"RFIDtable\" (\n//\t\"id\"\tINT NOT NULL,\n//  \"uidname\"  TEXT,\n//  \"currentdate\" DATE, \n//  \"currenttime\" TIME\n//\tPRIMARY KEY(\"id\")\n//);","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":520,"y":360,"wires":[["c1e51da0165079d3","fcc7495cf512588b"]]},{"id":"33ee680d5192fe7b","type":"function","z":"a3634e48ac6f0f7a","name":"刪除所有資料","func":"//DELETE from RFIDtable\nmsg.topic = \"DELETE from RFIDtable\";\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":620,"y":1000,"wires":[["5f84a16f53948caa"]]},{"id":"5f84a16f53948caa","type":"sqlite","z":"a3634e48ac6f0f7a","mydb":"8d99f15e50a51fcd","sqlquery":"msg.topic","sql":"","name":"My_RFID_database","x":820,"y":1000,"wires":[["0c10d73879f8ae3e","e172e3e022ecdc21"]]},{"id":"de2233c2e4e63820","type":"ui_button","z":"a3634e48ac6f0f7a","name":"","group":"9eb91d4467c6eec5","order":20,"width":3,"height":1,"passthru":false,"label":"刪除資料庫","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"刪除資料庫","payloadType":"str","topic":"topic","topicType":"msg","x":150,"y":1080,"wires":[["b0660fed11dbf785","2bbcae8c9ac0d30b"]]},{"id":"72e2ce34c68eb47d","type":"function","z":"a3634e48ac6f0f7a","name":"刪除資料庫","func":"//DROP TABLE RFIDtable\nmsg.topic = \"DROP TABLE RFIDtable\";\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":610,"y":1080,"wires":[["48b3d445f4605445"]]},{"id":"0c10d73879f8ae3e","type":"debug","z":"a3634e48ac6f0f7a","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":930,"y":1040,"wires":[]},{"id":"d66727debd1881dc","type":"function","z":"a3634e48ac6f0f7a","name":"檢視資料","func":"\n//CREATE TABLE \"RFIDtable\" (\n//\t\"id\"\tINT NOT NULL,\n//  \"uidname\"  TEXT,\n//  \"currentdate\" DATE, \n//  \"currenttime\" TIME\n//\tPRIMARY KEY(\"id\")\n//);\n\n//SELECT * FROM RFIDtable ORDER BY  id DESC LIMIT 50;\n\nmsg.topic = \"SELECT * FROM RFIDtable ORDER BY id DESC LIMIT 50\";\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":760,"y":780,"wires":[["ec626877c4250a75"]]},{"id":"ec626877c4250a75","type":"sqlite","z":"a3634e48ac6f0f7a","mydb":"8d99f15e50a51fcd","sqlquery":"msg.topic","sql":"","name":"My_RFID_database","x":940,"y":780,"wires":[["1428053660920b21"]]},{"id":"6ba518657cd07da3","type":"function","z":"a3634e48ac6f0f7a","name":"SELECT ALL","func":"var del_idtemp=msg.payload;\nflow.set(\"idtemp\", del_idtemp);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":920,"wires":[["5f4174115c020926"]]},{"id":"ca87a44eb0af2529","type":"function","z":"a3634e48ac6f0f7a","name":"確認 刪除","func":"var del_id = flow.get(\"idtemp\");\n\n\nmsg.topic = \"DELETE FROM RFIDtable WHERE id= ($del_id) \" ;\nmsg.payload = [del_id]\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":580,"y":860,"wires":[["1fed9722a4e87675"]]},{"id":"ae71379738a3ae8c","type":"ui_numeric","z":"a3634e48ac6f0f7a","name":"","label":"刪除的database_id","tooltip":"","group":"9eb91d4467c6eec5","order":19,"width":5,"height":1,"wrap":true,"passthru":true,"topic":"topic","topicType":"msg","format":"{{value}}","min":"1","max":"1000","step":1,"className":"","x":170,"y":920,"wires":[["6ba518657cd07da3","cfeb1f9317935bac"]]},{"id":"1fed9722a4e87675","type":"sqlite","z":"a3634e48ac6f0f7a","mydb":"8d99f15e50a51fcd","sqlquery":"msg.topic","sql":"DELETE FROM dhtreadings WHERE id =  VALUES ($theid)","name":"My_RFID_database","x":760,"y":860,"wires":[["d66727debd1881dc"]]},{"id":"406cf6b001e04f51","type":"ui_button","z":"a3634e48ac6f0f7a","name":"","group":"9eb91d4467c6eec5","order":18,"width":3,"height":1,"passthru":false,"label":"刪除一筆資料","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"刪除一筆資料","payloadType":"str","topic":"topic","topicType":"msg","x":160,"y":800,"wires":[["f515571476a927bb","270330b108b568f3"]]},{"id":"5f4174115c020926","type":"debug","z":"a3634e48ac6f0f7a","name":"debug 183","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":550,"y":920,"wires":[]},{"id":"4487f643ba9f0fd2","type":"mqtt in","z":"a3634e48ac6f0f7a","name":"新增 RFID","topic":"alex9ufo/esp32/RFID","qos":"2","datatype":"auto-detect","broker":"841df58d.ee5e98","nl":false,"rap":true,"rh":0,"inputs":0,"x":140,"y":360,"wires":[["4c6b8885d3c3cddf","45f093b1a3e4e478"]]},{"id":"fb32a8daf0436db9","type":"ui_text_input","z":"a3634e48ac6f0f7a","name":"","label":"新增一筆資料","tooltip":"","group":"9eb91d4467c6eec5","order":23,"width":3,"height":1,"passthru":true,"mode":"text","delay":300,"topic":"topic","sendOnBlur":true,"className":"","topicType":"msg","x":400,"y":480,"wires":[[]]},{"id":"e60a3be2dfebb199","type":"ui_audio","z":"a3634e48ac6f0f7a","name":"","group":"9eb91d4467c6eec5","voice":"Microsoft Hanhan - Chinese (Traditional, Taiwan)","always":true,"x":600,"y":520,"wires":[]},{"id":"fb14c26907304db6","type":"function","z":"a3634e48ac6f0f7a","name":"function ","func":"var temp= msg.payload;\nmsg.payload= \"新增一筆資料\" + temp;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":440,"wires":[["e60a3be2dfebb199","7f9618ee7be291e6","15380f8c2e4236f7"]]},{"id":"f515571476a927bb","type":"ui_audio","z":"a3634e48ac6f0f7a","name":"","group":"9eb91d4467c6eec5","voice":"Microsoft Hanhan - Chinese (Traditional, Taiwan)","always":true,"x":380,"y":780,"wires":[]},{"id":"903b4023a525c76d","type":"ui_audio","z":"a3634e48ac6f0f7a","name":"","group":"9eb91d4467c6eec5","voice":"Microsoft Hanhan - Chinese (Traditional, Taiwan)","always":true,"x":300,"y":240,"wires":[]},{"id":"329518b547d45fa6","type":"function","z":"a3634e48ac6f0f7a","name":"function 76","func":"//SELECT trackid,name FROM \ttracks WHERE name LIKE 'Wild%'\n//Query\n//CREATE TABLE \"RFIDtable\" (\n//\t\"id\"\tINT NOT NULL,\n//  \"uidname\"  TEXT,\n//  \"currentdate\" DATE, \n//  \"currenttime\" TIME\n//\tPRIMARY KEY(\"id\")\n//);\n//msg.topic = \"DELETE FROM RFIDtable WHERE id= ($del_id) \" ;\n\nvar query_uid = flow.get(\"uidtemp\");\nmsg.topic = \"SELECT id,uidname , currentdate,currenttime FROM RFIDtable WHERE uidname LIKE ($query_uid) \";\nmsg.payload = [query_uid]\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":390,"y":1160,"wires":[["54f57f87a644c5b1","5cbfad4c974ebfbb"]]},{"id":"84efd836cbcd2402","type":"ui_button","z":"a3634e48ac6f0f7a","name":"","group":"9eb91d4467c6eec5","order":15,"width":3,"height":1,"passthru":false,"label":"比對資料庫","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"比對資料庫","payloadType":"str","topic":"topic","topicType":"msg","x":150,"y":1160,"wires":[["329518b547d45fa6","b0660fed11dbf785","14a560ff944c6e4d"]]},{"id":"54f57f87a644c5b1","type":"sqlite","z":"a3634e48ac6f0f7a","mydb":"8d99f15e50a51fcd","sqlquery":"msg.topic","sql":"","name":"My_RFID_database","x":920,"y":1160,"wires":[["1428053660920b21"]]},{"id":"0655ace922aaf38f","type":"function","z":"a3634e48ac6f0f7a","name":"SELECT ALL","func":"var query_uidtemp=msg.payload;\nflow.set(\"uidtemp\", query_uidtemp);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":610,"y":560,"wires":[["1eccfd69d95347e1","25d78240c172f1b7"]]},{"id":"4d3b6381092c265b","type":"ui_text_input","z":"a3634e48ac6f0f7a","name":"","label":"手動查詢資料的uidname","tooltip":"","group":"9eb91d4467c6eec5","order":14,"width":3,"height":1,"passthru":true,"mode":"text","delay":300,"topic":"topic","sendOnBlur":true,"className":"","topicType":"msg","x":390,"y":620,"wires":[["0655ace922aaf38f"]]},{"id":"e739bff7428d567d","type":"function","z":"a3634e48ac6f0f7a","name":"function ","func":"var query=msg.payload;\n\nif (query== '1' )\n    msg.payload='Query';\nelse\n    msg.payload='NotQuery';\n\nflow.set(\"query_temp\", msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":580,"y":1360,"wires":[["3394010336c345a8","2a0868acf75d6de3"]]},{"id":"8c2bf31e7aac3e9b","type":"ui_switch","z":"a3634e48ac6f0f7a","name":"","label":"新增模式  /自動比對模式 ","tooltip":"","group":"9eb91d4467c6eec5","order":10,"width":4,"height":1,"passthru":true,"decouple":"false","topic":"s1","topicType":"str","style":"","onvalue":"1","onvalueType":"str","onicon":"","oncolor":"","offvalue":"0","offvalueType":"str","officon":"","offcolor":"","animate":false,"className":"","x":370,"y":1360,"wires":[["e739bff7428d567d","4ac05034663ebe2b","2e8a571b3cbbaa9f"]]},{"id":"3394010336c345a8","type":"debug","z":"a3634e48ac6f0f7a","name":"debug 184","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":730,"y":1320,"wires":[]},{"id":"fd68038a13f39b07","type":"switch","z":"a3634e48ac6f0f7a","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"Create","vt":"str"},{"t":"eq","v":"Query","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":190,"y":480,"wires":[["0f50b06aa25d9a27","fb32a8daf0436db9","fb14c26907304db6"],["fb32a8daf0436db9","05cd3eb72ea21546"]]},{"id":"4c6b8885d3c3cddf","type":"function","z":"a3634e48ac6f0f7a","name":"Query function ","func":"var query = flow.get(\"query_temp\");\n\nflow.set(\"uid_temp\", msg.payload);\n\nif (query==='NotQuery')\n    msg.payload='Create'\nelse\n    msg.payload='Query'\n    \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":300,"y":360,"wires":[["fd68038a13f39b07"]]},{"id":"2a0868acf75d6de3","type":"ui_audio","z":"a3634e48ac6f0f7a","name":"","group":"9eb91d4467c6eec5","voice":"Google US English","always":true,"x":740,"y":1360,"wires":[]},{"id":"5cbfad4c974ebfbb","type":"debug","z":"a3634e48ac6f0f7a","name":"debug ","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":530,"y":1180,"wires":[]},{"id":"1eccfd69d95347e1","type":"debug","z":"a3634e48ac6f0f7a","name":"debug 185","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":810,"y":580,"wires":[]},{"id":"25d78240c172f1b7","type":"ui_text","z":"a3634e48ac6f0f7a","group":"9eb91d4467c6eec5","order":25,"width":6,"height":1,"name":"","label":"自動感應RFID查詢的uid","format":"{{msg.payload}}","layout":"row-left","className":"","x":850,"y":480,"wires":[]},{"id":"7331950d82d2dbea","type":"link in","z":"a3634e48ac6f0f7a","name":"link in 31","links":["06de54b55a8793f0","f316a7347a7ff85a"],"x":275,"y":1240,"wires":[["329518b547d45fa6"]]},{"id":"ead0ca200552071d","type":"function","z":"a3634e48ac6f0f7a","name":"function ","func":"//CREATE TABLE \"RFIDtable\" (\n//\t\"id\"\tINT NOT NULL,\n//  \"uidname\"  TEXT,\n//  \"currentdate\" DATE, \n//  \"currenttime\" TIME\n//\tPRIMARY KEY(\"id\")\n//);\n\n//msg.topic = \"INSERT INTO RFIDtable ( uidname , currentdate, currenttime ) VALUES ($myRFID,  $var_date ,  $var_time ) \" ;\n//msg.payload = [myRFID, var_date , var_time ]\n//return msg;\n\n\nvar tmp=msg.payload;\nmsg.topic = \"select count( * ) as 總共有幾筆資料 from RFIDtable where uidname=($tmp)\";\nmsg.payload=[tmp];\nreturn msg;\n\n// select count( * ) as 總共有幾筆資料 from Customers where address='Japan'","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":500,"y":1460,"wires":[["d4576b8c2154430c","9735b8d80e1cff0d"]]},{"id":"d4576b8c2154430c","type":"sqlite","z":"a3634e48ac6f0f7a","mydb":"8d99f15e50a51fcd","sqlquery":"msg.topic","sql":"","name":"My_RFID_database","x":700,"y":1460,"wires":[["33aa36f869340693","ad3afcd24b4e68c5"]]},{"id":"33aa36f869340693","type":"function","z":"a3634e48ac6f0f7a","name":"function ","func":"var num=msg.payload[0].總共有幾筆資料;\nmsg.payload=num;\nreturn msg; \n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":640,"y":1520,"wires":[["ec2bf5f864be33e7","98c3c67c7d4dd923"]]},{"id":"02dac3468dc35ad8","type":"ui_text","z":"a3634e48ac6f0f7a","group":"9eb91d4467c6eec5","order":17,"width":4,"height":1,"name":"","label":"查詢結果","format":"<font face='arial'><font size=3><font color={{fcolor}}>{{msg.payload}}","layout":"row-left","className":"","x":980,"y":1560,"wires":[]},{"id":"57e4c337ce0dd152","type":"ui_text","z":"a3634e48ac6f0f7a","group":"9eb91d4467c6eec5","order":13,"width":4,"height":1,"name":"","label":"查詢結果:筆數","format":"<font face='arial'><font size=6><font color={{fcolor}}>{{msg.payload}}","layout":"row-left","className":"","x":1000,"y":1520,"wires":[]},{"id":"803dac8d929ebe15","type":"mqtt in","z":"a3634e48ac6f0f7a","name":"","topic":"alex9ufo/esp32/Starting","qos":"2","datatype":"auto-detect","broker":"841df58d.ee5e98","nl":false,"rap":true,"rh":0,"inputs":0,"x":580,"y":80,"wires":[["037541a81c50489e","76d27eedb9c76d0b","a8d12f58b2c1507c"]]},{"id":"037541a81c50489e","type":"ui_audio","z":"a3634e48ac6f0f7a","name":"","group":"9eb91d4467c6eec5","voice":"Google US English","always":false,"x":760,"y":120,"wires":[]},{"id":"76d27eedb9c76d0b","type":"debug","z":"a3634e48ac6f0f7a","name":"debug 186","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":770,"y":40,"wires":[]},{"id":"9735b8d80e1cff0d","type":"debug","z":"a3634e48ac6f0f7a","name":"debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":650,"y":1420,"wires":[]},{"id":"ec2bf5f864be33e7","type":"change","z":"a3634e48ac6f0f7a","name":"","rules":[{"t":"set","p":"fcolor","pt":"msg","to":"red","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":800,"y":1520,"wires":[["57e4c337ce0dd152","3d8c84055d04e53b"]]},{"id":"498aad13b49c5dbd","type":"change","z":"a3634e48ac6f0f7a","name":"","rules":[{"t":"set","p":"fcolor","pt":"msg","to":"red","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":820,"y":1560,"wires":[["02dac3468dc35ad8"]]},{"id":"14a560ff944c6e4d","type":"function","z":"a3634e48ac6f0f7a","name":"function","func":"\nvar a= flow.get(\"uidtemp\");\nmsg.payload=a;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":340,"y":1460,"wires":[["ead0ca200552071d"]]},{"id":"18203a7897a34263","type":"ui_audio","z":"a3634e48ac6f0f7a","name":"","group":"9eb91d4467c6eec5","voice":"Microsoft Hanhan - Chinese (Traditional, Taiwan)","always":true,"x":960,"y":1600,"wires":[]},{"id":"3d8c84055d04e53b","type":"debug","z":"a3634e48ac6f0f7a","name":"debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":970,"y":1480,"wires":[]},{"id":"d33512bf9cb7cdc9","type":"delay","z":"a3634e48ac6f0f7a","name":"","pauseType":"delay","timeout":"2","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":820,"y":1600,"wires":[["18203a7897a34263"]]},{"id":"98c3c67c7d4dd923","type":"function","z":"a3634e48ac6f0f7a","name":"function ","func":"var n=msg.payload;\n\nif (n>0)\n    msg.payload='RFID符合';\nelse\n    msg.payload='RFID錯誤';\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":640,"y":1580,"wires":[["d33512bf9cb7cdc9","498aad13b49c5dbd","d02a83b2a077b95e"]]},{"id":"6eeab9068e8a7cc6","type":"comment","z":"a3634e48ac6f0f7a","name":"Node-Red  subscribe HiveMQ Broker  , ESP32發行","info":"將 alex9ufo/inTopic 到(publish)HiveMQ Broker \n給 Arduino 訂閱(Subscribe)","x":260,"y":140,"wires":[]},{"id":"7f9618ee7be291e6","type":"function","z":"a3634e48ac6f0f7a","name":"function 78","func":"var myRFID = flow.get('uid_temp');\nmsg.payload=myRFID;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":610,"y":480,"wires":[["25d78240c172f1b7"]]},{"id":"b0660fed11dbf785","type":"ui_audio","z":"a3634e48ac6f0f7a","name":"","group":"9eb91d4467c6eec5","voice":"Microsoft Hanhan - Chinese (Traditional, Taiwan)","always":true,"x":300,"y":1120,"wires":[]},{"id":"40915de1f76f8c80","type":"ui_audio","z":"a3634e48ac6f0f7a","name":"","group":"9eb91d4467c6eec5","voice":"Microsoft Hanhan - Chinese (Traditional, Taiwan)","always":true,"x":320,"y":1000,"wires":[]},{"id":"fcc7495cf512588b","type":"function","z":"a3634e48ac6f0f7a","name":"function 79","func":"var ms1=msg.payload[0];\nvar ms2=msg.payload[1];\nvar ms3=msg.payload[2];\n\nmsg.payload=\"新增一筆:\"+ms1+\", 日期: \"+ms2+\", 時間:\"+ms3;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":670,"y":400,"wires":[["2a2a40c34e1b0908"]]},{"id":"2a2a40c34e1b0908","type":"function","z":"a3634e48ac6f0f7a","name":"Set Line API ","func":"msg.headers = {'content-type':'application/x-www-form-urlencoded','Authorization':'Bearer A4wwPNh2WqB7dlfeQyyIAwtggn1kfZSI5LkkCdia1gB'};\nmsg.payload = {\"message\":msg.payload};\nreturn msg;\n\n//oR7KdXvK1eobRr2sRRgsl4PMq23DjDlhfUs96SyUBZu","outputs":1,"noerr":0,"x":850,"y":400,"wires":[["2d34e9baf7a0b25e"]]},{"id":"2d34e9baf7a0b25e","type":"http request","z":"a3634e48ac6f0f7a","name":"","method":"POST","ret":"txt","paytoqs":false,"url":"https://notify-api.line.me/api/notify","tls":"","persist":false,"proxy":"","authType":"","x":1000,"y":400,"wires":[["0437f27fdc06ceb9"]]},{"id":"0437f27fdc06ceb9","type":"debug","z":"a3634e48ac6f0f7a","name":"debug 188","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1150,"y":400,"wires":[]},{"id":"e3e4d275216b7e63","type":"comment","z":"a3634e48ac6f0f7a","name":"Line Notify Message ","info":"","x":870,"y":440,"wires":[]},{"id":"b9a48949a91ef66b","type":"function","z":"a3634e48ac6f0f7a","name":"Set Line API ","func":"msg.headers = {'content-type':'application/x-www-form-urlencoded','Authorization':'Bearer A4wwPNh2WqB7dlfeQyyIAwtggn1kfZSI5LkkCdia1gB'};\nmsg.payload = {\"message\":msg.payload};\nreturn msg;\n\n//oR7KdXvK1eobRr2sRRgsl4PMq23DjDlhfUs96SyUBZu","outputs":1,"noerr":0,"x":810,"y":1680,"wires":[["ca07e35725cf5ae5"]]},{"id":"bc9261ddd92d1e95","type":"comment","z":"a3634e48ac6f0f7a","name":"Line Notify Message ","info":"","x":630,"y":1700,"wires":[]},{"id":"ca07e35725cf5ae5","type":"http request","z":"a3634e48ac6f0f7a","name":"","method":"POST","ret":"txt","paytoqs":false,"url":"https://notify-api.line.me/api/notify","tls":"","persist":false,"proxy":"","authType":"","x":960,"y":1680,"wires":[["0ab7b9eecc6c2903"]]},{"id":"0ab7b9eecc6c2903","type":"debug","z":"a3634e48ac6f0f7a","name":"debug 189","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":930,"y":1740,"wires":[]},{"id":"d02a83b2a077b95e","type":"function","z":"a3634e48ac6f0f7a","name":"function","func":"\nvar a= flow.get(\"uidtemp\");\nvar b=msg.payload;\nmsg.payload=a+\"--->\"+b;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":640,"y":1660,"wires":[["b9a48949a91ef66b","ed38014347f94cfb","3e3d4bb61e004e85"]]},{"id":"1428053660920b21","type":"ui_table","z":"a3634e48ac6f0f7a","group":"9eb91d4467c6eec5","name":"","order":26,"width":14,"height":12,"columns":[],"outputs":0,"cts":false,"x":1130,"y":780,"wires":[]},{"id":"e7f02ef16d9e0f3b","type":"inject","z":"a3634e48ac6f0f7a","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":"1","topic":"","payload":"0","payloadType":"str","x":170,"y":1360,"wires":[["8c2bf31e7aac3e9b","fed0fd4903efc9ad"]]},{"id":"4ac05034663ebe2b","type":"change","z":"a3634e48ac6f0f7a","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"1","fromt":"num","to":"查詢模式","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"0","fromt":"num","to":"新增模式","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":1300,"wires":[["da9eb10b04dca9af","01dd0925571c1076"]]},{"id":"da9eb10b04dca9af","type":"ui_text_input","z":"a3634e48ac6f0f7a","name":"","label":"State:","tooltip":"","group":"9eb91d4467c6eec5","order":11,"width":3,"height":1,"passthru":true,"mode":"text","delay":300,"topic":"","sendOnBlur":true,"className":"","topicType":"str","x":570,"y":1300,"wires":[[]]},{"id":"fed0fd4903efc9ad","type":"debug","z":"a3634e48ac6f0f7a","name":"debug ","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":330,"y":1400,"wires":[]},{"id":"2e8a571b3cbbaa9f","type":"debug","z":"a3634e48ac6f0f7a","name":"debug ","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":510,"y":1400,"wires":[]},{"id":"ba163d27d1929872","type":"inject","z":"a3634e48ac6f0f7a","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":"1","topic":"","payload":"","payloadType":"date","x":160,"y":80,"wires":[["d76335fa75916662"]]},{"id":"d76335fa75916662","type":"function","z":"a3634e48ac6f0f7a","name":"SET DEFAULT VALUE","func":"var del_idtemp=1;\nflow.set(\"idtemp\", del_idtemp);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":80,"wires":[[]]},{"id":"a8d12f58b2c1507c","type":"ui_toast","z":"a3634e48ac6f0f7a","position":"top right","displayTime":"3","highlight":"","sendall":true,"outputs":0,"ok":"OK","cancel":"Cancel","raw":false,"className":"","topic":"","name":"","x":790,"y":80,"wires":[]},{"id":"01dd0925571c1076","type":"ui_toast","z":"a3634e48ac6f0f7a","position":"top right","displayTime":"3","highlight":"","sendall":true,"outputs":0,"ok":"OK","cancel":"Cancel","raw":false,"className":"","topic":"","name":"","x":600,"y":1260,"wires":[]},{"id":"41d056989233b92f","type":"ui_toast","z":"a3634e48ac6f0f7a","position":"prompt","displayTime":"3","highlight":"","sendall":true,"outputs":1,"ok":"OK","cancel":"Cancel","raw":true,"className":"","topic":"","name":"","x":310,"y":1040,"wires":[["8991b071e8b79e6a"]]},{"id":"8991b071e8b79e6a","type":"function","z":"a3634e48ac6f0f7a","name":"function 80","func":"var topic=msg.payload;\nif (topic==\"\"){\n    return [msg,null];\n    \n}\nif (topic==\"Cancel\"){\n    return [null,msg];\n    \n}\nreturn msg;","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":470,"y":1040,"wires":[["33ee680d5192fe7b"],[]]},{"id":"2bbcae8c9ac0d30b","type":"ui_toast","z":"a3634e48ac6f0f7a","position":"prompt","displayTime":"3","highlight":"","sendall":true,"outputs":1,"ok":"OK","cancel":"Cancel","raw":true,"className":"","topic":"","name":"","x":350,"y":1080,"wires":[["1403acb62d180768"]]},{"id":"1403acb62d180768","type":"function","z":"a3634e48ac6f0f7a","name":"function 81","func":"var topic=msg.payload;\nif (topic==\"\"){\n    return [msg,null];\n    \n}\nif (topic==\"Cancel\"){\n    return [null,msg];\n    \n}\nreturn msg;","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":1120,"wires":[["72e2ce34c68eb47d"],[]]},{"id":"270330b108b568f3","type":"ui_toast","z":"a3634e48ac6f0f7a","position":"prompt","displayTime":"3","highlight":"","sendall":true,"outputs":1,"ok":"OK","cancel":"Cancel","raw":true,"className":"","topic":"","name":"","x":270,"y":860,"wires":[["245abd1627a9e864"]]},{"id":"245abd1627a9e864","type":"function","z":"a3634e48ac6f0f7a","name":"function 82","func":"var topic=msg.payload;\nif (topic==\"\"){\n    return [msg,null];\n    \n}\nif (topic==\"Cancel\"){\n    return [null,msg];\n    \n}\nreturn msg;","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":430,"y":860,"wires":[["ca87a44eb0af2529"],[]]},{"id":"e172e3e022ecdc21","type":"link out","z":"a3634e48ac6f0f7a","name":"link out 33","mode":"link","links":["5588b5d6ffcb8c59"],"x":1005,"y":960,"wires":[]},{"id":"5588b5d6ffcb8c59","type":"link in","z":"a3634e48ac6f0f7a","name":"link in 32","links":["e172e3e022ecdc21","d812694deae81cda","ad03f7000e15a6bf"],"x":675,"y":740,"wires":[["d66727debd1881dc"]]},{"id":"d812694deae81cda","type":"link out","z":"a3634e48ac6f0f7a","name":"link out 35","mode":"link","links":["5588b5d6ffcb8c59"],"x":835,"y":340,"wires":[]},{"id":"ad03f7000e15a6bf","type":"link out","z":"a3634e48ac6f0f7a","name":"link out 36","mode":"link","links":["5588b5d6ffcb8c59"],"x":335,"y":740,"wires":[]},{"id":"cfe5209be0e03f9a","type":"ui_toast","z":"a3634e48ac6f0f7a","position":"top right","displayTime":"3","highlight":"","sendall":true,"outputs":0,"ok":"OK","cancel":"Cancel","raw":false,"className":"","topic":"","name":"","x":990,"y":1640,"wires":[]},{"id":"06e06c6465863700","type":"ui_toast","z":"a3634e48ac6f0f7a","position":"top right","displayTime":"3","highlight":"","sendall":true,"outputs":0,"ok":"OK","cancel":"Cancel","raw":false,"className":"","topic":"","name":"","x":410,"y":700,"wires":[]},{"id":"15380f8c2e4236f7","type":"ui_toast","z":"a3634e48ac6f0f7a","position":"top right","displayTime":"3","highlight":"","sendall":true,"outputs":0,"ok":"OK","cancel":"Cancel","raw":false,"className":"","topic":"","name":"","x":630,"y":440,"wires":[]},{"id":"b99db4867081faa8","type":"sqlite","z":"a3634e48ac6f0f7a","mydb":"8d99f15e50a51fcd","sqlquery":"msg.topic","sql":"","name":"My_RFID_database","x":600,"y":280,"wires":[["abdb18149023552a"]]},{"id":"abdb18149023552a","type":"debug","z":"a3634e48ac6f0f7a","name":"debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":790,"y":280,"wires":[]},{"id":"05cd3eb72ea21546","type":"function","z":"a3634e48ac6f0f7a","name":"function","func":"\nvar a= flow.get(\"uid_temp\");\nmsg.payload=a;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":380,"y":560,"wires":[["0655ace922aaf38f","9d3bbe3b43ed309e"]]},{"id":"48b3d445f4605445","type":"sqlite","z":"a3634e48ac6f0f7a","mydb":"8d99f15e50a51fcd","sqlquery":"msg.topic","sql":"","name":"My_RFID_database","x":820,"y":1080,"wires":[["0c10d73879f8ae3e"]]},{"id":"cfeb1f9317935bac","type":"debug","z":"a3634e48ac6f0f7a","name":"debug 190","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":370,"y":960,"wires":[]},{"id":"ed38014347f94cfb","type":"function","z":"a3634e48ac6f0f7a","name":"function","func":"var b=msg.payload;\nmsg.payload=\"Line Notify --->\"+b;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":800,"y":1640,"wires":[["cfe5209be0e03f9a"]]},{"id":"ad3afcd24b4e68c5","type":"debug","z":"a3634e48ac6f0f7a","name":"debug 191","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":970,"y":1440,"wires":[]},{"id":"3e3d4bb61e004e85","type":"debug","z":"a3634e48ac6f0f7a","name":"debug 192","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":810,"y":1780,"wires":[]},{"id":"45f093b1a3e4e478","type":"ui_toast","z":"a3634e48ac6f0f7a","position":"top right","displayTime":"3","highlight":"","sendall":true,"outputs":0,"ok":"OK","cancel":"Cancel","raw":false,"className":"","topic":"","name":"","x":310,"y":320,"wires":[]},{"id":"9d3bbe3b43ed309e","type":"link out","z":"a3634e48ac6f0f7a","name":"link out 37","mode":"link","links":["f15df4eb3e12be13"],"x":475,"y":540,"wires":[]},{"id":"f15df4eb3e12be13","type":"link in","z":"a3634e48ac6f0f7a","name":"link in 34","links":["9d3bbe3b43ed309e"],"x":185,"y":1480,"wires":[["14a560ff944c6e4d"]]},{"id":"9e6416a4fad17e03","type":"comment","z":"a3634e48ac6f0f7a","name":"Set Default Value","info":"","x":160,"y":40,"wires":[]},{"id":"9eb91d4467c6eec5","type":"ui_group","name":"Default","tab":"23af251c8a87881d","order":1,"disp":true,"width":"14","collapse":false,"className":""},{"id":"8d99f15e50a51fcd","type":"sqlitedb","db":"C:\\Users\\User\\.node-red\\2023RFID.db","mode":"RWC"},{"id":"841df58d.ee5e98","type":"mqtt-broker","name":"","broker":"broker.mqtt-dashboard.com","port":"1883","clientid":"","autoConnect":true,"usetls":false,"compatmode":false,"protocolVersion":4,"keepalive":"15","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"23af251c8a87881d","type":"ui_tab","name":"Home_RFID","icon":"dashboard","disabled":false,"hidden":false}]

//====================================================
// esp32-wroom-32 devkit v1 default pins
//       SCL D22
//       SDA D21
//====================================================
// Define the interface type
#include <WiFi.h>           //WIFI
#include <PubSubClient.h>   //MQTT
#include <Wire.h>           //I2C
#include <PN532_I2C.h>      //PN532
#include <PN532.h>
#include <NfcAdapter.h>     //NFC

//NFC
PN532_I2C pn532i2c(Wire);
PN532 nfc(pn532i2c);


// WiFi
const char ssid[] = "alex9ufo"; // Enter your Wi-Fi name
const char password[] = "alex9981";  // Enter Wi-Fi password

// MQTT Broker
const char *mqtt_broker = "broker.mqtt-dashboard.com";
const char *topic2 = "alex9ufo/esp32/RFID";
const char *topic = "alex9ufo/esp32/Starting";
const char *mqtt_username = "alex9ufo";
const char *mqtt_password = "public";
const int mqtt_port = 1883;

bool atwork = false;

WiFiClient espClient;
PubSubClient MQTTclient(espClient);

long lastMsg = 0;
long lastMsg1= 0;
long countNFC= 0;
//=======NFC===============
boolean success;
volatile bool connected = false;
// Buffer to store the UID
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };
  // UID size (4 or 7 bytes depending on card type)
uint8_t uidLength;

char jsonChar1[30];  //client.publish("alex9ufo/Esp32/RFID"
//===========================================================
String printHex(byte *buffer, byte bufferSize) {
      String id = "";
      for (byte i = 0; i < bufferSize; i++) {
        id += buffer[i] < 0x10 ? "0" : "";
        id += String(buffer[i], HEX);
      }
      return id;
    }

//======================================================
bool NFCconnect() {
  nfc.begin();
  // Connected, show version
  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata)
  {
    Serial.println("PN53x card not found!");
    return false;
  }

  //port
  Serial.print("Found chip PN5"); Serial.println((versiondata >> 24) & 0xFF, HEX);
  Serial.print("Firmware version: "); Serial.print((versiondata >> 16) & 0xFF, DEC);
  Serial.print('.'); Serial.println((versiondata >> 8) & 0xFF, DEC);

  // Set the max number of retry attempts to read from a card
  // This prevents us from waiting forever for a card, which is
  // the default behaviour of the PN532.
  nfc.setPassiveActivationRetries(0xFF);

  // configure board to read RFID tags
  nfc.SAMConfig();

  Serial.println("Waiting for card (ISO14443A Mifare)...");
  Serial.println("");

  return true;
}

//===========================================================
void setup() {
    // Set software serial baud to 115200;
    Serial.begin(115200);
    delay(1000); // Delay for stability
    //======================================================
    // Connecting to a WiFi network
    Serial.print("Connecting to ");
    Serial.println(ssid);

    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }

    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
 

    Serial.println(F("Ready!"));
    Serial.println(F("======================================================"));
    Serial.println("*** Testing Module PN532 NFC RFID ***");

    // Connecting to an MQTT broker
    MQTTclient.setServer(mqtt_broker, mqtt_port);
    MQTTclient.setCallback(callback);

    while (!MQTTclient.connected()) {
        String MQTTclient_id = "esp32-client-";
        MQTTclient_id += String(WiFi.macAddress());
        Serial.printf("The client %s connects to the public MQTT broker\n", MQTTclient_id.c_str());
        if (MQTTclient.connect(MQTTclient_id.c_str(), mqtt_username, mqtt_password)) {
            Serial.println("Public HiveMQ MQTT broker (broker.mqtt-dashboard.com) connected");
        } else {
            Serial.print("Failed with state ");
            Serial.print(MQTTclient.state());
            delay(2000);
        }
    }

    // Publish and subscribe
    MQTTclient.publish(topic,"ESP32 at work");
    nfc.begin();
    connected = NFCconnect();
    while (!connected) {
        connected = NFCconnect();
        delay(200);
        Serial.print(". waiting NFC Readey ");
        countNFC=countNFC+1;
        if (countNFC==300){
            MQTTclient.publish(topic,"waiting NFC Readey");
            countNFC=0;
        }

    }
}
//===========================================================
void callback(char* topic, byte* message, unsigned int length) {
    Serial.println("Call back subroutine");
    Serial.println("--------------------");
    Serial.print("Message arrived on topic: ");
    Serial.print(topic);
    Serial.print(". Message: ");
    String messageTemp;
 
    for (int i = 0; i < length; i++) {
      Serial.print((char)message[i]);
      messageTemp += (char)message[i];
    }
    Serial.println();

}

//===========================================================
void reconnect() {
  // Loop until we're reconnected
  while (!MQTTclient.connected()) {
    Serial.print("Attempting MQTT connection...");
    delay(500);
    // Attempt to connect
    if (MQTTclient.connect("esp32-client")) {
      Serial.println("esp32-client connected");
      MQTTclient.setServer(mqtt_broker, mqtt_port);
      MQTTclient.setCallback(callback);  
    } else {
      Serial.print("failed, rc=");
      Serial.print(MQTTclient.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

//===========================================================
void loop() {
  if (!MQTTclient.connected()) {
    reconnect();
    delay(200);
  }
  MQTTclient.loop();
  long now = millis();
  long now1 = millis();

//============================================
    if (now - lastMsg > 5000) {
      Serial.println("Reading RFID card");
      lastMsg = now;
      connected = NFCconnect();
      while (!connected) {
        connected = NFCconnect();
      }
      // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
      // 'uid' will be populated with the UID, and uidLength will indicate
      // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
      success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength);

      // If the card is detected, print the UID
      if (success)
        {
          Serial.println("Card Detected");
          Serial.print("Size of UID: "); Serial.print(uidLength, DEC);
          Serial.println(" bytes");
          Serial.print("UID: ");
          for (uint8_t i = 0; i < uidLength; i++)
          {
            Serial.print(" 0x"); Serial.print(uid[i], HEX);
          }
          Serial.println("");
          Serial.println("");
        //=====================================    
          String json = printHex(uid, uidLength);
          // Convert JSON string to character array
          json.toCharArray(jsonChar1, json.length()+1);
   
          if  (MQTTclient.connected()) {
            Serial.print("Publish message: ");
            Serial.println(json);
            // Publish JSON character array to MQTT topic
            MQTTclient.publish(topic2,jsonChar1);
          }  
          //=====================================
          delay(100);
          connected = NFCconnect();
         
        }

      else
        {
            // PN532 probably timed out waiting for a card
            // Serial.println("Timed out waiting for a card");
        }      
         
    } //(now - lastMsg > 5000)
}
//========================================

沒有留言:

張貼留言

2024產專班 作業2 (純模擬)

2024產專班 作業2  (純模擬) 1) LED ON,OFF,TIMER,FLASH 模擬 (switch 控制) 2)RFID卡號模擬 (buttom  模擬RFID UID(不從ESP32) Node-Red 程式 [{"id":"d8886...