Bonito Bonsai Daisuki!
Published © MIT

Bonsai cultivation device using Strawberry-Pi Pico

I used AtomLite to turn a device made by my friend into an IoT device! I got carried away and even controlled SwitchBot.

AdvancedFull instructions provided90 days309
Bonsai cultivation device using Strawberry-Pi Pico

Things used in this project

Hardware components

Strawberry-Pi Pico
This is a device specialized for cultivation, created by my bonsai friend.
×1
ATOM Lite ESP32 Development Kit
M5Stack ATOM Lite ESP32 Development Kit
The main device for this project.
×1
Raspberry Pi 4 Model B
Raspberry Pi 4 Model B
In this project, we are running Node-RED continuously and using it as a server.
×1
SwitchBot Meter
I designed a mini weather station to use the indoor SwitchBot Meter outdoors. It has been in operation for about three years.
×1
SwitchBot Plug Mini(JP)
This is a 100V outlet plug that can be turned on and off with a program. It is connected to the Kantan Dokodemo Mini Shower.
×1
SwitchBot Hub Mini
This tool enables SwitchBot products to communicate via WiFi and BLE, allowing information to be handled in the cloud.
×1
Kantan Dokodemo Mini Shower
Powered by an AC adapter, it moves a water pump to spray water.
×1
Richell Mielno Plus Pot 17 Type N White Diameter 16.5 x Height 18 cm
The pot for bottom watering can be used as is.
×1
Slit Pot
Slit PotTraditionally, unglazed pots are used for cultivation, but recently, plastic slotted pots are also frequently used.
×1

Software apps and online services

Arduino IDE
Arduino IDE
I created a basic program for Strawberry-Pi Pico. If the connection with the broker is lost and a reset occurs, the system will water the plants once every three hours. This ensures stability by continuing to water the plants even if a problem occurs.
Node-RED MCU
I am creating a program to burn into Atom Lite using Node-RED MCU. This made it very easy to create a program with the simplicity of Node-RED.
Node-RED
Node-RED
It controls communication and UI. Fine adjustments after programming are very easy, and modifications can be made easily.
MQTT
MQTT
I like using it because it is a very easy-to-use communication protocol. In particular, I think it works very well with Node-RED.
SwitchBot API V1.1
I learned about this API through this project. It feels strange to think that my home IoT devices can be utilized via the Internet.
Raspbian
Raspberry Pi Raspbian
It's an OS that you can leave on 24 hours a day without feeling guilty.

Story

Read more

Schematics

System Diagram

This is a diagram of the overall configuration of the system we created this time.

Strawberry-Pi Pico - Atom Lite

This shows Strawberry-Pi Pico and Atom Lite connected.

Strawberry-Pi-Pico_Broker.json

Raspberry Pi Base.json

Swatchbot Handler.json

Code

SPP_20250707.ino

C/C++
This is a program to be written to Strawberry-Pi Pico. It is designed to water plants once every three hours as a basic function, while also being able to process commands.
#include <Arduino.h>
#include <Adafruit_NeoPixel.h>

#define ONBOARD_NP_PIN 25

#define LINE_NP_PIN 24
#define NUMPIXELS 144
#define SENSORPIN A0
#define TRANSISTORPIN 23

Adafruit_NeoPixel pixel0(1, ONBOARD_NP_PIN, NEO_GRB + NEO_KHZ800);


bool bPump = false;         // 
int pumpSec = 60 * 3;       // ()
int waitSec = 60 * 60 * 3;  // ()
int moisture = 0;           // 
unsigned long startTime = 0;// 
unsigned long waitTime = 0; // 
unsigned long dispTime = 0; // 
bool bDisp = false;         // 

int extractValueFromCommand(const String& cmd) {
  if (cmd.length() > 1) {
    return cmd.substring(1).toInt();
  } else {
    return 0;
  }
}

String CommandProcess(const String& cmd) {
  // 
  if (cmd.startsWith("W")) {
    int remainSec = extractValueFromCommand(cmd);
    bPump = true;
    startTime = millis();
    waitTime = remainSec * 1000;
    return "W1";
  }
  if (cmd.startsWith("T")) {
    pumpSec = extractValueFromCommand(cmd);
    if (bPump) {
      startTime = millis();
      waitTime = pumpSec * 1000;
    }
    return "T1";
  }
  if (cmd.startsWith("I")) {
    waitSec = extractValueFromCommand(cmd);
    if (!bPump) {
      startTime = millis();
      waitTime = waitSec * 1000;
    }
    return "I1";
  }
  if (cmd == "R") {
    int remainSec = (waitTime + startTime - millis()) / 1000;
    String response = "R" + String(remainSec);
    return response;
  }
  if (cmd == "S") {
    String response = "S" + String(bPump);
    return response;
  }
  if (cmd == "U") {
    String response = "U" + String(pumpSec);
    return response;
  }
  if (cmd == "J") {
    String response = "J" + String(waitSec);
    return response;
  }
  if (cmd == "M") {
    moisture = analogRead(SENSORPIN);
    String response = "M" + String(moisture);
    return response;
  }

  return "E1"; // 
}

void pumpOn() {
  Serial.println("ON");
  digitalWrite(TRANSISTORPIN, HIGH);
}

void pumpOff() {
  Serial.println("OFF");
  digitalWrite(TRANSISTORPIN, LOW);
}

void setup() {
  Serial.begin(9600);  // 
  pixel0.begin();
  pixel0.setBrightness(50);
  pinMode(TRANSISTORPIN, OUTPUT);
  digitalWrite(TRANSISTORPIN, LOW);

  Serial1.setTX(0); // TXGPIO 0
  Serial1.setRX(1); // RXGPIO 1
  Serial1.begin(9600);
  Serial.println("SST");
  bPump = false;
  startTime = millis(); // 
  waitTime = 5 * 1000;
  dispTime = millis();
  bDisp = false;
}

void loop() {
  // PC
  if (Serial1.available()) {
    String cmd = Serial1.readStringUntil('\n');

    cmd.trim();
    Serial.print(" : ");
    Serial.println(cmd);

    String response = CommandProcess(cmd);

    // 
    Serial.print(" : ");
    Serial.println(response);
    Serial1.println(response);
    delay(100);
  }

  // 
  //(https://garretlab.web.fc2.com/arduino/lab/millis/)
  //
  if (millis() - startTime > waitTime) {
    // 
    if (bPump) {
      pumpOff();
      bPump = false;
      startTime = millis();
      waitTime = waitSec * 1000;
    }
    else {
      pumpOn();
      bPump = true;
      startTime = millis();
      waitTime = pumpSec * 1000;
    }
  }

  //
  if (bPump) {
    if (millis() - dispTime > 500) {
      pixel0.setPixelColor(0, pixel0.Color(0, 0, 50 * bDisp));
      pixel0.show();
      dispTime = millis();
      bDisp = !bDisp;
    }
  }
  else {
    if (millis() - dispTime > 1000) {
      float ratio = (float)(millis() - startTime) / (float)waitTime;
      ratio = constrain(ratio, 0.0, 1.0);  // 0.01.0 
      pixel0.setPixelColor(0, pixel0.Color((uint8_t)(ratio * 50.0 * (float)bDisp), (uint8_t)((1.0 - ratio) * 50.0 * (float)bDisp), 0));
      pixel0.show();
      dispTime = millis();
      bDisp = !bDisp;
    }
  }
}

Strawberry-Pi-Pico_Broker.json

JSON
I created an Atom Lite broker using Node-RED MCU. It receives signals from Strawberry-Pi Pico and transmits them via MQTT.
[
    {
        "id": "de63ccaac6c54193",
        "type": "tab",
        "label": "Strawberry-Pi Pico Broker",
        "disabled": false,
        "info": "",
        "env": [],
        "_mcu": {
            "mcu": true
        }
    },
    {
        "id": "inject_test",
        "type": "inject",
        "z": "de63ccaac6c54193",
        "name": "W1",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "W1",
        "payloadType": "str",
        "_mcu": {
            "mcu": true
        },
        "x": 150,
        "y": 260,
        "wires": [
            [
                "func_parse"
            ]
        ]
    },
    {
        "id": "func_parse",
        "type": "function",
        "z": "de63ccaac6c54193",
        "name": "Cmd+Value > JSON",
        "func": "// 例: \"S1\" や \"R1234\" をパースして JSON に変換\nlet str = msg.payload;\nlet cmd = str.charAt(0);\nlet valueStr = str.substring(1);\nlet value = isNaN(valueStr) ? valueStr : Number(valueStr);\nmsg.payload = {\n    cmd: cmd,\n    value: value\n};\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "_mcu": {
            "mcu": true
        },
        "x": 400,
        "y": 220,
        "wires": [
            [
                "mqtt_out"
            ]
        ]
    },
    {
        "id": "mqtt_out",
        "type": "mqtt out",
        "z": "de63ccaac6c54193",
        "name": "",
        "topic": "SPP/out",
        "qos": "",
        "retain": "",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "6b4a7676fb401863",
        "_mcu": {
            "mcu": true
        },
        "x": 620,
        "y": 220,
        "wires": []
    },
    {
        "id": "4e83e1c3456a51e1",
        "type": "inject",
        "z": "de63ccaac6c54193",
        "name": "T1",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "T1",
        "payloadType": "str",
        "_mcu": {
            "mcu": true
        },
        "x": 150,
        "y": 300,
        "wires": [
            [
                "func_parse"
            ]
        ]
    },
    {
        "id": "badf37736fc97ca1",
        "type": "inject",
        "z": "de63ccaac6c54193",
        "name": "I1",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "I1",
        "payloadType": "str",
        "_mcu": {
            "mcu": true
        },
        "x": 150,
        "y": 340,
        "wires": [
            [
                "func_parse"
            ]
        ]
    },
    {
        "id": "3ecb92334d7f2fdf",
        "type": "inject",
        "z": "de63ccaac6c54193",
        "name": "R1234",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "R1234",
        "payloadType": "str",
        "_mcu": {
            "mcu": true
        },
        "x": 150,
        "y": 380,
        "wires": [
            [
                "func_parse"
            ]
        ]
    },
    {
        "id": "05c484e7e02a678f",
        "type": "inject",
        "z": "de63ccaac6c54193",
        "name": "S1",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "S1",
        "payloadType": "str",
        "_mcu": {
            "mcu": true
        },
        "x": 150,
        "y": 420,
        "wires": [
            [
                "func_parse"
            ]
        ]
    },
    {
        "id": "e877528cef011fe9",
        "type": "inject",
        "z": "de63ccaac6c54193",
        "name": "S0",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "S0",
        "payloadType": "str",
        "_mcu": {
            "mcu": true
        },
        "x": 150,
        "y": 460,
        "wires": [
            [
                "func_parse"
            ]
        ]
    },
    {
        "id": "e2dca2c1c6cb7445",
        "type": "inject",
        "z": "de63ccaac6c54193",
        "name": "U180",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "U180",
        "payloadType": "str",
        "_mcu": {
            "mcu": true
        },
        "x": 150,
        "y": 500,
        "wires": [
            [
                "func_parse"
            ]
        ]
    },
    {
        "id": "04226f8ef648e4fe",
        "type": "inject",
        "z": "de63ccaac6c54193",
        "name": "J10800",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "J10800",
        "payloadType": "str",
        "_mcu": {
            "mcu": true
        },
        "x": 150,
        "y": 540,
        "wires": [
            [
                "func_parse"
            ]
        ]
    },
    {
        "id": "7a162fcce4df1b4f",
        "type": "inject",
        "z": "de63ccaac6c54193",
        "name": "M1234",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "M1234",
        "payloadType": "str",
        "_mcu": {
            "mcu": true
        },
        "x": 150,
        "y": 580,
        "wires": [
            [
                "func_parse"
            ]
        ]
    },
    {
        "id": "5d828bbdf3c31bdd",
        "type": "inject",
        "z": "de63ccaac6c54193",
        "name": "E1",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "E1",
        "payloadType": "str",
        "_mcu": {
            "mcu": true
        },
        "x": 150,
        "y": 620,
        "wires": [
            [
                "func_parse"
            ]
        ]
    },
    {
        "id": "2fa57be624085cf4",
        "type": "function",
        "z": "de63ccaac6c54193",
        "name": "mcu serial in",
        "func": "// code or port settings are written in 'On Start' tab.\n// please ignore red triangle on this node.\n\n// コードやポート設定は「初期化処理(On Start)」にあります。\n// ノードに赤い三角マークがつきますが無視してください。",
        "outputs": 1,
        "timeout": 0,
        "noerr": 4,
        "initialize": "// Code added here will be run once\n// whenever the node is started.\n\nlet serial = new device.io.Serial({\n    ...device.Serial.default,\n    baud: 9600,\n    receive: 32,\n    transmit: 26,\n    format: \"buffer\",\n    onReadable: function (count) {\n        let  msg = {};\n        msg.payload = String.fromArrayBuffer(this.read());\n        msg.payload = msg.payload.trimEnd();\n        node.send(msg);\n    },\n});\nflow.set('serial', serial); // provide 'serial' for 'mcu serial out' node.\n",
        "finalize": "",
        "libs": [],
        "_mcu": {
            "mcu": true
        },
        "x": 130,
        "y": 220,
        "wires": [
            [
                "func_parse"
            ]
        ]
    },
    {
        "id": "99c649e1127deaed",
        "type": "function",
        "z": "de63ccaac6c54193",
        "name": "mcu serial out",
        "func": "let serial = flow.get('serial'); // get 'serial' from 'mcu serial in'\n\nif (msg.payload != null){\n    serial.write(ArrayBuffer.fromString(msg.payload + \"\\n\"));\n}\n",
        "outputs": 0,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "_mcu": {
            "mcu": true
        },
        "x": 640,
        "y": 780,
        "wires": []
    },
    {
        "id": "7adf52005f7c2259",
        "type": "mqtt in",
        "z": "de63ccaac6c54193",
        "name": "",
        "topic": "SPP/in",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "6b4a7676fb401863",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "_mcu": {
            "mcu": true
        },
        "x": 130,
        "y": 780,
        "wires": [
            [
                "3a4d65c7e0517f6f"
            ]
        ]
    },
    {
        "id": "25a7c828d870984d",
        "type": "comment",
        "z": "de63ccaac6c54193",
        "name": "Strawberry Pi Pico >> in",
        "info": "",
        "_mcu": {
            "mcu": true
        },
        "x": 120,
        "y": 160,
        "wires": []
    },
    {
        "id": "691b57f567e078c9",
        "type": "comment",
        "z": "de63ccaac6c54193",
        "name": "out >> Raspberry Pi",
        "info": "",
        "_mcu": {
            "mcu": true
        },
        "x": 650,
        "y": 160,
        "wires": []
    },
    {
        "id": "3a4d65c7e0517f6f",
        "type": "function",
        "z": "de63ccaac6c54193",
        "name": "cmd + value",
        "func": "let obj = JSON.parse(msg.payload);\n\nlet cmd = obj.cmd ?? \"\";\nlet value = obj.value ?? \"\";\n\nmsg.payload = cmd + value;\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "_mcu": {
            "mcu": true
        },
        "x": 350,
        "y": 780,
        "wires": [
            [
                "99c649e1127deaed"
            ]
        ]
    },
    {
        "id": "249951672a3f861a",
        "type": "comment",
        "z": "de63ccaac6c54193",
        "name": "Raspberry Pi >> in",
        "info": "",
        "_mcu": {
            "mcu": true
        },
        "x": 110,
        "y": 720,
        "wires": []
    },
    {
        "id": "f712ae310e2d27ca",
        "type": "comment",
        "z": "de63ccaac6c54193",
        "name": "out >> Strawberry Pi Pico",
        "info": "",
        "_mcu": {
            "mcu": true
        },
        "x": 670,
        "y": 720,
        "wires": []
    },
    {
        "id": "6b4a7676fb401863",
        "type": "mqtt-broker",
        "name": "",
        "broker": "192.168.64.59",
        "port": 1883,
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": 4,
        "keepalive": 60,
        "cleansession": true,
        "autoUnsubscribe": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthRetain": "false",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closeRetain": "false",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willRetain": "false",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": "",
        "_mcu": {
            "mcu": false
        }
    }
]

