u
This commit is contained in:
@@ -179,113 +179,131 @@ discover_and_report_controls() {
|
|||||||
|
|
||||||
log "Discovering available camera controls..."
|
log "Discovering available camera controls..."
|
||||||
|
|
||||||
# Helper function to escape strings for JSON
|
# Get v4l2-ctl output
|
||||||
json_escape() {
|
local v4l2_output
|
||||||
local str="$1"
|
v4l2_output=$(v4l2-ctl -d "$VIDEO_DEVICE" -L 2>/dev/null) || true
|
||||||
# Escape backslashes first, then quotes
|
|
||||||
str="${str//\\/\\\\}"
|
|
||||||
str="${str//\"/\\\"}"
|
|
||||||
# Remove any control characters
|
|
||||||
str=$(echo "$str" | tr -d '\n\r\t')
|
|
||||||
echo "$str"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse v4l2-ctl -L output into JSON
|
if [[ -z "$v4l2_output" ]]; then
|
||||||
# Example lines:
|
log "No v4l2 controls found"
|
||||||
# brightness 0x00980900 (int) : min=-64 max=64 step=1 default=0 value=0
|
return
|
||||||
# exposure_auto 0x009a0901 (menu) : min=0 max=3 default=3 value=3
|
fi
|
||||||
# 1: Manual Mode
|
|
||||||
# 3: Aperture Priority Mode
|
|
||||||
|
|
||||||
local controls_json="["
|
local payload
|
||||||
local current_values_json="{"
|
|
||||||
local first_control=true
|
if command -v jq &>/dev/null; then
|
||||||
local first_value=true
|
# Use jq for proper JSON generation
|
||||||
|
local controls_array="[]"
|
||||||
|
local values_obj="{}"
|
||||||
local current_ctrl=""
|
local current_ctrl=""
|
||||||
local ctrl_json=""
|
local current_type=""
|
||||||
local menu_options=""
|
local current_min=""
|
||||||
local in_menu=false
|
local current_max=""
|
||||||
|
local current_step=""
|
||||||
|
local current_default=""
|
||||||
|
local current_value=""
|
||||||
|
local menu_opts="{}"
|
||||||
|
|
||||||
while IFS= read -r line || [[ -n "$line" ]]; do
|
while IFS= read -r line; do
|
||||||
# Check if this is a control line (starts with control name)
|
# Control line pattern: name 0xhex (type) : params
|
||||||
if [[ "$line" =~ ^[[:space:]]*([a-z_][a-z0-9_]*)[[:space:]]+0x[0-9a-f]+[[:space:]]+\(([a-z]+)\)[[:space:]]*:[[:space:]]*(.*) ]]; then
|
if [[ "$line" =~ ^[[:space:]]*([a-z_][a-z0-9_]*)[[:space:]]+0x[0-9a-f]+[[:space:]]+\(([a-z]+)\)[[:space:]]*:[[:space:]]*(.*) ]]; then
|
||||||
# Save previous control if exists
|
# Save previous control
|
||||||
if [[ -n "$current_ctrl" ]]; then
|
if [[ -n "$current_ctrl" ]]; then
|
||||||
if [[ "$in_menu" == "true" && -n "$menu_options" ]]; then
|
local ctrl_obj
|
||||||
ctrl_json="${ctrl_json%, }, \"options\": {${menu_options%,}}}"
|
ctrl_obj=$(jq -n \
|
||||||
else
|
--arg name "$current_ctrl" \
|
||||||
ctrl_json="${ctrl_json%,}}"
|
--arg type "$current_type" \
|
||||||
|
--argjson min "${current_min:-null}" \
|
||||||
|
--argjson max "${current_max:-null}" \
|
||||||
|
--argjson step "${current_step:-null}" \
|
||||||
|
--argjson default "${current_default:-null}" \
|
||||||
|
--argjson opts "$menu_opts" \
|
||||||
|
'{name: $name, type: $type} +
|
||||||
|
(if $min != null then {min: $min} else {} end) +
|
||||||
|
(if $max != null then {max: $max} else {} end) +
|
||||||
|
(if $step != null then {step: $step} else {} end) +
|
||||||
|
(if $default != null then {default: $default} else {} end) +
|
||||||
|
(if ($opts | length) > 0 then {options: $opts} else {} end)')
|
||||||
|
controls_array=$(echo "$controls_array" | jq --argjson ctrl "$ctrl_obj" '. + [$ctrl]')
|
||||||
|
|
||||||
|
if [[ -n "$current_value" ]]; then
|
||||||
|
values_obj=$(echo "$values_obj" | jq --arg k "$current_ctrl" --argjson v "$current_value" '. + {($k): $v}')
|
||||||
fi
|
fi
|
||||||
if [[ "$first_control" == "true" ]]; then
|
|
||||||
first_control=false
|
|
||||||
else
|
|
||||||
controls_json+=","
|
|
||||||
fi
|
|
||||||
controls_json+="$ctrl_json"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
current_ctrl="${BASH_REMATCH[1]}"
|
current_ctrl="${BASH_REMATCH[1]}"
|
||||||
local ctrl_type="${BASH_REMATCH[2]}"
|
current_type="${BASH_REMATCH[2]}"
|
||||||
local params="${BASH_REMATCH[3]}"
|
local params="${BASH_REMATCH[3]}"
|
||||||
|
menu_opts="{}"
|
||||||
|
current_min="" current_max="" current_step="" current_default="" current_value=""
|
||||||
|
|
||||||
ctrl_json="{\"name\": \"$current_ctrl\", \"type\": \"$ctrl_type\","
|
[[ "$params" =~ min=(-?[0-9]+) ]] && current_min="${BASH_REMATCH[1]}"
|
||||||
menu_options=""
|
[[ "$params" =~ max=(-?[0-9]+) ]] && current_max="${BASH_REMATCH[1]}"
|
||||||
in_menu=false
|
[[ "$params" =~ step=([0-9]+) ]] && current_step="${BASH_REMATCH[1]}"
|
||||||
|
[[ "$params" =~ default=(-?[0-9]+) ]] && current_default="${BASH_REMATCH[1]}"
|
||||||
|
[[ "$params" =~ value=(-?[0-9]+) ]] && current_value="${BASH_REMATCH[1]}"
|
||||||
|
|
||||||
# Parse parameters
|
# Menu option line
|
||||||
if [[ "$params" =~ min=(-?[0-9]+) ]]; then
|
elif [[ "$current_type" == "menu" && "$line" =~ ^[[:space:]]+([0-9]+):[[:space:]]+(.+)$ ]]; then
|
||||||
ctrl_json+=" \"min\": ${BASH_REMATCH[1]},"
|
local opt_key="${BASH_REMATCH[1]}"
|
||||||
|
local opt_val="${BASH_REMATCH[2]}"
|
||||||
|
menu_opts=$(echo "$menu_opts" | jq --arg k "$opt_key" --arg v "$opt_val" '. + {($k): $v}')
|
||||||
fi
|
fi
|
||||||
if [[ "$params" =~ max=(-?[0-9]+) ]]; then
|
done <<< "$v4l2_output"
|
||||||
ctrl_json+=" \"max\": ${BASH_REMATCH[1]},"
|
|
||||||
fi
|
|
||||||
if [[ "$params" =~ step=([0-9]+) ]]; then
|
|
||||||
ctrl_json+=" \"step\": ${BASH_REMATCH[1]},"
|
|
||||||
fi
|
|
||||||
if [[ "$params" =~ default=(-?[0-9]+) ]]; then
|
|
||||||
ctrl_json+=" \"default\": ${BASH_REMATCH[1]},"
|
|
||||||
fi
|
|
||||||
if [[ "$params" =~ value=(-?[0-9]+) ]]; then
|
|
||||||
local current_value="${BASH_REMATCH[1]}"
|
|
||||||
if [[ "$first_value" == "true" ]]; then
|
|
||||||
first_value=false
|
|
||||||
else
|
|
||||||
current_values_json+=","
|
|
||||||
fi
|
|
||||||
current_values_json+="\"$current_ctrl\": $current_value"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$ctrl_type" == "menu" ]]; then
|
|
||||||
in_menu=true
|
|
||||||
fi
|
|
||||||
# Check if this is a menu option line (indented with number: description)
|
|
||||||
elif [[ "$in_menu" == "true" && "$line" =~ ^[[:space:]]+([0-9]+):[[:space:]]+(.+)$ ]]; then
|
|
||||||
local opt_val="${BASH_REMATCH[1]}"
|
|
||||||
local opt_name
|
|
||||||
opt_name=$(json_escape "${BASH_REMATCH[2]}")
|
|
||||||
menu_options+="\"$opt_val\": \"$opt_name\","
|
|
||||||
fi
|
|
||||||
done < <(v4l2-ctl -d "$VIDEO_DEVICE" -L 2>/dev/null)
|
|
||||||
|
|
||||||
# Save last control
|
# Save last control
|
||||||
if [[ -n "$current_ctrl" ]]; then
|
if [[ -n "$current_ctrl" ]]; then
|
||||||
if [[ "$in_menu" == "true" && -n "$menu_options" ]]; then
|
local ctrl_obj
|
||||||
ctrl_json="${ctrl_json%, }, \"options\": {${menu_options%,}}}"
|
ctrl_obj=$(jq -n \
|
||||||
else
|
--arg name "$current_ctrl" \
|
||||||
ctrl_json="${ctrl_json%,}}"
|
--arg type "$current_type" \
|
||||||
|
--argjson min "${current_min:-null}" \
|
||||||
|
--argjson max "${current_max:-null}" \
|
||||||
|
--argjson step "${current_step:-null}" \
|
||||||
|
--argjson default "${current_default:-null}" \
|
||||||
|
--argjson opts "$menu_opts" \
|
||||||
|
'{name: $name, type: $type} +
|
||||||
|
(if $min != null then {min: $min} else {} end) +
|
||||||
|
(if $max != null then {max: $max} else {} end) +
|
||||||
|
(if $step != null then {step: $step} else {} end) +
|
||||||
|
(if $default != null then {default: $default} else {} end) +
|
||||||
|
(if ($opts | length) > 0 then {options: $opts} else {} end)')
|
||||||
|
controls_array=$(echo "$controls_array" | jq --argjson ctrl "$ctrl_obj" '. + [$ctrl]')
|
||||||
|
|
||||||
|
if [[ -n "$current_value" ]]; then
|
||||||
|
values_obj=$(echo "$values_obj" | jq --arg k "$current_ctrl" --argjson v "$current_value" '. + {($k): $v}')
|
||||||
fi
|
fi
|
||||||
if [[ "$first_control" != "true" ]]; then
|
|
||||||
controls_json+=","
|
|
||||||
fi
|
|
||||||
controls_json+="$ctrl_json"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
controls_json+="]"
|
payload=$(jq -n --argjson controls "$controls_array" --argjson values "$values_obj" \
|
||||||
current_values_json+="}"
|
'{controls: $controls, currentValues: $values}')
|
||||||
|
else
|
||||||
|
# Fallback: simple approach without jq (no menu options, basic controls only)
|
||||||
|
log "jq not available, using simple control discovery"
|
||||||
|
local controls="["
|
||||||
|
local values="{"
|
||||||
|
local first_ctrl=true
|
||||||
|
local first_val=true
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
if [[ "$line" =~ ^[[:space:]]*([a-z_][a-z0-9_]*)[[:space:]]+0x[0-9a-f]+[[:space:]]+\(([a-z]+)\)[[:space:]]*:.*value=(-?[0-9]+) ]]; then
|
||||||
|
local name="${BASH_REMATCH[1]}"
|
||||||
|
local type="${BASH_REMATCH[2]}"
|
||||||
|
local value="${BASH_REMATCH[3]}"
|
||||||
|
|
||||||
|
[[ "$first_ctrl" == "true" ]] && first_ctrl=false || controls+=","
|
||||||
|
controls+="{\"name\":\"$name\",\"type\":\"$type\"}"
|
||||||
|
|
||||||
|
[[ "$first_val" == "true" ]] && first_val=false || values+=","
|
||||||
|
values+="\"$name\":$value"
|
||||||
|
fi
|
||||||
|
done <<< "$v4l2_output"
|
||||||
|
|
||||||
|
controls+="]"
|
||||||
|
values+="}"
|
||||||
|
payload="{\"controls\":$controls,\"currentValues\":$values}"
|
||||||
|
fi
|
||||||
|
|
||||||
# POST to server
|
# POST to server
|
||||||
local payload="{\"controls\": $controls_json, \"currentValues\": $current_values_json}"
|
|
||||||
|
|
||||||
local response
|
local response
|
||||||
response=$(curl -s --max-time 10 \
|
response=$(curl -s --max-time 10 \
|
||||||
-X POST \
|
-X POST \
|
||||||
@@ -296,7 +314,11 @@ discover_and_report_controls() {
|
|||||||
|
|
||||||
if echo "$response" | grep -q '"success"'; then
|
if echo "$response" | grep -q '"success"'; then
|
||||||
local count
|
local count
|
||||||
|
if command -v jq &>/dev/null; then
|
||||||
|
count=$(echo "$response" | jq -r '.controlsRegistered // "?"')
|
||||||
|
else
|
||||||
count=$(echo "$response" | grep -o '"controlsRegistered":[0-9]*' | cut -d: -f2)
|
count=$(echo "$response" | grep -o '"controlsRegistered":[0-9]*' | cut -d: -f2)
|
||||||
|
fi
|
||||||
log "Reported $count available controls to server"
|
log "Reported $count available controls to server"
|
||||||
else
|
else
|
||||||
log "Failed to report available controls: $response"
|
log "Failed to report available controls: $response"
|
||||||
|
|||||||
Reference in New Issue
Block a user