#!/bin/sh set -e usage() { echo "usage: $0 [-h|--help] [-t ]" >&2 exit } die() { echo "error: $1" >&2 exit 1 } check_command() { if ! command -v "$1" >/dev/null; then die "$1 is not installed. Please install $1 to proceed." fi } parse_yaml() { if ! yaml_output=$(yq -r "$1" "$2" 2>/dev/null); then die "YAML file is malformed or does not exist." fi echo "$yaml_output" } for c in yq mosquitto_sub tput; do check_command $c; done [ -z "$1" ] && usage bold=$(tput bold) rst=$(tput sgr0) topic= while [ $# -gt 0 ]; do case "$1" in -h|--help) usage exit 0 ;; -t|--topic) topic="$2" shift ;; *) ;; esac shift done [ -z "$topic" ] && die "Topic not provided. Use -t or --topic to specify the topic." config_dirs="$HOME/.config/homekit /etc/homekit" config_file= for dir in $config_dirs; do if [ -f "$dir/mqtt.yaml" ]; then config_file="$dir/mqtt.yaml" break fi done [ -z "$config_file" ] && die "mqtt.yaml not found" yaml_data=$(parse_yaml "." "$config_file") required_fields=".remote_addr.host, .remote_addr.port, .default_client_creds, .creds" if ! echo "$yaml_data" | yq -e "$required_fields" >/dev/null; then die "YAML file is missing required fields." fi remote_host=$(echo "$yaml_data" | yq -r ".remote_addr.host") remote_port=$(echo "$yaml_data" | yq -r ".remote_addr.port") default_client_creds=$(echo "$yaml_data" | yq -r ".default_client_creds") username=$(echo "$yaml_data" | yq -r ".creds.$default_client_creds.username") password=$(echo "$yaml_data" | yq -r ".creds.$default_client_creds.password") homekit_dir="$(realpath "$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)/../")" cafile="$homekit_dir/misc/mqtt_ca.crt" topic_regex="${topic%#}" topic_regex="${topic_regex//\//\\/}" mosquitto_sub -h "$remote_host" -p "$remote_port" --cafile "$cafile" -t "$topic" -u "$username" -P "$password" -v | while IFS= read -r line; do binary_data="$(echo "$line" | sed "s/^${topic_regex}[^ ]* //")" echo -n "${bold}$(echo "$line" | awk '{print $1}')${rst}" echo -n " " echo -n "$binary_data" | xxd -p | tr -d '\n' | sed 's/../& /g' echo # echo done