Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[workaround] Docker Stack device mapping #2049

Closed
RaymondMouthaan opened this issue Sep 29, 2019 · 2 comments
Closed

[workaround] Docker Stack device mapping #2049

RaymondMouthaan opened this issue Sep 29, 2019 · 2 comments

Comments

@RaymondMouthaan
Copy link
Contributor

RaymondMouthaan commented Sep 29, 2019

Hi,

This is not an error report, but a workaround for running zigbee2mqtt in a Docker Swarm environment using the docker stack command and might be considered to be added to the zigbee2mqtt documentation.

Greets,
Ray


Docker Stack device mapping workaround

Docker stack doesn't support device mappings with option --devices when deploying a stack in Swam mode. A workaround is to bind the device as volume binding and set the right permissions.

The workaround is based on the solution found at Add support for devices with "service create", all credits goes this him.

  1. Identify cc2531 device
    Identify the cc2531 device using the following command:

    sudo lsusb -v
    Bus 001 Device 005: ID 0451:16a8 Texas Instruments, Inc.
    Device Descriptor:
      bLength                18
      bDescriptorType         1
      bcdUSB               2.00
      bDeviceClass            2 Communications
      bDeviceSubClass         0 
      bDeviceProtocol         0 
      bMaxPacketSize0        32
      idVendor           0x0451 Texas Instruments, Inc.
      idProduct          0x16a8 
      bcdDevice            0.09
      iManufacturer           1 Texas Instruments
      iProduct                2 TI CC2531 USB CDC
      iSerial                 3 __0X00124B001936AC60
      bNumConfigurations      1
      Configuration Descriptor:
    	bLength                 9
    	bDescriptorType         2
    	wTotalLength           67
    	bNumInterfaces          2
    	bConfigurationValue     1
    	iConfiguration          0 
    	bmAttributes         0x80
    	  (Bus Powered)
    	MaxPower               50mA
    	Interface Descriptor:
    	  bLength                 9
    	  bDescriptorType         4
    	  bInterfaceNumber        0
    	  bAlternateSetting       0
    	  bNumEndpoints           1
    	  bInterfaceClass         2 Communications
    	  bInterfaceSubClass      2 Abstract (modem)
    	  bInterfaceProtocol      1 AT-commands (v.25ter)
    	  iInterface              0 
    	  CDC Header:
    		bcdCDC               1.10
    	  CDC ACM:
    		bmCapabilities       0x02
    		  line coding and serial state
    	  CDC Union:
    		bMasterInterface        0
    		bSlaveInterface         1 
    	  CDC Call Management:
    		bmCapabilities       0x00
    		bDataInterface          1
    	  Endpoint Descriptor:
    		bLength                 7
    		bDescriptorType         5
    		bEndpointAddress     0x82  EP 2 IN
    		bmAttributes            3
    		  Transfer Type            Interrupt
    		  Synch Type               None
    		  Usage Type               Data
    		wMaxPacketSize     0x0040  1x 64 bytes
    		bInterval              64
    	Interface Descriptor:
    	  bLength                 9
    	  bDescriptorType         4
    	  bInterfaceNumber        1
    	  bAlternateSetting       0
    	  bNumEndpoints           2
    	  bInterfaceClass        10 CDC Data
    	  bInterfaceSubClass      0 Unused
    	  bInterfaceProtocol      0 
    	  iInterface              0 
    	  Endpoint Descriptor:
    		bLength                 7
    		bDescriptorType         5
    		bEndpointAddress     0x84  EP 4 IN
    		bmAttributes            2
    		  Transfer Type            Bulk
    		  Synch Type               None
    		  Usage Type               Data
    		wMaxPacketSize     0x0040  1x 64 bytes
    		bInterval               0
    	  Endpoint Descriptor:
    		bLength                 7
    		bDescriptorType         5
    		bEndpointAddress     0x04  EP 4 OUT
    		bmAttributes            2
    		  Transfer Type            Bulk
    		  Synch Type               None
    		  Usage Type               Data
    		wMaxPacketSize     0x0040  1x 64 bytes
    		bInterval               0
    Device Status:     0x0000
      (Bus Powered)
    
  2. UDEV Rules

    Create a new udev rule for cc2531, idVendor and idProduct must be equal to values from lsusb command. The rule below creates device /dev/cc2531:

    echo "SUBSYSTEM==\"tty\", ATTRS{idVendor}==\"0451\", ATTRS{idProduct}==\"16a8\", SYMLINK+=\"cc2531\",  RUN+=\"/usr/local/bin/docker-setup-cc2531.sh\"" | sudo tee /etc/udev/rules.d/99-cc2531.rules

    Reload newly created rule using the following command:

    sudo udevadm control --reload-rules
  3. Create docker-setup-cc2531.sh

    sudo nano /usr/local/bin/docker-setup-cc2531.sh

    Copy the following content:

    #!/bin/bash
    USBDEV=`readlink -f /dev/cc2531`
    read minor major < <(stat -c '%T %t' $USBDEV)
    if [[ -z $minor || -z $major ]]; then
    	echo 'Device not found'
    	exit
    fi
    dminor=$((0x${minor}))
    dmajor=$((0x${major}))
    CID=`docker ps -a --no-trunc | grep koenkk/zigbee2mqtt | head -1 |  awk '{print $1}'`
    if [[ -z $CID ]]; then
    	echo 'CID not found'
    	exit
    fi
    echo 'Setting permissions'
    echo "c $dmajor:$dminor rwm" > /sys/fs/cgroup/devices/docker/$CID/devices.allow

    Set permissions:

    sudo chmod 644 /usr/local/bin/docker-setup-cc2531.sh
  4. Create docker-event-listener.sh

    sudo nano /usr/local/bin/docker-event-listener.sh

    Copy the following content:

    #!/bin/bash
    docker events --filter 'event=start'| \
    while read line; do
    	/usr/local/bin/docker-setup-cc2531.sh

    Set permissions:

    sudo chmod 644 /usr/local/bin/docker-event-listener.sh
  5. Create docker-event-listener.service

    sudo nano /etc/systemd/system/docker-event-listener.service

    Copy the following content:

    [Unit]
    Description=Docker Event Listener for TI CC2531 device
    After=network.target
    StartLimitIntervalSec=0
    [Service]
    Type=simple
    Restart=always
    RestartSec=1
    User=root
    ExecStart=/bin/bash /usr/local/bin/docker-event-listener.sh
    
    [Install]
    WantedBy=multi-user.target

    Set permissions:

    sudo chmod 644 /etc/systemd/system/docker-event-listener.service

    Reload daemon

    sudo systemctl daemon-reload

    Start Docker event listener

    sudo systemctl start docker-event-listener.service

    Status Docker event listener

    sudo systemctl status docker-event-listener.service

    Enable Docker event listener

    sudo systemctl enable docker-event-listener.service
  6. Verify and deploy Zigbee2Mqtt stack

    Now reconnect the cc2531. Verify using the following command:

    ls -al /dev/cc2531
    lrwxrwxrwx 1 root root 7 Sep 28 21:14 /dev/cc2531 -> ttyACM0

    Below an example of a docker-stack-zigbee2mqtt.yml:

    version: "3.7"
    services:
      zigbee2mqtt:
    	image: koenkk/zigbee2mqtt:latest-dev
    	environment:
    	  - TZ=Europe/Amsterdam
    	volumes:
    	  - /mnt/docker-cluster/zigbee2mqtt/data:/app/data
    	  - /dev/cc2531:/dev/cc2531
    	networks:
    	  - proxy_traefik-net
    	deploy:
    	  placement:
    		constraints: [node.hostname == rpi-3]
    	  replicas: 1
    
    networks:
      proxy_traefik-net:
    	external: true

    In the above example, proxy_traefik-net is the network to connect to the mqtt broker. The constraint makes sure Docker deploys only to this (rpi-3) node, where the cc2531 is connected to. The volume binding /mnt/docker-cluster/zigbee2mqtt/data is the zigbee2mqtt persistent directory, where configuration.yaml is saved.

    The zigbee2mqtt configuration.yaml should point to /dev/cc2531:

    [...]
    serial:
      port: /dev/cc2531
    [...]

    Deploy the stack:

    docker stack deploy zigbee2mqtt --compose-file docker-stack-zigbee2mqtt.yml
@Koenkk
Copy link
Owner

Koenkk commented Sep 29, 2019

@RaymondMouthaan
Copy link
Contributor Author

Sure, please find it under #119

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants