#!/bin/bash # 从 targets.csv 生成 target-onvif.json、target-ping.json、target-topology.geojson # 用法: ./update-configs.sh [targets.csv] set -e cd "$(dirname "$0")" command -v jq &>/dev/null || { echo "❌ 需要 jq"; exit 1; } CSV="${1:-targets.csv}" [ ! -f "$CSV" ] && { echo '[]' > target-onvif.json; echo '[]' > target-ping.json; echo '{"type":"FeatureCollection","features":[]}' > target-topology.geojson; exit 0; } ONVIF=$(mktemp) PING=$(mktemp) TMP=$(mktemp) trap "rm -f $ONVIF $PING $TMP" EXIT # target-onvif.json + target-ping.json tail -n +2 "$CSV" | grep -v '^#' | while IFS=',' read -r type ip name role parent uplink_type network device_type model location username password onvif_port lat lon; do type=$(echo "$type" | xargs) ip=$(echo "$ip" | xargs) [ -z "$type" ] && continue if [ "$type" = "onvif" ]; then device_type=$(echo "$device_type" | xargs) model=$(echo "$model" | xargs) location=$(echo "$location" | xargs) username=$(echo "$username" | xargs) password=$(echo "$password" | xargs) onvif_port=$(echo "$onvif_port" | xargs) labels="{\"device_type\":\"$device_type\",\"model\":\"$model\",\"location\":\"$location\",\"username\":\"$username\",\"password\":\"$password\"" [ -n "$onvif_port" ] && [ "$onvif_port" != "80" ] && labels="${labels%?},\"onvif_port\":\"$onvif_port\"}" echo "{\"targets\":[\"$ip\"],\"labels\":$labels}" >> "$ONVIF" elif [ "$type" = "ping" ]; then name=$(echo "$name" | xargs) network=$(echo "$network" | xargs) role=$(echo "$role" | xargs) parent=$(echo "$parent" | xargs) uplink_type=$(echo "$uplink_type" | xargs) labels="{\"device\":\"$name\"" [ -n "$network" ] && labels="$labels,\"network\":\"$network\"" [ -n "$role" ] && labels="$labels,\"role\":\"$role\"" [ -n "$parent" ] && labels="$labels,\"parent\":\"$parent\"" [ -n "$uplink_type" ] && labels="$labels,\"uplink_type\":\"$uplink_type\"" labels="$labels}" echo "{\"targets\":[\"$ip\"],\"labels\":$labels}" >> "$PING" fi done [ -s "$ONVIF" ] && jq -s '.' "$ONVIF" > target-onvif.json || echo '[]' > target-onvif.json [ -s "$PING" ] && jq -s '.' "$PING" > target-ping.json || echo '[]' > target-ping.json # target-topology.geojson tail -n +2 "$CSV" | grep -v '^#' | while IFS=',' read -r type ip name role parent uplink_type network device_type model location username password onvif_port lat lon; do [ -z "$(echo $type | xargs)" ] || [ -z "$(echo $name | xargs)" ] && continue echo "{\"type\":\"$type\",\"ip\":\"$ip\",\"name\":\"$name\",\"role\":\"$role\",\"parent\":\"$parent\",\"uplink_type\":\"$uplink_type\",\"network\":\"$network\",\"device_type\":\"$device_type\",\"model\":\"$model\",\"location\":\"$location\",\"lat\":\"$lat\",\"lon\":\"$lon\"}" >> "$TMP" done jq -s ' def toPoint: select(.lat != "" and .lon != "") | {type:"Feature", geometry:{type:"Point", coordinates:[(.lon|tonumber), (.lat|tonumber)]}, properties:{kind:.type, name:.name, role:.role, parent:.parent, ip:.ip, uplink_type:.uplink_type, network:.network, device_type:.device_type, model:.model, location:.location}}; def toLine(all): select(.parent != "" and .lat != "" and .lon != "") as $c | (all[] | select(.name == $c.parent and .lat != "" and .lon != "")) as $p | if $p then {type:"Feature", geometry:{type:"LineString", coordinates:[[($p.lon|tonumber), ($p.lat|tonumber)], [($c.lon|tonumber), ($c.lat|tonumber)]]}, properties:{type:"link", from:$p.name, to:$c.name}} else empty end; . as $all | {type:"FeatureCollection", features: ([$all[] | toPoint] + [$all[] | toLine($all)])} ' "$TMP" > target-topology.geojson 2>/dev/null || echo '{"type":"FeatureCollection","features":[]}' > target-topology.geojson