deCONZ VNC access without full blown Xorg install

deCONZ / Phoscon-GW recommends a full blown Xorg install on a Raspberry Pi to access their GUI. deCONZ is a utility to work with Zigbee controller provided by Raspbee / Conbee. deCONZ GUI provides more advanced control of Zigbee devices, and has functionality that is not available via web interface/REST API.

No need to install a full blown UI if you want to run headless. These instructions are for Raspbian.

Make sure to disable and stop existing deconz services if enabled:

systemctl disable deconz
systemctl stop deconz

You may also have deconz-gui service if you have followed their install guide, so make sure to disable and stop this as well if applicable.

Install TigerVNC which we will use to provide headless VNC access to the GUI:

apt-get install tigervnc-standalone-server

You will create a new systemd service definition, which is outlined below .

/etc/systemd/system/deconz-vnc.service

[Unit]
Description=deCONZ: ZigBee gateway -- GUI/REST API VNC
Wants=deconz-init.service deconz-update.service

[Service]
User=1000
Environment="DISPLAY=:0"
ExecStartPre=/usr/bin/tigervncserver -geometry 1024x768 -useold -SecurityTypes None -localhost yes -noxstartup "$DISPLAY"
ExecStart=/usr/bin/deCONZ --http-port=80
Restart=on-failure
StartLimitIntervalSec=0
RestartSec=30
AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_KILL CAP_SYS_BOOT CAP_SYS_TIME

[Install]
WantedBy=multi-user.target

Then reload systemd, enable and start the newly created service:

systemctl daemon-reload
systemctl enable deconz-vnc
systemctl start deconz-vnc

Once this is done you can setup a SSH port forward to localhost:5900 and access deCONZ GUI using your favourite VNC viewer.

Home Assistant sensors and CyberPower UPS via RMCARD205

RMCARD205 supplies metrics via SNMP for all supported CyberPower UPS. Who doesn't want to display power usage on their UPS via Home Assistant?

Lovelace card for CyberPower UPS

I created a "package" for CyberPower UPS RMCARD that exports data via SNMP. This assumes your default read-only community is named public.

packages/ups.yaml:

sensor:
  - platform: snmp
    scan_interval: 60
    name: ups_nompower
    host: x.x.x.x
    baseoid: 1.3.6.1.4.1.3808.1.1.1.4.2.5.0
    accept_errors: true
    unit_of_measurement: Watts
  - platform: snmp
    scan_interval: 60
    name: ups_nominv
    host: x.x.x.x
    baseoid: 1.3.6.1.4.1.3808.1.1.1.3.2.1.0
    accept_errors: true
    unit_of_measurement: Volts
    value_template: '{{((value | int) / 10) | int}}'
  - platform: snmp
    scan_interval: 60
    name: ups_itemp
    host: x.x.x.x
    baseoid: 1.3.6.1.4.1.3808.1.1.1.2.2.3.0
    accept_errors: true
    unit_of_measurement: "°C"
  - platform: snmp
    scan_interval: 60
    name: ups_timeleft
    host: x.x.x.x
    baseoid: 1.3.6.1.4.1.3808.1.1.1.2.2.4.0
    accept_errors: true
    unit_of_measurement: 'minutes'
    value_template: '{{((value | int) / 6000) | int}}'
  - platform: snmp
    scan_interval: 30
    name: ups_status
    host: x.x.x.x
    baseoid: 1.3.6.1.4.1.3808.1.1.1.4.1.1.0
    accept_errors: true
    value_template: >-
      {% set status = (value | int) %}
      {%- if status == 2 -%}
      Online
      {%- elif status ==  3 -%}
      On Battery
      {%- elif status ==  4 -%}
      On Boost
      {%- elif status ==  5 -%}
      On Sleep
      {%- elif status ==  6 -%}
      Off
      {%- elif status ==  7 -%}
      Rebooting
      {%- elif status ==  8 -%}
      On ECO
      {%- elif status ==  9 -%}
      On Bypass
      {%- elif status ==  10 -%}
      On Buck
      {%- elif status ==  11 -%}
      On Overload
      {%- else -%}
      Unknown
      {%- endif -%}
      