Raspberry Pi Base.json

JSON
It runs on Node-RED on Raspberry Pi.
It manages the MQTT server, displays signals emitted from the broker on the UI, and transmits changed values.
[
    {
        "id": "309997a2fd87c15a",
        "type": "tab",
        "label": "Raspberry Pi Base",
        "disabled": false,
        "info": "",
        "env": [],
        "_mcu": {
            "mcu": false
        }
    },
    {
        "id": "1490d21255099ebb",
        "type": "junction",
        "z": "309997a2fd87c15a",
        "x": 940,
        "y": 440,
        "wires": [
            [
                "ad5569d57e27a655"
            ]
        ]
    },
    {
        "id": "db2c3a53b69af5ac",
        "type": "aedes broker",
        "z": "309997a2fd87c15a",
        "name": "",
        "mqtt_port": 1883,
        "mqtt_ws_bind": "port",
        "mqtt_ws_port": "",
        "mqtt_ws_path": "",
        "cert": "",
        "key": "",
        "certname": "",
        "keyname": "",
        "persistence_bind": "memory",
        "dburl": "",
        "usetls": false,
        "_mcu": {
            "mcu": false
        },
        "x": 170,
        "y": 60,
        "wires": [
            [],
            []
        ]
    },
    {
        "id": "e9c6645628be9509",
        "type": "mqtt in",
        "z": "309997a2fd87c15a",
        "name": "",
        "topic": "SPP/out",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "6b4a7676fb401863",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "_mcu": {
            "mcu": false
        },
        "x": 140,
        "y": 440,
        "wires": [
            [
                "80d2dc58410cd8a9"
            ]
        ]
    },
    {
        "id": "80d2dc58410cd8a9",
        "type": "switch",
        "z": "309997a2fd87c15a",
        "name": "",
        "property": "payload.cmd",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "R",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "S",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "U",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "J",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "M",
                "vt": "str"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 6,
        "_mcu": {
            "mcu": false
        },
        "x": 300,
        "y": 440,
        "wires": [
            [
                "01f672bdfd6503bc"
            ],
            [
                "e477f882f2fcb5e0"
            ],
            [
                "61e1982c6a927a7e"
            ],
            [
                "950cb41683f6dd44"
            ],
            [
                "59714174168a36a4"
            ],
            []
        ]
    },
    {
        "id": "ad5569d57e27a655",
        "type": "mqtt out",
        "z": "309997a2fd87c15a",
        "name": "",
        "topic": "SPP/in",
        "qos": "",
        "retain": "",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "6b4a7676fb401863",
        "_mcu": {
            "mcu": false
        },
        "x": 1010,
        "y": 440,
        "wires": []
    },
    {
        "id": "ac48e7fc758ff73b",
        "type": "ui_button",
        "z": "309997a2fd87c15a",
        "name": "",
        "group": "2a28fe2c9d53f257",
        "order": 3,
        "width": 0,
        "height": 0,
        "passthru": false,
        "label": "",
        "tooltip": "",
        "color": "",
        "bgcolor": "",
        "className": "",
        "icon": "",
        "payload": "{ \"cmd\" : \"W\", \"value\" : 180 }",
        "payloadType": "str",
        "topic": "topic",
        "topicType": "msg",
        "_mcu": {
            "mcu": false
        },
        "x": 660,
        "y": 520,
        "wires": [
            [
                "1490d21255099ebb"
            ]
        ]
    },
    {
        "id": "199eaaa074548d01",
        "type": "ui_slider",
        "z": "309997a2fd87c15a",
        "name": "",
        "label": "()",
        "tooltip": "",
        "group": "2a28fe2c9d53f257",
        "order": 1,
        "width": 0,
        "height": 0,
        "passthru": true,
        "outs": "end",
        "topic": "topic",
        "topicType": "msg",
        "min": "1",
        "max": "100",
        "step": "1",
        "className": "",
        "_mcu": {
            "mcu": false
        },
        "x": 660,
        "y": 400,
        "wires": [
            [
                "f237f969f7c136b2"
            ]
        ]
    },
    {
        "id": "ac47c1d47f804941",
        "type": "ui_slider",
        "z": "309997a2fd87c15a",
        "name": "",
        "label": "()",
        "tooltip": "",
        "group": "2a28fe2c9d53f257",
        "order": 2,
        "width": 0,
        "height": 0,
        "passthru": true,
        "outs": "end",
        "topic": "topic",
        "topicType": "msg",
        "min": "1",
        "max": "180",
        "step": "10",
        "className": "",
        "_mcu": {
            "mcu": false
        },
        "x": 660,
        "y": 460,
        "wires": [
            [
                "a82e67c454b23b52"
            ]
        ]
    },
    {
        "id": "5526a8bb2cd4e151",
        "type": "ui_gauge",
        "z": "309997a2fd87c15a",
        "name": "",
        "group": "2a28fe2c9d53f257",
        "order": 4,
        "width": 0,
        "height": 0,
        "gtype": "donut",
        "title": "",
        "label": "min.",
        "format": "{{value}}",
        "min": 0,
        "max": "180",
        "colors": [
            "#00b500",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "diff": false,
        "className": "",
        "_mcu": {
            "mcu": false
        },
        "x": 640,
        "y": 580,
        "wires": []
    },
    {
        "id": "742e384f00279995",
        "type": "ui_switch",
        "z": "309997a2fd87c15a",
        "name": "",
        "label": "",
        "tooltip": "",
        "group": "2a28fe2c9d53f257",
        "order": 5,
        "width": 0,
        "height": 0,
        "passthru": false,
        "decouple": "true",
        "topic": "topic",
        "topicType": "msg",
        "style": "",
        "onvalue": "true",
        "onvalueType": "bool",
        "onicon": "",
        "oncolor": "",
        "offvalue": "false",
        "offvalueType": "bool",
        "officon": "",
        "offcolor": "",
        "animate": false,
        "className": "",
        "_mcu": {
            "mcu": false
        },
        "x": 640,
        "y": 640,
        "wires": [
            []
        ]
    },
    {
        "id": "ab4d895a73351fda",
        "type": "ui_numeric",
        "z": "309997a2fd87c15a",
        "name": "",
        "label": "",
        "tooltip": "",
        "group": "2a28fe2c9d53f257",
        "order": 6,
        "width": 0,
        "height": 0,
        "wrap": false,
        "passthru": true,
        "topic": "topic",
        "topicType": "msg",
        "format": "{{value}}",
        "min": 0,
        "max": 10,
        "step": 1,
        "className": "",
        "_mcu": {
            "mcu": false
        },
        "x": 630,
        "y": 700,
        "wires": [
            []
        ]
    },
    {
        "id": "f237f969f7c136b2",
        "type": "change",
        "z": "309997a2fd87c15a",
        "name": "\"T\"+value",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "{ \"cmd\" : \"T\", \"value\" : $number(payload)*60 }",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "_mcu": {
            "mcu": false
        },
        "x": 820,
        "y": 400,
        "wires": [
            [
                "1490d21255099ebb"
            ]
        ]
    },
    {
        "id": "a82e67c454b23b52",
        "type": "change",
        "z": "309997a2fd87c15a",
        "name": "\"I\"+value",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "{ \"cmd\" : \"I\", \"value\" : $number(payload)*60 }",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "_mcu": {
            "mcu": false
        },
        "x": 820,
        "y": 460,
        "wires": [
            [
                "1490d21255099ebb"
            ]
        ]
    },
    {
        "id": "431e69ae3b848d6e",
        "type": "inject",
        "z": "309997a2fd87c15a",
        "name": "first time",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "_mcu": {
            "mcu": false
        },
        "x": 140,
        "y": 160,
        "wires": [
            []
        ]
    },
    {
        "id": "c8bbd9ae0474da30",
        "type": "change",
        "z": "309997a2fd87c15a",
        "name": "\"R\"",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "{ \"cmd\" : \"R\" }",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "_mcu": {
            "mcu": false
        },
        "x": 510,
        "y": 160,
        "wires": [
            [
                "1490d21255099ebb"
            ]
        ]
    },
    {
        "id": "8b9d4885a9ddc88a",
        "type": "change",
        "z": "309997a2fd87c15a",
        "name": "\"S\"",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "{ \"cmd\" : \"S\" }",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "_mcu": {
            "mcu": false
        },
        "x": 510,
        "y": 200,
        "wires": [
            [
                "1490d21255099ebb"
            ]
        ]
    },
    {
        "id": "ef544a3171bc0229",
        "type": "change",
        "z": "309997a2fd87c15a",
        "name": "\"M\"",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "{ \"cmd\" : \"M\" }",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "_mcu": {
            "mcu": false
        },
        "x": 510,
        "y": 320,
        "wires": [
            [
                "1490d21255099ebb"
            ]
        ]
    },
    {
        "id": "8f8902b19ed1c723",
        "type": "change",
        "z": "309997a2fd87c15a",
        "name": "\"U\"",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "{ \"cmd\" : \"U\" }",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "_mcu": {
            "mcu": false
        },
        "x": 510,
        "y": 240,
        "wires": [
            [
                "1490d21255099ebb"
            ]
        ]
    },
    {
        "id": "08312d9071f1315f",
        "type": "change",
        "z": "309997a2fd87c15a",
        "name": "\"J\"",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "{ \"cmd\" : \"J\" }",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "_mcu": {
            "mcu": false
        },
        "x": 510,
        "y": 280,
        "wires": [
            [
                "1490d21255099ebb"
            ]
        ]
    },
    {
        "id": "61e1982c6a927a7e",
        "type": "change",
        "z": "309997a2fd87c15a",
        "name": "value",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "payload.value / 60",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "_mcu": {
            "mcu": false
        },
        "x": 510,
        "y": 400,
        "wires": [
            [
                "199eaaa074548d01"
            ]
        ]
    },
    {
        "id": "950cb41683f6dd44",
        "type": "change",
        "z": "309997a2fd87c15a",
        "name": "value",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "payload.value / 60",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "_mcu": {
            "mcu": false
        },
        "x": 510,
        "y": 460,
        "wires": [
            [
                "ac47c1d47f804941"
            ]
        ]
    },
    {
        "id": "01f672bdfd6503bc",
        "type": "change",
        "z": "309997a2fd87c15a",
        "name": "value",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "$round(payload.value / 60 * 10) / 10",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "_mcu": {
            "mcu": false
        },
        "x": 510,
        "y": 580,
        "wires": [
            [
                "5526a8bb2cd4e151"
            ]
        ]
    },
    {
        "id": "e477f882f2fcb5e0",
        "type": "change",
        "z": "309997a2fd87c15a",
        "name": "value",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "payload.value = 1 ? true : false",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "_mcu": {
            "mcu": false
        },
        "x": 510,
        "y": 640,
        "wires": [
            [
                "742e384f00279995"
            ]
        ]
    },
    {
        "id": "59714174168a36a4",
        "type": "change",
        "z": "309997a2fd87c15a",
        "name": "value",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "payload.value",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "_mcu": {
            "mcu": false
        },
        "x": 510,
        "y": 700,
        "wires": [
            [
                "ab4d895a73351fda",
                "c4e74f0a62526eb5"
            ]
        ]
    },
    {
        "id": "3ad61da910c16d61",
        "type": "inject",
        "z": "309997a2fd87c15a",
        "name": "evrey 1 sec.",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "1",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "_mcu": {
            "mcu": false
        },
        "x": 160,
        "y": 220,
        "wires": [
            [
                "c8bbd9ae0474da30",
                "8b9d4885a9ddc88a",
                "ef544a3171bc0229",
                "8f8902b19ed1c723",
                "08312d9071f1315f"
            ]
        ]
    },
    {
        "id": "30814bf03b72c61a",
        "type": "ui_chart",
        "z": "309997a2fd87c15a",
        "name": "",
        "group": "2a28fe2c9d53f257",
        "order": 6,
        "width": 0,
        "height": 0,
        "label": "",
        "chartType": "line",
        "legend": "false",
        "xformat": "HH:mm:ss",
        "interpolate": "linear",
        "nodata": "",
        "dot": false,
        "ymin": "",
        "ymax": "",
        "removeOlder": 1,
        "removeOlderPoints": "",
        "removeOlderUnit": "604800",
        "cutout": 0,
        "useOneColor": false,
        "useUTC": false,
        "colors": [
            "#1f77b4",
            "#aec7e8",
            "#ff7f0e",
            "#2ca02c",
            "#98df8a",
            "#d62728",
            "#ff9896",
            "#9467bd",
            "#c5b0d5"
        ],
        "outputs": 1,
        "useDifferentColor": false,
        "className": "",
        "_mcu": {
            "mcu": false
        },
        "x": 850,
        "y": 740,
        "wires": [
            []
        ]
    },
    {
        "id": "c4e74f0a62526eb5",
        "type": "delay",
        "z": "309997a2fd87c15a",
        "name": "every 20min.",
        "pauseType": "rate",
        "timeout": "5",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "20",
        "rateUnits": "minute",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": true,
        "allowrate": false,
        "outputs": 1,
        "_mcu": {
            "mcu": false
        },
        "x": 650,
        "y": 740,
        "wires": [
            [
                "30814bf03b72c61a"
            ]
        ]
    },
    {
        "id": "3751b8bd99ad401c",
        "type": "mqtt in",
        "z": "309997a2fd87c15a",
        "name": "",
        "topic": "switchbot-meter/vpd",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "6b4a7676fb401863",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "_mcu": {
            "mcu": false
        },
        "x": 170,
        "y": 880,
        "wires": [
            [
                "65e6ebef26b073cb",
                "41da90ce6733a387"
            ]
        ]
    },
    {
        "id": "65e6ebef26b073cb",
        "type": "ui_gauge",
        "z": "309997a2fd87c15a",
        "name": "",
        "group": "760af579a075de14",
        "order": 5,
        "width": 0,
        "height": 0,
        "gtype": "gage",
        "title": "VPD",
        "label": "kPa",
        "format": "{{value}}",
        "min": 0,
        "max": "3",
        "colors": [
            "#a38800",
            "#00b500",
            "#ca3838"
        ],
        "seg1": "0.8",
        "seg2": "1.2",
        "diff": true,
        "className": "",
        "_mcu": {
            "mcu": false
        },
        "x": 370,
        "y": 880,
        "wires": []
    },
    {
        "id": "41da90ce6733a387",
        "type": "ui_chart",
        "z": "309997a2fd87c15a",
        "name": "",
        "group": "760af579a075de14",
        "order": 6,
        "width": 0,
        "height": 0,
        "label": "VPD",
        "chartType": "line",
        "legend": "false",
        "xformat": "HH:mm:ss",
        "interpolate": "linear",
        "nodata": "",
        "dot": false,
        "ymin": "",
        "ymax": "",
        "removeOlder": 1,
        "removeOlderPoints": "",
        "removeOlderUnit": "604800",
        "cutout": 0,
        "useOneColor": false,
        "useUTC": false,
        "colors": [
            "#1f77b4",
            "#aec7e8",
            "#ff7f0e",
            "#2ca02c",
            "#98df8a",
            "#d62728",
            "#ff9896",
            "#9467bd",
            "#c5b0d5"
        ],
        "outputs": 1,
        "useDifferentColor": false,
        "className": "",
        "_mcu": {
            "mcu": false
        },
        "x": 370,
        "y": 920,
        "wires": [
            []
        ]
    },
    {
        "id": "e62c077f9a42f751",
        "type": "mqtt in",
        "z": "309997a2fd87c15a",
        "name": "",
        "topic": "switchbot-meter/temp",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "6b4a7676fb401863",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "_mcu": {
            "mcu": false
        },
        "x": 180,
        "y": 800,
        "wires": [
            [
                "17774e9aa7f055e1"
            ]
        ]
    },
    {
        "id": "8b8cb637a7f88b36",
        "type": "mqtt in",
        "z": "309997a2fd87c15a",
        "name": "",
        "topic": "switchbot-meter/hum",
        "qos": "2",
        "datatype": "auto-detect",
        "broker": "6b4a7676fb401863",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "_mcu": {
            "mcu": false
        },
        "x": 170,
        "y": 840,
        "wires": [
            [
                "56c0bc0765c33d5f"
            ]
        ]
    },
    {
        "id": "17774e9aa7f055e1",
...

This file has been truncated, please download it to see its full contents.

SwitchBot Handler.json

JSON
Exchange SwitchBot API signals.
Set the Open Token and Secret Key obtained from the SwitchBot app on your smartphone, and use the results to obtain VPD.
[
    {
        "id": "40184443b1291b03",
        "type": "tab",
        "label": "SwitchBot Handler",
        "disabled": false,
        "info": "",
        "env": [],
        "_mcu": {
            "mcu": false
        }
    },
    {
        "id": "929eda5930975394",
        "type": "inject",
        "z": "40184443b1291b03",
        "name": "Initialize",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "_mcu": {
            "mcu": false
        },
        "x": 140,
        "y": 80,
        "wires": [
            [
                "f566e82019707ab0",
                "0e4706c85a456a5a",
                "1ba070e60caf48c4",
                "4d5f4eedb8a3afd6"
            ]
        ]
    },
    {
        "id": "f566e82019707ab0",
        "type": "change",
        "z": "40184443b1291b03",
        "name": "set flow.switchbot_open_token",
        "rules": [
            {
                "t": "set",
                "p": "switchbot_open_token",
                "pt": "flow",
                "to": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "_mcu": {
            "mcu": false
        },
        "x": 410,
        "y": 80,
        "wires": [
            []
        ]
    },
    {
        "id": "0e4706c85a456a5a",
        "type": "change",
        "z": "40184443b1291b03",
        "name": "set flow.switchbot_secret_key",
        "rules": [
            {
                "t": "set",
                "p": "switchbot_secret_key",
                "pt": "flow",
                "to": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "_mcu": {
            "mcu": false
        },
        "x": 410,
        "y": 120,
        "wires": [
            []
        ]
    },
    {
        "id": "1ba070e60caf48c4",
        "type": "change",
        "z": "40184443b1291b03",
        "name": "set flow.meter_status_url",
        "rules": [
            {
                "t": "set",
                "p": "meter_status_url",
                "pt": "flow",
                "to": "https://api.switch-bot.com/v1.1/devices/XXXXXXXXXXXXXXXX/status",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "_mcu": {
            "mcu": false
        },
        "x": 390,
        "y": 160,
        "wires": [
            []
        ]
    },
    {
        "id": "7da1c5a8eb03b1a6",
        "type": "inject",
        "z": "40184443b1291b03",
        "name": "every 30 min.",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "1800",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "_mcu": {
            "mcu": false
        },
        "x": 160,
        "y": 300,
        "wires": [
            [
                "658bb8ae3c357b0e"
            ]
        ]
    },
    {
        "id": "658bb8ae3c357b0e",
        "type": "change",
        "z": "40184443b1291b03",
        "name": "Meter GET",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "{\"command\":\"on_bright\",\"parameter\":\"default\",\"commandType\":\"customize\"}",
                "tot": "json"
            },
            {
                "t": "set",
                "p": "url",
                "pt": "msg",
                "to": "meter_status_url",
                "tot": "flow"
            },
            {
                "t": "set",
                "p": "method",
                "pt": "msg",
                "to": "GET",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "_mcu": {
            "mcu": false
        },
        "x": 350,
        "y": 300,
        "wires": [
            [
                "3e4a6222098fba1a"
            ]
        ]
    },
    {
        "id": "3e4a6222098fba1a",
        "type": "function",
        "z": "40184443b1291b03",
        "name": "Setup to call SwitchBotAPI",
        "func": "const crypto = global.get('crypto');\n\nconst token = flow.get(\"switchbot_open_token\");\nconst secret = flow.get(\"switchbot_secret_key\");\n\nif (!token || !secret) {\n    node.error(\"token or secret is undefined \");\n    return null;\n}\n\nconst t = Date.now().toString();\nconst nonce = crypto.randomBytes(16).toString('base64').substring(0, 16);\nconst data = token + t + nonce;\nconst sign = crypto.createHmac('sha256', secret)\n    .update(Buffer.from(data, 'utf-8'))\n    .digest()\n    .toString(\"base64\");\n\nmsg.token = token;\nmsg.sign = sign;\nmsg.t = t;\nmsg.nonce = nonce;\nreturn msg;\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "_mcu": {
            "mcu": false
        },
        "x": 560,
        "y": 300,
        "wires": [
            [
                "787894589a193107"
            ]
        ]
    },
    {
        "id": "787894589a193107",
        "type": "http request",
        "z": "40184443b1291b03",
        "name": "Request to SwitchBot http",
        "method": "use",
        "ret": "txt",
        "paytoqs": "ignore",
        "url": "",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [
            {
                "keyType": "Content-Type",
                "keyValue": "",
                "valueType": "other",
                "valueValue": "application/json"
            },
            {
                "keyType": "Authorization",
                "keyValue": "",
                "valueType": "msg",
                "valueValue": "token"
            },
            {
                "keyType": "other",
                "keyValue": "sign",
                "valueType": "msg",
                "valueValue": "sign"
            },
            {
                "keyType": "other",
                "keyValue": "t",
                "valueType": "msg",
                "valueValue": "t"
            },
            {
                "keyType": "other",
                "keyValue": "nonce",
                "valueType": "msg",
                "valueValue": "nonce"
            }
        ],
        "_mcu": {
            "mcu": false
        },
        "x": 810,
        "y": 300,
        "wires": [
            [
                "2a289686ca1a6971",
                "fb0411288231bd79",
                "d040c00760062bfd"
            ]
        ]
    },
    {
        "id": "2a289686ca1a6971",
        "type": "function",
        "z": "40184443b1291b03",
        "name": "get VPD",
        "func": "let data = JSON.parse(msg.payload);\n\nlet temp = data.body.temperature;\nlet hum = data.body.humidity;\n\nlet e_s = 0.6108 * Math.exp((17.27 * temp) / (temp + 237.3));\nlet e_a = e_s * (hum / 100);\nlet vpd = e_s - e_a;\n\nmsg.payload = Number(vpd.toFixed(2));\nreturn msg;\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "_mcu": {
            "mcu": false
        },
        "x": 1020,
        "y": 340,
        "wires": [
            [
                "7466fe9aea83a072",
                "c980fccb66cf5dbc"
            ]
        ]
    },
    {
        "id": "c980fccb66cf5dbc",
        "type": "switch",
        "z": "40184443b1291b03",
        "name": "VPD >= 1.5 ",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "gte",
                "v": "1.5",
                "vt": "num"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "_mcu": {
            "mcu": false
        },
        "x": 250,
        "y": 400,
        "wires": [
            [
                "a81032d966e9d076"
            ]
        ]
    },
    {
        "id": "7466fe9aea83a072",
        "type": "mqtt out",
        "z": "40184443b1291b03",
        "name": "",
        "topic": "switchbot-meter/vpd",
        "qos": "",
        "retain": "",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "6b4a7676fb401863",
        "_mcu": {
            "mcu": false
        },
        "x": 1240,
        "y": 340,
        "wires": []
    },
    {
        "id": "a81032d966e9d076",
        "type": "change",
        "z": "40184443b1291b03",
        "name": "Plug turn on POST",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "{\"command\":\"turnOn\",\"parameter\":\"default\",\"commandType\":\"command\"}",
                "tot": "json"
            },
            {
                "t": "set",
                "p": "url",
                "pt": "msg",
                "to": "plug_commands_url",
                "tot": "flow"
            },
            {
                "t": "set",
                "p": "method",
                "pt": "msg",
                "to": "POST",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "_mcu": {
            "mcu": false
        },
        "x": 370,
        "y": 460,
        "wires": [
            [
                "062fdb824990a89b"
            ]
        ]
    },
    {
        "id": "4d5f4eedb8a3afd6",
        "type": "change",
        "z": "40184443b1291b03",
        "name": "set flow.plug_commands_url",
        "rules": [
            {
                "t": "set",
                "p": "plug_commands_url",
                "pt": "flow",
                "to": "https://api.switch-bot.com/v1.1/devices/XXXXXXXXXX/commands",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "_mcu": {
            "mcu": false
        },
        "x": 400,
        "y": 200,
        "wires": [
            []
        ]
    },
    {
        "id": "062fdb824990a89b",
        "type": "function",
        "z": "40184443b1291b03",
        "name": "Setup to call SwitchBotAPI",
        "func": "const crypto = global.get('crypto');\n\nconst token = flow.get(\"switchbot_open_token\");\nconst secret = flow.get(\"switchbot_secret_key\");\n\nif (!token || !secret) {\n    node.error(\"token or secret is undefined \");\n    return null;\n}\n\nconst t = Date.now().toString();\nconst nonce = crypto.randomBytes(16).toString('base64').substring(0, 16);\nconst data = token + t + nonce;\nconst sign = crypto.createHmac('sha256', secret)\n    .update(Buffer.from(data, 'utf-8'))\n    .digest()\n    .toString(\"base64\");\n\nmsg.token = token;\nmsg.sign = sign;\nmsg.t = t;\nmsg.nonce = nonce;\nreturn msg;\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "_mcu": {
            "mcu": false
        },
        "x": 620,
        "y": 460,
        "wires": [
            [
                "7df20d82d13ea040"
            ]
        ]
    },
    {
        "id": "7df20d82d13ea040",
        "type": "http request",
        "z": "40184443b1291b03",
        "name": "Request to SwitchBot http",
        "method": "use",
        "ret": "txt",
        "paytoqs": "ignore",
        "url": "",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [
            {
                "keyType": "Content-Type",
                "keyValue": "",
                "valueType": "other",
                "valueValue": "application/json"
            },
            {
                "keyType": "Authorization",
                "keyValue": "",
                "valueType": "msg",
                "valueValue": "token"
            },
            {
                "keyType": "other",
                "keyValue": "sign",
                "valueType": "msg",
                "valueValue": "sign"
            },
            {
                "keyType": "other",
                "keyValue": "t",
                "valueType": "msg",
                "valueValue": "t"
            },
            {
                "keyType": "other",
                "keyValue": "nonce",
                "valueType": "msg",
                "valueValue": "nonce"
            }
        ],
        "_mcu": {
            "mcu": false
        },
        "x": 890,
        "y": 460,
        "wires": [
            [
                "61df1c73357945b7"
            ]
        ]
    },
    {
        "id": "e69a543bdaa52ccd",
        "type": "change",
        "z": "40184443b1291b03",
        "name": "Plug turn off POST",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "{\"command\":\"turnOff\",\"parameter\":\"default\",\"commandType\":\"command\"}",
                "tot": "json"
            },
            {
                "t": "set",
                "p": "url",
                "pt": "msg",
                "to": "plug_commands_url",
                "tot": "flow"
            },
            {
                "t": "set",
                "p": "method",
                "pt": "msg",
                "to": "POST",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "_mcu": {
            "mcu": false
        },
        "x": 370,
        "y": 580,
        "wires": [
            [
                "bbcb09cc57fb5311"
            ]
        ]
    },
    {
        "id": "bbcb09cc57fb5311",
        "type": "function",
        "z": "40184443b1291b03",
        "name": "Setup to call SwitchBotAPI",
        "func": "const crypto = global.get('crypto');\n\nconst token = flow.get(\"switchbot_open_token\");\nconst secret = flow.get(\"switchbot_secret_key\");\n\nif (!token || !secret) {\n    node.error(\"token or secret is undefined \");\n    return null;\n}\n\nconst t = Date.now().toString();\nconst nonce = crypto.randomBytes(16).toString('base64').substring(0, 16);\nconst data = token + t + nonce;\nconst sign = crypto.createHmac('sha256', secret)\n    .update(Buffer.from(data, 'utf-8'))\n    .digest()\n    .toString(\"base64\");\n\nmsg.token = token;\nmsg.sign = sign;\nmsg.t = t;\nmsg.nonce = nonce;\nreturn msg;\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "_mcu": {
            "mcu": false
        },
        "x": 620,
        "y": 580,
        "wires": [
            [
                "cabc75c219df82b6"
            ]
        ]
    },
    {
        "id": "cabc75c219df82b6",
        "type": "http request",
        "z": "40184443b1291b03",
        "name": "Request to SwitchBot http",
        "method": "use",
        "ret": "txt",
        "paytoqs": "ignore",
        "url": "",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [
            {
                "keyType": "Content-Type",
                "keyValue": "",
                "valueType": "other",
                "valueValue": "application/json"
            },
            {
                "keyType": "Authorization",
                "keyValue": "",
                "valueType": "msg",
                "valueValue": "token"
            },
            {
                "keyType": "other",
                "keyValue": "sign",
                "valueType": "msg",
                "valueValue": "sign"
            },
            {
                "keyType": "other",
                "keyValue": "t",
                "valueType": "msg",
                "valueValue": "t"
            },
            {
                "keyType": "other",
                "keyValue": "nonce",
                "valueType": "msg",
                "valueValue": "nonce"
            }
        ],
        "_mcu": {
            "mcu": false
        },
        "x": 890,
        "y": 580,
        "wires": [
            []
        ]
    },
    {
        "id": "61df1c73357945b7",
        "type": "delay",
        "z": "40184443b1291b03",
        "name": "",
        "pauseType": "delay",
        "timeout": "10",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "_mcu": {
            "mcu": false
        },
        "x": 240,
        "y": 520,
        "wires": [
            [
                "e69a543bdaa52ccd"
            ]
        ]
    },
    {
        "id": "bfb62571fc18db77",
        "type": "inject",
        "z": "40184443b1291b03",
        "name": "for test",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "_mcu": {
            "mcu": false
        },
        "x": 190,
        "y": 460,
        "wires": [
            [
                "a81032d966e9d076"
            ]
        ]
    },
    {
        "id": "d040c00760062bfd",
        "type": "function",
        "z": "40184443b1291b03",
        "name": "get temperature",
        "func": "let data = JSON.parse(msg.payload);\n\nlet temp = data.body.temperature;\nlet hum = data.body.humidity;\n\nmsg.payload = Number(temp.toFixed(2));\nreturn msg;\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "_mcu": {
            "mcu": false
        },
        "x": 1040,
        "y": 260,
        "wires": [
            [
                "46987fcdb41886e5"
            ]
        ]
    },
    {
        "id": "fb0411288231bd79",
        "type": "function",
        "z": "40184443b1291b03",
        "name": "get humidity",
        "func": "let data = JSON.parse(msg.payload);\n\nlet temp = data.body.temperature;\nlet hum = data.body.humidity;\n\nmsg.payload = Number(hum.toFixed(2));\nreturn msg;\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "_mcu": {
            "mcu": false
        },
        "x": 1030,
        "y": 300,
        "wires": [
            [
                "31b3653355001aa7"
            ]
        ]
    },
    {
        "id": "31b3653355001aa7",
        "type": "mqtt out",
        "z": "40184443b1291b03",
        "name": "",
        "topic": "switchbot-meter/hum",
        "qos": "",
        "retain": "",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "6b4a7676fb401863",
        "_mcu": {
            "mcu": false
        },
        "x": 1240,
        "y": 300,
        "wires": []
    },
    {
        "id": "46987fcdb41886e5",
        "type": "mqtt out",
        "z": "40184443b1291b03",
        "name": "",
        "topic": "switchbot-meter/temp",
        "qos": "",
        "retain": "",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "6b4a7676fb401863",
        "_mcu": {
            "mcu": false
        },
        "x": 1240,
        "y": 260,
        "wires": []
    },
    {
        "id": "6b4a7676fb401863",
        "type": "mqtt-broker",
        "name": "",
        "broker": "000.000.000.000",
        "port": 1883,
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": 4,
        "keepalive": 60,
        "cleansession": true,
        "autoUnsubscribe": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthRetain": "false",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closeRetain": "false",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willRetain": "false",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": "",
        "_mcu": {
            "mcu": false
        }
    }
]

Credits

Bonito Bonsai Daisuki!
1 project • 4 followers
Bonsai lover. Electric crafting, M5Stack, Raspberry Pi.CAD/CAM Engineer

Comments