Saturday, April 24, 2021

Simple MQTT handler in bash

How to subscribe to an MQTT topic efficiently in bash.

This is hosted on a Raspberry Pi which controls a pool pump via a solid state relay on GPIO 4, and these topics :

  • /pool/pump/action 0  # Command, set externally (subscribed)
  • /pool/pump/state  1  # Feedback state (published)


''

#!/bin/bash -feu
set -o pipefail

mqtt()
{
action="$1"
shift
"mosquitto_${action}" -h 192.168.1.1 -p 8833 -t "$@"
}

handler()
{
new_state=$(echo "$1" | sed 's/[^01]//g')
[[ -z "$new_state" ]] && new_state="0"

if /usr/local/bin/gpio_out.sh 4 "$new_state"; then
echo "pump state change OK, now $new_state"
else
echo "ERROR: pump state change fail towards $new_state"
fi

# Ping back
real_state=$(cat /sys/class/gpio/gpio4/value)
mqtt pub '/pool/pump/state' -m "$real_state" -r
}

export -f mqtt
export -f handler


action={1-}
cfg=$(basename $0 .sh).service
if [[ $action = 'stop' ]]; then
systemctl stop $cfg

elif [[ $action = 'start' ]]; then
systemctl restart $cfg

elif [[ $action = 'install' ]]; then

cat > /etc/systemd/system/$cfg << EOF
[Install]
WantedBy=multi-user.target
[Service]
Restart=always
RestartSec=3
ExecStart=$(realpath $0)
#Type=simple
#Restart=on-failure
EOF

systemctl daemon-reload &&
systemctl restart $cfg &&
systemctl enable $cfg

else # here is the deal

# Run only once
LOCK_FILE="/var/lock/$(basename $0 .sh).lock"
exec 9> "$LOCK_FILE" && flock -n 9 || exit 5
trap "rm -f '$LOCK_FILE'; logger 'Stopped $0 watcher on $(date)'" EXIT
logger "Started $0 watcher on $(date)"

# Wait for orders
mqtt sub '/pool/pump/action' |\
xargs -n 1 -I {} /bin/bash -c 'handler "$@"' _ {}

fi

''

This small script embeds its own ''systemd'' config, just run it with ''install' as the sole parameter.

Wednesday, March 3, 2021

Install CH552 support for platformio (and CH5xx variants) with ch5xduino support

https://community.platformio.org/t/platformio-8051-model-medium-linker-err/18099

''
mkdir ~/.platformio/boards
cd ~/.platformio/boards
cat > ch55xduino.json << 'EOF'
{
  "build": {    
    "f_cpu": "24000000",
    "size_iram": 256,
    "size_xram": 1024,
    "size_code": 14336,
    "size_heap": 128,
    "mcu": "ch552t",
    "cpu": "mcs51"
  },
  "frameworks": [],
  "upload": {
    "maximum_ram_size": 1280,
    "maximum_size": 14336,
    "protocol": "stcgal",
    "stcgal_protocol": "stc15",
    "protocols": [
      "stcgal"
    ]
  },
  "name": "Generic CH552",
  "url": "http://www.wch.cn/product/CH552.html",
  "vendor": "WCH"
}
EOF

platformio boards|grep ch5xduino
cd
mkdir myproj552
cd myproj552
platformio init --board ch55xduino

cat > platformio.ini <<'EOF'
[env:ch552]
platform = intel_mcs51
board = ch552
build_flags =
  --model-medium
  --LC:/Users/caoyf/.platformio/packages/toolchain-sdcc/lib/medium
  -IC:
  -IC:/Users/caoyf/Documents/PlatformIO/Projects/ch552_gpio/src/Driver/inc
  -Isrc/PLAT/inc

extra_scripts = link_medium.py
'EOF'

cat > link_medium.py
Import("env")
env.Append(LINKFLAGS=["--model-medium"])

''