group:
  ups:
    name: UPS
    entities:
      - sensor.ups_status
      - sensor.ups_nompower
      - sensor.ups_nominv
      - sensor.ups_itemp
      - sensor.ups_timeleft

homeassistant:
  customize:
    sensor.ups_nompower:
      friendly_name: 'UPS Nominal Output Power'
      icon: mdi:flash
    sensor.ups_nominv:
      friendly_name: 'UPS Nominal Input Voltage'
      icon: mdi:flash
    sensor.ups_status:
      friendly_name: 'UPS Status'
      icon: mdi:information-outline
    sensor.ups_itemp:
      friendly_name: 'UPS Internal Temperature'
      icon: mdi:thermometer
    sensor.ups_timeleft:
      friendly_name: 'UPS Time Left'
      icon: mdi:clock-alert

prosody websocket behind nginx reverse proxy

Useful for kawai and other XMPP services behind the same URL (eg. for serving SSL traffic.)

WebSockets require HTTP/1.1, and prosody assumes traffic on TCP port 5280 is not secure (and trying to force it to starttls) thus requiring the configuration knob highlighted below.

prosody.cfg.lua

consider_websocket_secure = true

nginx.conf

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

server {
# ...
  location /xmpp-websocket {
    proxy_pass http://127.0.0.1:5280;
    proxy_buffering off;
    proxy_set_header Host $host;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
}

Boot LVM on mdraid (5, and others) on Ubuntu 14.04 on newer kernels

If you build a LVM mdraid5 on Ubuntu 14.04, and update the kernel you may be dropped into initramfs on reboot and be forced to manually activate the logical volumes on the volume group. This is due to a missing/incomplete udev rule for LVM which should be incorporated into initramfs.

/etc/udev/rules.d/85-lvm2.rules

# This file causes block devices with LVM signatures to be automatically
# added to their volume group.
# See udev(8) for syntax

SUBSYSTEM=="block", ACTION=="add|change", ENV{ID_TYPE}=="disk", \
        RUN+="watershed sh -c '/sbin/lvm vgscan; /sbin/lvm vgchange -a y'"

Once you have added this udev rule, you should update initramfs on your system:

update-initramfs -u -k all

If you need to activate the logical volume groups from initramfs, execute the following commands to boot the system:

lvm vgscan
lvm vgchange -a y
exit

QEMU agent for graceful shutdown of Windows guests under libvirt/qemu-kvm

libvirt sending an ACPI shutdown doesn't always prompt Windows guests to shutdown. That's why there is a QEMU guest agent (which is also handy for freezing/thawing guest file systems.) Installing QEMU guest agent will also cause libvirt to block on shutdown commands until the guest has terminated.

libvirt XML definition required

<channel type='unix'>
<target type='virtio' name='org.qemu.guest_agent.0'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>

You may also have to create /var/lib/libvirt/qemu/channel/target on the KVM host.

mkdir -p /var/lib/libvirt/qemu/channel/target
chown -R libvirt-qemu:kvm /var/lib/libvirt/qemu/channel/target

virtio-win drivers distributed by the Fedora Project contain the guest-agent and required virtioserial drivers for communication between guest and host and can be downloaded as an RPM package called virtio-win.

Once you have the RPM, you can either install it or convert it to a Debian package using alien. The ISO will be installed to /usr/share/virtio-win/virtio-win.iso and can be mounted in the guest.

virsh attach-disk GuestName /usr/share/virtio-win/virtio-win.iso hdc –type cdrom –mode readonly

Once you have restarted the guest with the XML definition changes, you can complete the following steps

  • Install virtioserial driver for PCI Simple Communication Controller under Device Manager, in the vioserial folder
  • Install the guest-agent located under the guest-agent folder for your architecture in the virtio-win ISO