# Raspi Control SainSmart USB Connected Relay

**URL:** <https://discourse.nodered.org/t/raspi-control-sainsmart-usb-connected-relay/92081>\
**Category:** General\
**Created:** [30 September 2024 18:15 UTC](https://discourse.nodered.org/t/raspi-control-sainsmart-usb-connected-relay/92081 "2024-09-30T18:15:28Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![ryanprel](https://avatars.discourse-cdn.com/v4/letter/r/7c8e57/32.png) [@ryanprel](https://discourse.nodered.org/u/ryanprel)\
**Post date:** [30 September 2024 18:15 UTC](https://discourse.nodered.org/t/raspi-control-sainsmart-usb-connected-relay/92081/1 "2024-09-30T18:15:28Z")

</div>

I'm in the process of switching from a Denkovi wifi modbus relay to a SainSmart USB connected relay, both are 16 port relays. I'm trying to use gdziuba/node-red-usbhid to connect up. I've also tried the other hid modules and can't get any of them to work as expected. I'm assuming this has something to do with the configuration of the Raspberry Pi more than it is an issue with Node-Red but I'm not positive about that.

This is the new SainSmart relay: [16-Channel 9-36V USB Relay Module – SainSmart.com](https://www.sainsmart.com/products/16-channel-9-36v-usb-relay-module)

Below is the USBHID flow I'm trying to use to connect to the USB Relay and a screenshot of the LUSB scan to determine the VID and PID.

I've added a file to /etc/udev/rules.d with the additional udev rules I think are needed and added the pi user to the input group.

The debug data is below - the getHIDdevices is throwing the empty array and the HIDdevice is showing disconnected and debug shows the bottom error from that node.

Any ideas on what I'm missing on this? I'm switching relays because I want the local connection for reliability and the Denkovi relay also just stopped connecting and being accessible to my network. A full factory reset on the device (several times) wasn't able to fix it so I'm moving the switchover to the SainSmart relay up on the schedule but struggling to make the SainSmart relay available to node-red.

I haven't really been able to find any support for SainSmart USB relays with node-red so hopefully this thread also is useful for the next person.

```auto
[{"id":"cbae0763803aa6e9","type":"group","z":"3b6a718c4021497b","name":"USBHID","style":{"label":true},"nodes":["78f82fb335672aca","c1ecae6308a0525f","d99660be8c6c6066","546ab3a525f72ecc","1b5120024bf4bc62","f8d8cae1919e186c","e1d69c8863f6de73"],"x":34,"y":19,"w":692,"h":122},{"id":"78f82fb335672aca","type":"debug","z":"3b6a718c4021497b","g":"cbae0763803aa6e9","name":"debug 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":460,"y":60,"wires":[]},{"id":"c1ecae6308a0525f","type":"getHIDdevices","z":"3b6a718c4021497b","g":"cbae0763803aa6e9","name":"","x":300,"y":60,"wires":[["78f82fb335672aca"]]},{"id":"d99660be8c6c6066","type":"inject","z":"3b6a718c4021497b","g":"cbae0763803aa6e9","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":60,"wires":[["c1ecae6308a0525f"]]},{"id":"546ab3a525f72ecc","type":"HIDdevice","z":"3b6a718c4021497b","g":"cbae0763803aa6e9","connection":"68a0ec4b6af1dcb1","name":"","x":290,"y":100,"wires":[["e1d69c8863f6de73"],[]]},{"id":"1b5120024bf4bc62","type":"inject","z":"3b6a718c4021497b","g":"cbae0763803aa6e9","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":100,"wires":[["546ab3a525f72ecc"]]},{"id":"f8d8cae1919e186c","type":"debug","z":"3b6a718c4021497b","g":"cbae0763803aa6e9","name":"debug 3","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":620,"y":100,"wires":[]},{"id":"e1d69c8863f6de73","type":"function","z":"3b6a718c4021497b","g":"cbae0763803aa6e9","name":"Hex to String","func":"const hexBuffer = msg.payload;\n\n// Convert the hex buffer to a Buffer object\nconst buffer = Buffer.from(hexBuffer, 'hex');\n\n// Convert the Buffer to a string\nconst string = buffer.toString();\n\n// Assign the string to msg.payload for further processing\nmsg.payload = string;\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":470,"y":100,"wires":[["f8d8cae1919e186c"]]},{"id":"68a0ec4b6af1dcb1","type":"HIDConfig","vid":"1504","pid":"1536","name":"Barcode Scanner"}]

```

 ![Screenshot 2024-09-30 at 11.01.36 AM](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/8/e/8ebd42dd986b0dddba55bf5e0c9ac05fee76b277.png)

 ![Screenshot 2024-09-30 at 1.04.31 PM](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/0/9/09aa7d6fb14cf885008be688dd0ce1406a0fbaec.png)

![Screenshot 2024-09-30 at 1.08.54 PM](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/1/7/17d2c676fbde7cddd11546ecc826583db5ab7e4a.png)

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [30 September 2024 19:30 UTC](https://discourse.nodered.org/t/raspi-control-sainsmart-usb-connected-relay/92081/2 "2024-09-30T19:30:11Z")

</div>

Can you point us to the documentation for using the board?

---

<div class="post-metadata">

**Author:** ![ryanprel](https://avatars.discourse-cdn.com/v4/letter/r/7c8e57/32.png) [@ryanprel](https://discourse.nodered.org/u/ryanprel)\
**Post date:** [30 September 2024 20:39 UTC](https://discourse.nodered.org/t/raspi-control-sainsmart-usb-connected-relay/92081/3 "2024-09-30T20:39:25Z")

</div>

This is about the only documentation I can find from their website. I've pasted the text of this document below. I am able to setup a serial control node to /dev/ttyusb0 and that's showing a green light, a serial-in node is showing not connected and a serial-request node times out when I try to send a status request of "status = usbrelay[0][1] " to it via an inject node. I'm assuming I have something configured wrong here but changing to serial communications is maybe the direction I need to go?

[https://s3.us-east-1.amazonaws.com/s3.image.smart/download/101-70-208/WIN10%26Python3.7.txt](https://s3.us-east-1.amazonaws.com/s3.image.smart/download/101-70-208/WIN10%26Python3.7.txt)

* * *

This 16-channel usb relay (101-70-208) works great with Python 3.7 and Windows 10 (see sample Python code)  
The HEX table from Sainsmart needs to be converted to ASCII chars. See sample Python code:  
========== python code below =========  
import serial  
from time import sleep

port = 'COM13' # change this to YOUR usb port  
ser = serial.Serial(port, 9600, timeout=5)

delay = 1  
tap\_delay = 2  
ready\_delay = 3  
off\_delay = .5

"""  
Sainsmart 16-Channel 9-36v USB Relay Module (CH341 chip)(sku# 101-70-208)

1. Requires CH341 Windows driver installed (see [http://wiki.sainsmart.com/index.php/101-70-208](http://wiki.sainsmart.com/index.php/101-70-208))
2. The hex table provided by Sainsmart requires converting to ASCII chars (see 'usbrelay' below)
3. Format of 'usbrelay' two-dimensional array is:  
usbrelay = [row][ch-off, ch-on] so that the 2nd index selects ON/OFF value  
while the 1st index selects the array row.  
Example...  
status = usbrelay[0][1] # row-0 (status)  
stat\_ret = usbrelay[0][0] # row-0 (status return)  
ch\_1\_on = usbrelay[1][1] # row-1 (chan-1 off)  
ch\_1\_off = usbrelay[1][0] # row-1 (chan-1 off)  
ch\_16\_on = usbrelay[16][1] # row-16 (chan-16 on)  
ch\_16\_off = usbrelay[16][0] # row-16 (chan-16 off)  
all\_on = usbrelay[17][1] # row-17 (all on)  
all\_off = usbrelay[17][0] # row-17 (all off)  
"""

usbrelay = [[b':FE0100200000FF\r\n', b':FE0100000010F1\r\n'], # status & status return  
[b':FE0500000000FD\r\n', b':FE050000FF00FE\r\n'], # channel-1  
[b':FE0500010000FC\r\n', b':FE050001FF00FD\r\n'], # channel-2  
[b':FE0500020000FB\r\n', b':FE050002FF00FC\r\n'], # channel-3  
[b':FE0500030000FA\r\n', b':FE050003FF00FB\r\n'], # channel-4  
[b':FE0500040000F9\r\n', b':FE050004FF00FA\r\n'], # channel-5  
[b':FE0500050000F8\r\n', b':FE050005FF00F9\r\n'], # channel-6  
[b':FE0500060000F7\r\n', b':FE050006FF00F8\r\n'], # channel-7  
[b':FE0500070000F6\r\n', b':FE050007FF00F7\r\n'], # channel-8  
[b':FE0500080000F5\r\n', b':FE050008FF00F6\r\n'], # channel-9  
[b':FE0500090000F4\r\n', b':FE050009FF00F5\r\n'], # channel-10  
[b':FE05000A0000F3\r\n', b':FE05000AFF00F4\r\n'], # channel-11  
[b':FE05000B0000F2\r\n', b':FE05000BFF00F3\r\n'], # channel-12  
[b':FE05000C0000F1\r\n', b':FE05000CFF00F2\r\n'], # channel-13  
[b':FE05000D0000F0\r\n', b':FE05000DFF00F1\r\n'], # channel-14  
[b':FE05000E0000FF\r\n', b':FE05000EFF00F0\r\n'], # channel-15  
[b':FE05000F0000FE\r\n', b':FE05000FFF00FF\r\n'], # channel-16  
[b':FE0F00000010020000E1\r\n', b':FE0F0000001002FFFFE3\r\n']] # all channels

# # uncomment below for quick sequencing test

# for row in range(len(usbrelay)): # sequence through each row

# ser.write(usbrelay[row][1]) # turn ON

# sleep(delay/2)

# ser.write(usbrelay[row][0]) # turn OFF

# sleep(delay/2)

# below is example of turning single usbrelay channel on/off

def ch\_9\_on\_off():  
ser.write(usbrelay[9][1])  
sleep(delay)  
ser.write(usbrelay[9][0])  
sleep(off\_delay)  
def ch\_10\_on\_off():  
ser.write(usbrelay[10][1])  
sleep(delay)  
ser.write(usbrelay[10][0])  
sleep(off\_delay)  
def ch\_11\_on\_off():  
ser.write(usbrelay[11][1])  
sleep(delay)  
ser.write(usbrelay[11][0])  
sleep(off\_delay)  
def ch\_12\_on\_off():  
ser.write(usbrelay[12][1])  
sleep(delay)  
ser.write(usbrelay[12][0])  
sleep(off\_delay)

# # below is example of using this usbrelay bd to control a 4-port usb switch.

# (usb\_port\_switching uses PAIR of usbrelay channels)

def usb\_1\_ON():  
ser.write(usbrelay[1][1])  
ser.write(usbrelay[2][1])  
sleep(ready\_delay)  
def usb\_1\_OFF():  
ser.write(usbrelay[1][0])  
ser.write(usbrelay[2][0])  
sleep(off\_delay)  
def usb\_2\_ON():  
ser.write(usbrelay[3][1])  
ser.write(usbrelay[4][1])  
sleep(ready\_delay)  
def usb\_2\_OFF():  
ser.write(usbrelay[3][0])  
ser.write(usbrelay[4][0])  
sleep(off\_delay)  
def usb\_3\_ON():  
ser.write(usbrelay[5][1])  
ser.write(usbrelay[6][1])  
sleep(ready\_delay)  
def usb\_3\_OFF():  
ser.write(usbrelay[5][0])  
ser.write(usbrelay[6][0])  
sleep(off\_delay)  
def usb\_4\_ON():  
ser.write(usbrelay[7][1])  
ser.write(usbrelay[8][1])  
sleep(ready\_delay)  
def usb\_4\_OFF():  
ser.write(usbrelay[7][0])  
ser.write(usbrelay[8][0])  
sleep(off\_delay)

def main():  
ch\_9\_on\_off()  
ch\_10\_on\_off()  
ch\_11\_on\_off()  
ch\_12\_on\_off()

usb\_1\_ON()  
usb\_1\_OFF()  
usb\_2\_ON()  
usb\_2\_OFF()  
usb\_3\_ON()  
usb\_3\_OFF()  
usb\_4\_ON()  
usb\_4\_OFF()

if **name** == " **main**":  
main()  
ser.close()

---

<div class="post-metadata">

**Author:** ![ryanprel](https://avatars.discourse-cdn.com/v4/letter/r/7c8e57/32.png) [@ryanprel](https://discourse.nodered.org/u/ryanprel)\
**Post date:** [30 September 2024 20:44 UTC](https://discourse.nodered.org/t/raspi-control-sainsmart-usb-connected-relay/92081/4 "2024-09-30T20:44:28Z")

</div>

This is the lsusb -v ouput for the device in question and it is listing it as a "serial converter".

Bus 001 Device 003: ID 1a86:7523 QinHeng Electronics CH340 serial converter  
Device Descriptor:  
bLength 18  
bDescriptorType 1  
bcdUSB 1.10  
bDeviceClass 255 Vendor Specific Class  
bDeviceSubClass 0  
bDeviceProtocol 0  
bMaxPacketSize0 8  
idVendor 0x1a86 QinHeng Electronics  
idProduct 0x7523 CH340 serial converter  
bcdDevice 2.64  
iManufacturer 0  
iProduct 2 USB Serial  
iSerial 0  
bNumConfigurations 1  
Configuration Descriptor:  
bLength 9  
bDescriptorType 2  
wTotalLength 0x0027  
bNumInterfaces 1  
bConfigurationValue 1  
iConfiguration 0  
bmAttributes 0x80  
(Bus Powered)  
MaxPower 98mA  
Interface Descriptor:  
bLength 9  
bDescriptorType 4  
bInterfaceNumber 0  
bAlternateSetting 0  
bNumEndpoints 3  
bInterfaceClass 255 Vendor Specific Class  
bInterfaceSubClass 1  
bInterfaceProtocol 2  
iInterface 0  
Endpoint Descriptor:  
bLength 7  
bDescriptorType 5  
bEndpointAddress 0x82 EP 2 IN  
bmAttributes 2  
Transfer Type Bulk  
Synch Type None  
Usage Type Data  
wMaxPacketSize 0x0020 1x 32 bytes  
bInterval 0  
Endpoint Descriptor:  
bLength 7  
bDescriptorType 5  
bEndpointAddress 0x02 EP 2 OUT  
bmAttributes 2  
Transfer Type Bulk  
Synch Type None  
Usage Type Data  
wMaxPacketSize 0x0020 1x 32 bytes  
bInterval 0  
Endpoint Descriptor:  
bLength 7  
bDescriptorType 5  
bEndpointAddress 0x81 EP 1 IN  
bmAttributes 3  
Transfer Type Interrupt  
Synch Type None  
Usage Type Data  
wMaxPacketSize 0x0008 1x 8 bytes  
bInterval 1  
Device Status: 0x0000  
(Bus Powered)

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [1 October 2024 08:36 UTC](https://discourse.nodered.org/t/raspi-control-sainsmart-usb-connected-relay/92081/5 "2024-10-01T08:36:38Z")

</div>

Unplug the usb connection, open a command window and run `tail -f /var/log/syslog` and plug in the usb connector. Copy/paste here what is shown in the log. Copy/paste please, not screen shot.

What does the command `/dev/serial/by_id` show?

Uninstall the hid nodes, use serial instead.

Show us the output when you start node red in a command window.

---

<div class="post-metadata">

**Author:** ![ryanprel](https://avatars.discourse-cdn.com/v4/letter/r/7c8e57/32.png) [@ryanprel](https://discourse.nodered.org/u/ryanprel)\
**Post date:** [1 October 2024 14:08 UTC](https://discourse.nodered.org/t/raspi-control-sainsmart-usb-connected-relay/92081/6 "2024-10-01T14:08:44Z")

</div>

* * *

journalctl output because syslog doesn't exist on raspberry pi as rsyslog isn't installed by default.

Oct 01 08:46:52 micros kernel: usb 1-1.2: new full-speed USB device number 4 using xhci\_hcd

Oct 01 08:46:52 micros kernel: usb 1-1.2: New USB device found, idVendor=1a86, idProduct=7523, bcdDevice= 2.64

Oct 01 08:46:52 micros kernel: usb 1-1.2: New USB device strings: Mfr=0, Product=2, SerialNumber=0

Oct 01 08:46:52 micros kernel: usb 1-1.2: Product: USB Serial

Oct 01 08:46:52 micros kernel: ch341 1-1.2:1.0: ch341-uart converter detected

Oct 01 08:46:52 micros kernel: usb 1-1.2: ch341-uart converter now attached to ttyUSB0

Oct 01 08:46:52 micros mtp-probe[3839]: checking bus 1, device 4: "/sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2"

Oct 01 08:46:52 micros mtp-probe[3839]: bus: 1, device: 4 was not an MTP device

Oct 01 08:46:52 micros mtp-probe[3850]: checking bus 1, device 4: "/sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2"

Oct 01 08:46:52 micros mtp-probe[3850]: bus: 1, device: 4 was not an MTP device

Oct 01 08:46:54 micros ModemManager[643]: [base-manager] couldn't check support for device '/sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2': not supported by any plugin

* * *

**pi@micros** : **/dev/serial $** /dev/serial/by-id/ show  
-bash: /dev/serial/by-id/: Is a directory

but the by\_id folder does list usb-1a86\_USB\_Serial-if00-port0

* * *

1 Oct 09:07:34 - [info] Node-RED version: v4.0.3  
1 Oct 09:07:34 - [info] Node.js version: v20.17.0  
1 Oct 09:07:34 - [info] Linux 6.6.51+rpt-rpi-v8 arm64 LE  
1 Oct 09:07:34 - [info] Loading palette nodes  
1 Oct 09:07:35 - [info] Dashboard version 3.6.5 started at /ui  
1 Oct 09:07:36 - [info] Settings file : /home/pi/.node-red/settings.js  
1 Oct 09:07:36 - [info] Context store : 'default' [module=memory]  
1 Oct 09:07:36 - [info] User directory : /home/pi/.node-red  
1 Oct 09:07:36 - [warn] Projects disabled : editorTheme.projects.enabled=false  
1 Oct 09:07:36 - [info] Flows file : /home/pi/.node-red/flows.json  
1 Oct 09:07:36 - [info] Server now running at [http://127.0.0.1:1880/](http://127.0.0.1:1880/)  
1 Oct 09:07:36 - [warn] Using unencrypted credentials  
1 Oct 09:07:36 - [info] Starting flows  
1 Oct 09:07:36 - [warn] Unknown context store 'default' specified. Using default store.  
1 Oct 09:07:37 - [info] Started flows  
1 Oct 09:07:37 - [error] [serialconfig:fbc944192c31becd] serial port /dev/ttyusb0 error: Error: Error: No such file or directory, cannot open /dev/ttyusb0

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [1 October 2024 14:43 UTC](https://discourse.nodered.org/t/raspi-control-sainsmart-usb-connected-relay/92081/7 "2024-10-01T14:43:12Z")

</div>

> [@ryanprel](#):
>
> ch341-uart converter now attached to ttyUSB0

> [@ryanprel](#):
>
> 1 Oct 09:07:37 - [error] [serialconfig:fbc944192c31becd] serial port /dev/ttyusb0 error: Error: Error: No such file or directory, cannot open /dev/ttyusb0

This is LInux. Case matters.

> [@ryanprel](#):
>
> -bash: /dev/serial/by-id/: Is a directory

Sorry, I meant to say `ls -al /dev/serial/by-id`  
Since it does show the device you can use `/dev/serial/by-id/usb-1a86_USB_Serial-if00-port0` instead of `/dev/ttyUSB0`. That has the advantage that it will not change if the OS decides today to mount it as `/dev/ttyUSB1`, which is quite possible.

---

<div class="post-metadata">

**Author:** ![ryanprel](https://avatars.discourse-cdn.com/v4/letter/r/7c8e57/32.png) [@ryanprel](https://discourse.nodered.org/u/ryanprel)\
**Post date:** [1 October 2024 17:21 UTC](https://discourse.nodered.org/t/raspi-control-sainsmart-usb-connected-relay/92081/8 "2024-10-01T17:21:10Z")

</div>

Alright, It appears that I'm connected to that serial port.

 ![Screenshot 2024-10-01 at 11.03.59 AM](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/1/1/11d85b99fafc4a98aa42dc80009cc2ce35cd67a4.png)

Now I'm trying to figure out how to actually send commands and request relay status from the device. Any ideas on example flows out there that are similar?

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [1 October 2024 20:22 UTC](https://discourse.nodered.org/t/raspi-control-sainsmart-usb-connected-relay/92081/9 "2024-10-01T20:22:55Z")

</div>

> [@ryanprel](#):
>
> Now I'm trying to figure out how to actually send commands and request relay status

What exact messages do you need to send/receive?

---

<div class="post-metadata">

**Author:** ![ryanprel](https://avatars.discourse-cdn.com/v4/letter/r/7c8e57/32.png) [@ryanprel](https://discourse.nodered.org/u/ryanprel)\
**Post date:** [1 October 2024 22:57 UTC](https://discourse.nodered.org/t/raspi-control-sainsmart-usb-connected-relay/92081/10 "2024-10-01T22:57:41Z")

</div>

I'm utilizing this setup to turn on and off 16 individual peristaltic pumps using the relay to water a rack with 16 different microgreen trays for a commercial restaurant. These get watered on a set schedule multiple times a day with varying amounts of water. What I need to do with the relay is just be able to send power-on and power-off signals to each individual relay based on whether or not there is a tray in that slot.

Below is the flow I'm using for one individual slot on the relay. Because of the unreliability I was occasionally having with the Denkovi Wifi relay, I had a 2nd and 3rd turn off signal being sent on a delay to make sure the pumps turn off. None of that's important, just notes for anyone else looking at the flow.

 ![Screenshot 2024-10-01 at 5.58.14 PM](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/4/b/4b340db5db375e50d8757d5faf2602217d69f806.png)

```auto
[
    {
        "id": "0923e25dcc8f66ee",
        "type": "delay",
        "z": "4d39bd7ab87afe9a",
        "name": "",
        "pauseType": "delay",
        "timeout": "5",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 740,
        "y": 100,
        "wires": [
            [
                "cbe4087d2441c349",
                "271c44eaa54985e6"
            ]
        ]
    },
    {
        "id": "0e9d7eae1b870f33",
        "type": "delay",
        "z": "4d39bd7ab87afe9a",
        "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,
        "x": 740,
        "y": 140,
        "wires": [
            [
                "cbe4087d2441c349",
                "271c44eaa54985e6"
            ]
        ]
    },
    {
        "id": "271c44eaa54985e6",
        "type": "debug",
        "z": "4d39bd7ab87afe9a",
        "name": "Backup P1",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 930,
        "y": 140,
        "wires": []
    },
    {
        "id": "cbe4087d2441c349",
        "type": "tcp request",
        "z": "4d39bd7ab87afe9a",
        "name": "",
        "server": "192.168.2.17",
        "port": "8899",
        "out": "time",
        "ret": "buffer",
        "splitc": "0",
        "newline": "",
        "trim": false,
        "tls": "",
        "x": 940,
        "y": 80,
        "wires": [
            []
        ]
    },
    {
        "id": "aca132168538208f",
        "type": "function",
        "z": "4d39bd7ab87afe9a",
        "name": "Send Dose",
        "func": "msg.payload = \"01+//\";\nsetTimeout(() => {\n node.send([{payload: \"01-//\"}, {payload: \"01-//\"}]);\n}, flow.get(\"DoseTimeP1\") * 1000);\nreturn [msg, null];",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 470,
        "y": 80,
        "wires": [
            [
                "e1216a4118849adc",
                "cbe4087d2441c349",
                "60ec51f67c6ef72e"
            ]
        ]
    },
    {
        "id": "15ea8fa8f389eb9d",
        "type": "function",
        "z": "4d39bd7ab87afe9a",
        "name": "set_global_DoseTime",
        "func": "global.set(\"DoseTimeP1\",msg.payload)\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 280,
        "y": 140,
        "wires": [
            [
                "46ec7d208d525083"
            ]
        ]
    },
    {
        "id": "46ec7d208d525083",
        "type": "change",
        "z": "4d39bd7ab87afe9a",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "DoseTimeP1",
                "pt": "flow",
                "to": "payload",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 500,
        "y": 140,
        "wires": [
            []
        ]
    },
    {
        "id": "b03bf6155f607823",
        "type": "inject",
        "z": "4d39bd7ab87afe9a",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "str",
        "x": 310,
        "y": 40,
        "wires": [
            [
                "e39e566a7f7e8e14"
            ]
        ]
    },
    {
        "id": "e1216a4118849adc",
        "type": "debug",
        "z": "4d39bd7ab87afe9a",
        "name": "Primary P1",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 630,
        "y": 60,
        "wires": []
    },
    {
        "id": "60ec51f67c6ef72e",
        "type": "switch",
        "z": "4d39bd7ab87afe9a",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "01-//",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 610,
        "y": 100,
        "wires": [
            [
                "0e9d7eae1b870f33",
                "0923e25dcc8f66ee"
            ]
        ]
    },
    {
        "id": "b9b78ee5bd94ab4a",
        "type": "ui_switch",
        "z": "4d39bd7ab87afe9a",
        "name": "Off/On",
        "label": "Off/On",
        "tooltip": "",
        "group": "8681125fd492334c",
        "order": 1,
        "width": 0,
        "height": 0,
        "passthru": true,
        "decouple": "false",
        "topic": "control",
        "topicType": "str",
        "style": "",
        "onvalue": "open",
        "onvalueType": "str",
        "onicon": "",
        "oncolor": "",
        "offvalue": "close",
        "offvalueType": "str",
        "officon": "",
        "offcolor": "",
        "animate": false,
        "className": "",
        "x": 70,
        "y": 40,
        "wires": [
            [
                "e39e566a7f7e8e14"
            ]
        ]
    },
    {
        "id": "a53ee1e99199fb08",
        "type": "ui_numeric",
        "z": "4d39bd7ab87afe9a",
        "name": "",
        "label": "Dosing Time",
        "tooltip": "",
        "group": "8681125fd492334c",
        "order": 2,
        "width": 5,
        "height": 1,
        "wrap": false,
        "passthru": true,
        "topic": "topic",
        "topicType": "msg",
        "format": "{{value}}",
        "min": "0",
        "max": "260000",
        "step": "10",
        "className": "",
        "x": 90,
        "y": 140,
        "wires": [
            [
                "15ea8fa8f389eb9d"
            ]
        ]
    },
    {
        "id": "e39e566a7f7e8e14",
        "type": "gate",
        "z": "4d39bd7ab87afe9a",
        "name": "Pump Gate",
        "controlTopic": "control",
        "defaultState": "closed",
        "openCmd": "Open",
        "closeCmd": "Close",
        "toggleCmd": "toggle",
        "defaultCmd": "default",
        "statusCmd": "status",
        "persist": true,
        "storeName": "memory",
        "x": 310,
        "y": 80,
        "wires": [
            [
                "aca132168538208f"
            ]
        ]
    },
    {
        "id": "fe50969e5b62c435",
        "type": "chronos-scheduler",
        "z": "4d39bd7ab87afe9a",
        "name": "Pump 1 Schedule",
        "config": "dbcf10fd9c32cebf",
        "schedule": [
            {
                "trigger": {
                    "type": "time",
                    "value": "1:00",
                    "offset": 0,
                    "random": false
                },
                "output": {
                    "type": "msg",
                    "property": {
                        "name": "payload",
                        "type": "str",
                        "value": ""
                    }
                }
            },
            {
                "trigger": {
                    "type": "time",
                    "value": "9:00",
                    "offset": 0,
                    "random": false
                },
                "output": {
                    "type": "msg",
                    "property": {
                        "name": "payload",
                        "type": "str",
                        "value": ""
                    }
                }
            },
            {
                "trigger": {
                    "type": "time",
                    "value": "16:00",
                    "offset": 0,
                    "random": false
                },
                "output": {
                    "type": "msg",
                    "property": {
                        "name": "payload",
                        "type": "str",
                        "value": ""
                    }
                }
            }
        ],
        "disabled": false,
        "multiPort": false,
        "nextEventPort": false,
        "delayOnStart": true,
        "onStartDelay": "",
        "outputs": 1,
        "x": 110,
        "y": 80,
        "wires": [
            [
                "e39e566a7f7e8e14"
            ]
        ]
    },
    {
        "id": "8681125fd492334c",
        "type": "ui_group",
        "name": "Pump 1",
        "tab": "168c1349c26582fe",
        "order": 1,
        "disp": true,
        "width": "6",
        "collapse": false,
        "className": ""
    },
    {
        "id": "dbcf10fd9c32cebf",
        "type": "chronos-config",
        "name": "Ripon",
        "latitudeType": "num",
        "longitudeType": "num",
        "timezone": "",
        "sunPositions": []
    },
    {
        "id": "168c1349c26582fe",
        "type": "ui_tab",
        "name": "Scheduler",
        "icon": "dashboard",
        "order": 1,
        "disabled": false,
        "hidden": false
    }
]

```

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [2 October 2024 08:13 UTC](https://discourse.nodered.org/t/raspi-control-sainsmart-usb-connected-relay/92081/11 "2024-10-02T08:13:07Z")

</div>

It is not clear to me whether you still have a problem. If you do then what is it?

---

<div class="post-metadata">

**Author:** ![ryanprel](https://avatars.discourse-cdn.com/v4/letter/r/7c8e57/32.png) [@ryanprel](https://discourse.nodered.org/u/ryanprel)\
**Post date:** [2 October 2024 18:59 UTC](https://discourse.nodered.org/t/raspi-control-sainsmart-usb-connected-relay/92081/12 "2024-10-02T18:59:28Z")

</div>

What I'm trying to figure out is what commands to send via a serial node that will turn on and off the relays. The below screenshots are in the documentation but getting this into a usable format that will enable or disable a relay is my challenge.

 ![Screenshot 2024-10-02 at 1.54.57 PM](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/7/8/78f5c3739d9628a6e3e811cf6451ffd1d0f9a457.png)

 ![Screenshot 2024-10-02 at 1.55.25 PM](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/0/2/02589599ffc56afdf9e6c03de7ea587f11a93182.png)

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [2 October 2024 20:28 UTC](https://discourse.nodered.org/t/raspi-control-sainsmart-usb-connected-relay/92081/13 "2024-10-02T20:28:43Z")

</div>

I have not used the serial port to send binary data, but at a guess something like this in a function node, sent to a serial out node should work to, for example, switch channel 2 on

```auto
msg.payload = Buffer.from([0x3a, 0x46, 0x45, ....., 0x0d, 0x0a])
return msg;

```

With the rest filled in obviously.

---

<div class="post-metadata">

**Author:** ![ryanprel](https://avatars.discourse-cdn.com/v4/letter/r/7c8e57/32.png) [@ryanprel](https://discourse.nodered.org/u/ryanprel)\
**Post date:** [14 October 2024 19:57 UTC](https://discourse.nodered.org/t/raspi-control-sainsmart-usb-connected-relay/92081/14 "2024-10-14T19:57:36Z")

</div>

Alright, I have everything working properly with this thanks to Colin's help. Below are the on and off codes for each channel and below that is a an example flow for turning on and off each of the relays manually with a dashboard2 switch. Hope this helps someone else that won't need to go digging for the info!

```auto
1-CH ON 0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x30, 0x46, 0x46, 0x30, 0x30, 0x46, 0x45, 0x0D, 0x0A
1-CH OFF	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x46, 0x44, 0x0D, 0x0A
2-CH ON 0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x31, 0x46, 0x46, 0x30, 0x30, 0x46, 0x44, 0x0D, 0x0A
2-CH OFF	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x46, 0x43, 0x0D, 0x0A
3-CH ON 0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x32, 0x46, 0x46, 0x30, 0x30, 0x46, 0x43, 0x0D, 0x0A
3-CH OFF	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x46, 0x42, 0x0D, 0x0A
4-CH ON 0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x33, 0x46, 0x46, 0x30, 0x30, 0x46, 0x42, 0x0D, 0x0A
4-CH OFF	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, 0x46, 0x41, 0x0D, 0x0A
5-CH ON 0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x34, 0x46, 0x46, 0x30, 0x30, 0x46, 0x41, 0x0D, 0x0A
5-CH OFF	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x46, 0x39, 0x0D, 0x0A
6-CH ON 0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x35, 0x46, 0x46, 0x30, 0x30, 0x46, 0x39, 0x0D, 0x0A
6-CH OFF	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x35, 0x30, 0x30, 0x30, 0x30, 0x46, 0x38, 0x0D, 0x0A
7-CH ON 0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x36, 0x46, 0x46, 0x30, 0x30, 0x46, 0x38, 0x0D, 0x0A
7-CH OFF	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x46, 0x37, 0x0D, 0x0A
8-CH ON 0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x37, 0x46, 0x46, 0x30, 0x30, 0x46, 0x37, 0x0D, 0x0A
8-CH OFF	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x46, 0x36, 0x0D, 0x0A
9-CH ON 0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x38, 0x46, 0x46, 0x30, 0x30, 0x46, 0x36, 0x0D, 0x0A
9-CH OFF	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x38, 0x30, 0x30, 0x30, 0x30, 0x46, 0x35, 0x0D, 0x0A
10-CH ON	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x39, 0x46, 0x46, 0x30, 0x30, 0x46, 0x35, 0x0D, 0x0A
10-CH OFF	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x46, 0x34, 0x0D, 0x0A
11-CH ON	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x41, 0x46, 0x46, 0x30, 0x30, 0x46, 0x34, 0x0D, 0x0A
11-CH OFF	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x41, 0x30, 0x30, 0x30, 0x30, 0x46, 0x33, 0x0D, 0x0A
12-CH ON	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x42, 0x46, 0x46, 0x30, 0x30, 0x46, 0x33, 0x0D, 0x0A
12-CH OFF	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x42, 0x30, 0x30, 0x30, 0x30, 0x46, 0x32, 0x0D, 0x0A
13-CH ON	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x43, 0x46, 0x46, 0x30, 0x30, 0x46, 0x32, 0x0D, 0x0A
13-CH OFF	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x43, 0x30, 0x30, 0x30, 0x30, 0x46, 0x31, 0x0D, 0x0A
14-CH ON	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x44, 0x46, 0x46, 0x30, 0x30, 0x46, 0x31, 0x0D, 0x0A
14-CH OFF	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x44, 0x30, 0x30, 0x30, 0x30, 0x46, 0x30, 0x0D, 0x0A
15-CH ON	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x45, 0x46, 0x46, 0x30, 0x30, 0x46, 0x30, 0x0D, 0x0A
15-CH OFF	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x45, 0x30, 0x30, 0x30, 0x30, 0x46, 0x46, 0x0D, 0x0A
16-CH ON	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x46, 0x46, 0x46, 0x30, 0x30, 0x46, 0x46, 0x0D, 0x0A
16-CH OFF	0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x46, 0x30, 0x30, 0x30, 0x30, 0x46, 0x45, 0x0D, 0x0A

```

---

<div class="post-metadata">

**Author:** ![ryanprel](https://avatars.discourse-cdn.com/v4/letter/r/7c8e57/32.png) [@ryanprel](https://discourse.nodered.org/u/ryanprel)\
**Post date:** [14 October 2024 19:59 UTC](https://discourse.nodered.org/t/raspi-control-sainsmart-usb-connected-relay/92081/15 "2024-10-14T19:59:16Z")

</div>

Here's an example of the codes being used.

 ![Screenshot 2024-10-14 at 2.55.56 PM](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/d/8/d8619acea43899236fdfb0c7a2fc966991a1789c.jpeg)

```auto
[
    {
        "id": "f66b20f60f744ad7",
        "type": "serial out",
        "z": "25fbcd3ade1c5a77",
        "name": "",
        "serial": "fbc944192c31becd",
        "x": 550,
        "y": 200,
        "wires": []
    },
    {
        "id": "5bd70fb56e717727",
        "type": "function",
        "z": "25fbcd3ade1c5a77",
        "name": "Relay On",
        "func": "msg.payload = Buffer.from([0x3A, 0x46, 0x45, 0x30, 0x35, 0x30, 0x30, 0x30, 0x30, 0x46, 0x46, 0x30, 0x30, 0x46, 0x45, 0x0D, 0x0A]);\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 400,
        "y": 180,
        "wires": [
            [
                "f66b20f60f744ad7"
            ]
        ]
    },
    {
        "id": "94bec453560a6e9e",
        "type": "function",
        "z": "25fbcd3ade1c5a77",
        "name": "Relay Off",
        "func": "msg.payload = Buffer.from([0x3A, 0x46, 0x45, 0x30,\t0x35, 0x30,\t0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x46, 0x44, 0x0D, 0x0A]);\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 400,
        "y": 220,
        "wires": [
            [
                "f66b20f60f744ad7"
            ]
        ]
    },
    {
        "id": "146ed2da77f78dee",
        "type": "ui-switch",
        "z": "25fbcd3ade1c5a77",
        "name": "Pump 1 Switch",
        "label": "Pump 1",
        "group": "c3f78cbf06978574",
        "order": 1,
        "width": 0,
        "height": 0,
        "passthru": false,
        "decouple": false,
        "topic": "topic",
        "topicType": "msg",
        "style": "",
        "className": "",
        "clickableArea": "switch",
        "onvalue": "true",
        "onvalueType": "bool",
        "onicon": "",
        "oncolor": "",
        "offvalue": "false",
        "offvalueType": "bool",
        "officon": "",
        "offcolor": "",
        "x": 100,
        "y": 200,
        "wires": [
            [
                "223fb90ca608be30"
            ]
        ]
    },
    {
        "id": "223fb90ca608be30",
        "type": "switch",
        "z": "25fbcd3ade1c5a77",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "true"
            },
            {
                "t": "false"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 250,
        "y": 200,
        "wires": [
            [
                "5bd70fb56e717727"
            ],
            [
                "94bec453560a6e9e"
            ]
        ]
    },
    {
        "id": "fbc944192c31becd",
        "type": "serial-port",
        "name": "Relay",
        "serialport": "/dev/serial/by-id/usb-1a86_USB_Serial-if00-port0",
        "serialbaud": "9600",
        "databits": "8",
        "parity": "none",
        "stopbits": "1",
        "waitfor": "",
        "dtr": "none",
        "rts": "none",
        "cts": "none",
        "dsr": "none",
        "newline": "\\n",
        "bin": "false",
        "out": "char",
        "addchar": "",
        "responsetimeout": "10000"
    },
    {
        "id": "c3f78cbf06978574",
        "type": "ui-group",
        "name": "Manual Control",
        "page": "6dc2b8605bdfa521",
        "width": "2",
        "height": "1",
        "order": 1,
        "showTitle": true,
        "className": "",
        "visible": "true",
        "disabled": "false"
    },
    {
        "id": "6dc2b8605bdfa521",
        "type": "ui-page",
        "name": "Manual",
        "ui": "96a33ff7e334bb72",
        "path": "/manual",
        "icon": "home",
        "layout": "grid",
        "theme": "e80f2e3f89e4d55f",
        "breakpoints": [
            {
                "name": "Default",
                "px": "0",
                "cols": "3"
            },
            {
                "name": "Tablet",
                "px": "576",
                "cols": "6"
            },
            {
                "name": "Small Desktop",
                "px": "768",
                "cols": "9"
            },
            {
                "name": "Desktop",
                "px": "1024",
                "cols": "12"
            }
        ],
        "order": 1,
        "className": "",
        "visible": "true",
        "disabled": "false"
    },
    {
        "id": "96a33ff7e334bb72",
        "type": "ui-base",
        "name": "Micros",
        "path": "/dashboard",
        "includeClientData": true,
        "acceptsClientConfig": [
            "ui-notification",
            "ui-control"
        ],
        "showPathInSidebar": false,
        "showPageTitle": true,
        "navigationStyle": "default",
        "titleBarStyle": "default"
    },
    {
        "id": "e80f2e3f89e4d55f",
        "type": "ui-theme",
        "name": "Default",
        "colors": {
            "surface": "#ffffff",
            "primary": "#0094ce",
            "bgPage": "#eeeeee",
            "groupBg": "#ffffff",
            "groupOutline": "#cccccc"
        },
        "sizes": {
            "density": "default",
            "pagePadding": "12px",
            "groupGap": "12px",
            "groupBorderRadius": "4px",
            "widgetGap": "12px"
        }
    }
]

```

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [28 October 2024 19:59 UTC](https://discourse.nodered.org/t/raspi-control-sainsmart-usb-connected-relay/92081/16 "2024-10-28T19:59:36Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
