Command line should probably work but I’m using a logic specific to “my” use case.
Let me explain
- I run the plcstat command and put info in a file devolo.network.
- Then, for each li,ne in the devolo.network file, I run the plctool command to get the userfriendly name.
- This allow me to detect one plug that was discovered in the past but did not popup in the plcstat command output:
a. in the output → online
b. not in the output → offline - Create the mqtt config topic
- Update state
- Update attributes (mac, type, rx, tx)
Here is the code without the mqtt part:(replaced by echo command)
#!/bin/bash
# Check if the interface parameter is provided
if [ $# -ne 1 ]; then
echo "Usage: $0 <interface>"
exit 1
fi
interface="$1"
# Look for PLC devices
plcstat_output=$(plcstat -t -i "$interface" | tail -n +2)
# Run plcstat to update devolo.network file
while IFS= read -r line; do
mac=$(echo "$line" | awk '{print $4}')
type=$(echo "$line" | awk '{print $1}')
plctool_output=$(plctool -I -i "$interface" "$mac")
# Extracting friendly_name from plctool output
friendly_name=$(echo "$plctool_output" | awk '/USR/ {print $2}')
# Check if friendly_name is empty or missing
if [ -z "$friendly_name" ]; then
friendly_name="$mac" # Use MAC as friendly_name
fi
# Append unique MAC addresses (excluding the first line) to the devolo.network file
# Create a temporary file
tmp_file=$(mktemp)
# Exclude the line containing the specific value and write the result to the temporary file
grep -v "$mac" devolo.network > "$tmp_file"
# Overwrite the original file with the modified content
mv "$tmp_file" devolo.network
# Append unique MAC addresses (excluding the first line) to the devolo.network file
echo "$mac $friendly_name $type" >> devolo.network
done <<< "$plcstat_output"
# Process the devolo.network file
while IFS=" " read -r mac friendly_name type; do
plctool_output=$(plctool -I -i "$interface" "$mac" 2>/dev/null)
# Extracting type, tx, and rx values from plcstat output
line=$(echo "$plcstat_output" | awk -v mac="$mac" '$0 ~ mac { print $0 }')
if [ -z "$line" ]; then
# Plug is offline
status="off"
else
# Plug is online
status="on"
read -r type _ _ _ _ tx rx _ <<< "$line"
fi
# Generate sensor name by removing unauthorized characters from friendly_name
sensor_name=$(echo "$friendly_name" | tr -cd '[:alnum:]-_')
# Create the JSON payload for MQTT Discovery configuration
json_payload=$(jq -n --arg sensor_name "$sensor_name" --arg status "$status" --arg type "$type" --arg friendly_name "$friendly_name" \
'{"name": "Devolo '$friendly_name'",
"state_topic": "homeassistant/sensor/'$sensor_name'/state",
"unique_id": "'$sensor_name'",
"device": {"identifiers": ["'$mac'"],
"name": "'$friendly_name'",
"model": "dLAN 550 duo+",
"manufacturer": "Devolo"
},
"json_attributes_topic": "homeassistant/sensor/'$sensor_name'/attributes",
"json_attributes_template": "{{ value_json.data.value | tojson }}"
}')
# Publish the MQTT Discovery configuration to the appropriate topic
echo "$json_payload"
# Publish the sensor state to the MQTT state topic
echo "$status"
# Publish the sensor attributes to the MQTT attribute topic
json_attribute="{ \"mac\": \"$mac\", \"type\": \"$type\""
# Check if tx is a numeric value
if [[ $tx =~ ^[0-9]+$ ]]; then
json_attribute="$json_attribute, \"tx\": $tx"
fi
# Check if rx is a numeric value
if [[ $rx =~ ^[0-9]+$ ]]; then
json_attribute="$json_attribute, \"rx\": $rx"
fi
json_attribute="$json_attribute }"
echo "$json_attribute"
done < devolo.network
Manufacturer and model are hard coded. It is a custom script, you can adjust for your need.
echo are there so you can output what will suit you for a command_line
sensor.