Merge pull request #350 from femtofox/noon2

Revamp meshtastic settings ingest
This commit is contained in:
noon92 2025-02-18 22:27:21 +02:00 • committed by GitHub
commit f2e8ad0491
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 194 additions and 108 deletions

View file

@ -21,7 +21,7 @@ loading() {
}
## function to pull data from various femto scripts and convert it to the contents of a read only dialog --form
# ingest_data() { # usage: `ingest_data "command.sh -argument" key_width value_width`
# ingest_form_data() { # usage: `ingest_form_data "command.sh -argument" key_width value_width`
# unset output_array #debug code, delete me
# declare -a output_array
# # Read the output from femto-meshtasticd-config.sh and store it in the array
@ -42,7 +42,7 @@ loading() {
# echo "$form_contents" | sed 's/\x1b\[[0-9;]*m//g'
# }
## CODE TO USE THIS FUNCTION:
# eval "$(echo -e "dialog --no-collapse --no-cancel --form \"Meshtastic node info\" 0 0 0 $(ingest_data "femto-meshtasticd-config.sh -i" 18 0) 2>/dev/null")"
# eval "$(echo -e "dialog --no-collapse --no-cancel --form \"Meshtastic node info\" 0 0 0 $(ingest_form_data "femto-meshtasticd-config.sh -i" 18 0) 2>/dev/null")"
# function to pull data from various femto scripts and convert it a simple text string, with dialog colors
@ -62,10 +62,16 @@ ingest_data() { # usage: `ingest_data "command.sh -argument" key_width`
}
check_meshtasticd_running() {
if echo $(femto-utils.sh -C "meshtasticd") | grep -q "not running"; then
if ! echo $(femto-utils.sh -C "meshtasticd") | sed 's/\x1b\[[0-9;]*m//g' | grep -q ", running"; then
dialog --no-collapse --title "Meshtasticd service" --yesno "Meshtasticd service is not running but is required.\n\nStart service?" 9 50
if [ $? -eq 0 ]; then #unless cancel/no
femto-meshtasticd-config.sh -s
echo "Waiting for meshtasticd service to start..."
sleep 3
if ! echo $(femto-utils.sh -C "meshtasticd") | sed 's/\x1b\[[0-9;]*m//g' | grep -q ", running"; then
dialog --no-collapse --colors --title "Meshtasticd service" --msgbox "Meshtasticd service ($(femto-utils.sh -R "$(femto-utils.sh -C "meshtasticd")")) failed to run, but is required." 7 50
return 1
fi
return 0
else
return 1
@ -186,12 +192,12 @@ networking_settings() {
if [ $exit_status -eq 1 ]; then # Exit the loop if the user selects "Cancel" or closes the dialog
break
elif [ $exit_status -eq 2 ]; then # Help ("extra") button
dialog --no-collapse --colors --title "Meshtastic wifi sync service help" --msgbox "The Meshtastic wifi sync service synchronizes wifi settings with Meshtastic wifi settings. This allows you to use remote node administration to enable/disable Femtofox wifi.\n\nIn future, this will also allow you to reconfigure SSID and password.\n" 0 0
dialog --no-collapse --colors --title "Meshtastic wifi sync service help" --msgbox "The Meshtastic wifi sync service synchronizes system wifi settings with Meshtastic wifi settings. This allows you to use Meshtastic's remote node administration feature to enable/disable wifi.\n\nIn future, this will also allow you to reconfigure SSID and password.\n" 0 0
else
case $choice in
"View detailed service status")
echo "Getting Meshtastic wifi sync service status..."
dialog --no-collapse --no-shadow --title "Meshtastic wifi sync service status" --msgbox "$(systemctl status femto-wifi-mesh-control)" 0 0
dialog --no-collapse --title "Meshtastic wifi sync service status" --msgbox "$(systemctl status femto-wifi-mesh-control)" 0 0
;;
"Start/restart service")
dialog --no-collapse --title "$title" --yesno "Start/restart Meshtastic wifi sync service?" 7 45
@ -383,7 +389,7 @@ legacy_admin() {
choice="" # zero the choice before loading the submenu
while true; do
loading "Getting current legacy admin state..."
choice=$(dialog --no-collapse --colors --title "Legacy Admin" --default-item "$choice" --help-button --item-help --menu "If the node you need to administer or be administered by is running 2.4.x or earlier, you should set this to Enabled.\n\nCurrent state: $(femto-utils.sh -R "$(femto-meshtasticd-config.sh -p)")" 16 65 5 \
choice=$(dialog --no-collapse --colors --title "Legacy Admin" --default-item "$choice" --help-button --item-help --menu "If the node you Femtofox needs to administer or be administered by is running 2.4.x or earlier, you should set this to Enabled.\n\nCurrent state: $(femto-utils.sh -R "$(femto-meshtasticd-config.sh -p)")" 16 65 5 \
1 "Enable" "" \
2 "Disable (default)" "" \
" " "" "" \
@ -553,7 +559,7 @@ meshtastic_settings() {
case $choice in
"View detailed service status")
echo "Getting Meshtasticd service status..."
dialog --no-collapse --no-shadow --title "Meshtasticd service status" --msgbox "$(systemctl status meshtasticd)" 0 0
dialog --no-collapse --title "Meshtasticd service status" --msgbox "$(systemctl status meshtasticd)" 0 0
;;
"Start/restart service")
dialog --no-collapse --title "$title" --yesno "Start/restart Meshtasticd service?" 6 45
@ -614,7 +620,7 @@ help_menu() {
local title="Help / About"
help_choice=$(dialog --no-collapse --cancel-label "Back" --default-item "$help_choice" --item-help --menu "$title" 0 0 7 \
1 "About Femtofox" "" \
2 "View pinout" "" \
2 "Display pinout" "" \
3 "Femtofox licensing info - short" "" \
4 "Femtofox licensing info - long" "" \
5 "Meshtastic licensing info" "" \
@ -696,7 +702,7 @@ while getopts ":hlLwc" opt; do
;;
c) # Option -c (Check if Meshtasticd is running and warn the user if not)
check_meshtasticd_running
exit $? # relay exit status
exit $?
;;
\?) # Unknown option)
echo -e "Unknown argument $1.\n$help"

View file

@ -8,6 +8,7 @@ help=$(cat <<EOF
Options are:
-h This message
-i Get important node info
-C "all" Get node configuration, by category. Multiple categories can be selected by comma delineation. \`quiet\`: do not echo to console. Options are \`quiet\`, \`all\`, \`nodeinfo\`, \`settings\`, \`channels\`
-g Gets the current configuration URL and QR code
-k Get current LoRa radio selection
-l "RADIO" Choose LoRa radio model. Options are \`lr1121_tcxo\`, \`sx1262_tcxo\`, \`sx1262_xtal\`, \`none\` (simradio)
@ -28,7 +29,7 @@ Options are:
-S Get Meshtasticd service state
-z Upgrade Meshtasticd
-x Uninstall Meshtasticd
-m Meshtastic update tool. Syntax: \`femto-meshtasticd-config.sh -m '--set security.admin_channel_enabled false' 10 'Disable legacy admin'\`
-m Meshtastic update tool. Syntax: \`femto-meshtasticd-config.sh -m \"--set security.admin_channel_enabled false\" 10 \"Disable legacy admin\"\`
Will retry the \`--set security.admin_channel_enabled false\` command until successful or up to 10 times, and tag status reports with \`Disable legacy admin\` via echo and to system log.
EOF
)
@ -45,19 +46,18 @@ meshtastic_update() {
local ref="$3: "
echo "Submitting to Meshtastic..."
for retries in $(seq 1 $attempts); do
local output=$(meshtastic --host $command | tee /dev/tty) #>&2 lets meshtastic's output display on screen
local output=$(meshtastic --host $command 2>&1 | tee $(if [ -e /dev/tty ]; then echo /dev/tty; else echo /dev/ttyFIQ0; fi))
logger $output
if echo "$output" | grep -qiE "Abort|invalid|Error|refused|Errno"; then
if [ "$retries" -lt $attempts ]; then
local msg="${ref:+$ref}Meshtastic command failed, retrying ($(($retries + 1))/$attempts)..."
femto-meshtasticd-config.sh -s
echo "$msg"
logger "$msg"
femto-meshtasticd-config.sh -s
sleep 2 # Add a small delay before retrying
fi
else
local success="true"
echo -e "$output"
msg="${ref:+$ref}Meshtastic command successful!"
echo "$msg"
logger "$msg"
@ -76,53 +76,144 @@ meshtastic_update() {
fi
}
get_meshtastic_settings() {
for retries in $(seq 1 3); do
if meshtastic_info=$(meshtastic --host --info); then # if successful
success="true"
break
else # if failed
if [ "$retries" -lt 3 ]; then # if under 3 retries
echo "Meshtastic command failed, retrying ($(($retries + 1))/3)..."
femto-meshtasticd-config.sh -s
sleep 2 # Add a small delay before retrying
fi
fi
done
if [ -z "$success" ]; then # if failed all retries
echo "Meshtastic command FAILED."
exit 1 # always exit script if failed
fi
if [[ "$1" == *"all"* ]] || [[ "$1" == *"nodeinfo"* ]]; then
# myInfo
eval "myInfo_owner='$(echo "$meshtastic_info" | grep "^Owner: " | sed 's/^Owner: //')'"
[[ "$1" != *"quiet"* ]] && echo "myInfo_owner:$myInfo_owner"
while IFS="=" read -r varname value; do
eval "myInfo_$varname='$value'" # Create a variable with the formatted name
[[ "$1" != *"quiet"* ]] && echo "myInfo_$varname:$value"
done < <(
echo "$(echo "$meshtastic_info" | grep '^My info: ' | sed 's/^My info: //')" |
jq -r 'to_entries[] | "\(.key)=\(.value)"'
)
# metadata
while IFS="=" read -r varname value; do
eval "metadata_$varname='$value'" # Create a variable with the formatted name
[[ "$1" != *"quiet"* ]] && echo "metadata_$varname:$value"
done < <(
echo "$(echo "$meshtastic_info" | grep '^Metadata: ' | sed 's/^Metadata: //')" |
jq -r 'to_entries[] | "\(.key)=\(.value)"'
)
metadata_nodedbCount=$(echo "$meshtastic_info" | grep -oP '"![a-zA-Z0-9]+":\s*\{' | wc -l)
[[ "$1" != *"quiet"* ]] && echo "metadata_nodedbCount:$metadata_nodedbCount"
# nodeinfo
while IFS='=' read -r var value; do
eval "nodeinfo_$var=\"$value\""
[[ "$1" != *"quiet"* ]] && echo "nodeinfo_$var:$value"
done < <(echo "$(echo "$meshtastic_info" | sed -n '/Nodes in mesh:/,$p' | sed '1s/^Nodes in mesh: *//' | sed '/^[[:space:]]*$/q' | jq -r 'to_entries | .[0] | "\(.key)=\(.value)"' | sed 's/^[^=]*=//;s/^[ \t]*}//')" | jq -r '
def recurse:
if type == "object" then
to_entries | .[] | "\(.key)=\(.value | recurse)"
elif type == "array" then
. | tostring
else
.
end;
recurse' | sed '/=/ {s/\(.*\)=\(.*\)=/\1_\2=/; }'
)
fi
if [[ "$1" == *"all"* ]] || [[ "$1" == *"settings"* ]]; then
# settings
while IFS="=" read -r varname value; do
eval "$varname='$value'"
[[ "$1" != *"quiet"* ]] && echo "$varname:$value"
done < <(
echo "$(echo "$meshtastic_info" | sed -n '/Preferences: {/,$p' | sed '1s/.*/{/; /^[[:space:]]*$/q')" |
jq -r 'to_entries[] | select(.value | type == "object") | .key as $block | .value | to_entries[] | "\($block)_\(.key)=\(.value)"'
)
# module settings
while IFS="=" read -r varname value; do
eval "$varname='$value'"
[[ "$1" != *"quiet"* ]] && echo "$varname:$value"
done < <(
echo "$(echo "$meshtastic_info" | sed -n '/Module preferences: {/,$p' | sed '1s/.*/{/; /^[[:space:]]*$/q')" |
jq -r 'to_entries[] | select(.value | type == "object") | .key as $block | .value | to_entries[] | "\($block)_\(.key)=\(.value)"'
)
fi
if [[ "$1" == *"all"* ]] || [[ "$1" == *"channels"* ]]; then
# channels
while read index line; do
channel_type=$(echo "$line" | awk '{print $3}')
psk_type=$(echo "$line" | grep -o 'psk=[^ ]*' | cut -d= -f2)
eval "channel${index}_type='$channel_type'"
[[ "$1" != *"quiet"* ]] && echo "channel${index}_type:$channel_type"
eval "channel${index}_psk_type='$psk_type'"
[[ "$1" != *"quiet"* ]] && echo "channel${index}_psk_type:$psk_type"
# get the json portion of the channel listing
while IFS=":" read -r key value; do
eval "$key='$value'"
[[ "$1" != *"quiet"* ]] && echo "$key:$value"
done < <(
echo "$(echo "$line" | sed 's/.*\({.*\)/\1/')" | jq -r 'to_entries | .[] | "channel'${index}'_\(.key):\(.value)"'
)
done < <(
echo "$meshtastic_info" | awk '/Channels:/ {f=1; next} f && NF {print} f && !NF {exit}' | nl -v 0
)
eval "url_primary_channel='$(echo "$meshtastic_info" | sed -n 's/^Primary channel URL: //p')'"
[[ "$1" != *"quiet"* ]] && echo "url_primary_channel:$url_primary_channel"
eval "url_all_channels='$(echo "$meshtastic_info" | sed -n 's/^Complete URL (includes all channels): //p')'"
[[ "$1" != *"quiet"* ]] && echo "url_all_channels:$url_all_channels"
fi
}
# Parse options
while getopts ":higkl:q:uU:rR:aA:cpo:sM:Stwuxm" opt; do
while getopts ":hiC:gkl:q:uU:rR:aA:cpo:sM:Stwuxm" opt; do
case ${opt} in
h) # Option -h (help)
echo -e "$help"
;;
i) # Option -i (Get important node info)
declare -a output_array
output=$(meshtastic --host --info)
output_array+=("Service=$(femto-meshtasticd-config.sh -S)")
output_array+=("Version=$(echo "$output" | grep -oP '"firmwareVersion":\s*"\K[^"]+' | head -n 1)")
output_array+=("Node name=$(echo "$output" | grep -oP 'Owner:\s*\K.*' | head -n 1)")
output_array+=("NodeID=$(echo "!$(printf "%08x\n" $(echo "$output" | grep -oP '"myNodeNum":\s*\K\d+' | head -n 1))")")
output_array+=("Nodenum=$(echo "$output" | grep -oP '"myNodeNum":\s*\K\d+' | head -n 1)")
output_array+=("TX enabled=$(echo "$output" | grep -oP '"txEnabled":\s*\K\w+')")
use_preset=$(echo "$output" | grep -oP '"usePreset":\s*\K\w+')
output_array+=("Use preset=$use_preset")
if [ "$use_preset" = "true" ]; then # if use-preset is true, then display the preset
output_array+=("Preset=$(echo "$output" | grep -oP '"modemPreset":\s*"\K[^"]+')")
else # otherwise, display the lora settings
output_array+=("Bandwidth=$(echo "$output" | grep -oP '"bandwidth":\s*\K\w+')")
output_array+=("Spread factor=$(echo "$output" | grep -oP '"spreadFactor":\s*\K\w+')")
output_array+=("Coding rate=$(echo "$output" | grep -oP '"codingRate":\s*\K\w+')")
fi
output_array+=("Role=$(echo "$output" | grep -oP '"role":\s*"\K[^"]+' | head -n 1)")
freq_offset=$(echo "$output" | grep -oP '"bandwidth":\s*\K\w+')
if [ "$freq_offset" != 0 ]; then # only display frequency offset if not 0
output_array+=("Freq offset=$freq_offset")
fi
output_array+=("Region=$(echo "$output" | grep -oP '"region":\s*"\K[^"]+')")
output_array+=("Hop limit=$(echo "$output" | grep -oP '"hopLimit":\s*\K\w+')")
freq_slot=$(echo "$output" | grep -oP '"channelNum":\s*\K\d+' | head -n 1)
if [ "$freq_slot" != 0 ]; then # only display frequency slot if not 0
freq_slot+=("Freq slot=$freq_slot")
fi
override_freq=$(echo "$output" | grep -oP '"overrideFrequency":\s*\K[0-9.]+')
if [ "$override_freq" != "0.0" ]; then # only display override frequency if not 0.0
output_array+=("Override freq=$override_freq")
fi
output_array+=("Public key=$(echo "$output" | grep -oP '"publicKey":\s*"\K[^"]+' | head -n 1)")
output_array+=("Nodes in db=$(echo "$output" | grep -oP '"![a-zA-Z0-9]+":\s*\{' | wc -l)")
# now, echo the array
for pair in "${output_array[@]}"; do
key=$(echo "$pair" | cut -d'=' -f1)
value=$(echo "$pair" | cut -d'=' -f2-)
echo "$key:$value"
done
get_meshtastic_settings quiet,nodeinfo,settings
echo -e "\
Service:$(femto-meshtasticd-config.sh -S)
Version:$metadata_firmwareVersion
Node name:$myInfo_owner
NodeID:$nodeinfo_user_id
Nodenum:$myInfo_myNodeNum
TX enabled:$lora_txEnabled
Use preset:$lora_usePreset
Preset:$lora_modemPreset
Bandwidth:$lora_bandwidth
Spread factor:$lora_spreadFactor
Coding rate:$lora_codingRate
Role:$device_role
Freq offset:$lora_frequencyOffset
Region:$lora_region
Hop limit:$lora_hopLimit
Freq slot:$lora_channelNum
Override freq:$lora_overrideFrequency
Public key:$security_publicKey
Nodes in db:$metadata_nodedbCount"
;;
C) # Option -C (Complete node config)
get_meshtastic_settings $OPTARG
;;
g) # Option -g (get config URL)
url=$(meshtastic --host --qr-all | grep -oP '(?<=Complete URL \(includes all channels\): )https://[^ ]+') #add look for errors
@ -239,14 +330,16 @@ while getopts ":higkl:q:uU:rR:aA:cpo:sM:Stwuxm" opt; do
x) # Option -x (uninstall meshtasticd)
apt remove meshtasticd
;;
m) # Option -m (manual meshtastic command)
m)
external="true" # set a variable so the function knows it was called by an an external script and not locally
meshtastic_update "$2" $3 "$4"
;;
\?) # Invalid option)
echo -e "Unknown argument $1.\n$help"
\?) # Invalid option
echo "Invalid option: -$OPTARG"
echo -e "$help"
exit 1
;;
:) # Missing argument for option)
:) # Missing argument for option
echo "Option -$OPTARG requires a setting."
echo -e "$help"
exit 1

View file

@ -11,7 +11,6 @@ export LANG=C.UTF-8
title="Meshtastic LoRa Settings"
args=$@
send_settings() {
if [ -n "$command" ]; then
set -o pipefail
@ -25,6 +24,7 @@ send_settings() {
dialog --no-collapse --colors --title "$title" --msgbox "$(echo -e "\Z4Command Successful!\Zn\n\nLog:\n$output")" 0 0
fi
fi
[ "$1" = "wizard" ] && [ -z "$args" ] && dialog --no-collapse --title "$title" --colors --msgbox "Meshtastic LoRa Settings Wizard complete!" 6 50 # if in wizard mode AND there are no script arguments, display the message
}
@ -102,21 +102,21 @@ set_lora_radio() {
}
lora_settings_actions() {
if [ "$1" = "set_lora_radio_model" ] || [ "$1" = "wizard" ]; then
set_lora_radio $1
fi
if femto-config -c; then
if [ "$1" = "set_lora_radio_model" ] || [ "$1" = "wizard" ]; then
set_lora_radio $1
[ "$1" != "wizard" ] && return
fi
if [ "$1" = "wizard" ]; then
choice="" # zero the choice before loading the submenu
while true; do
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --default-item "True" --item-help --menu "Meshtastic configuration method" 8 50 0 \
choice=$(dialog --no-collapse --title "$title" --cancel-label "Cancel" --default-item "True" --item-help --menu "Meshtastic configuration method" 8 50 0 \
"Automatic configuration with URL" "" "" \
"Manual configuration" "" "" \
" " "" "" \
"$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" "" "" 3>&1 1>&2 2>&3)
[ $? -eq 1 ] || [ "$choice" == "Cancel" ] || [ "$choice" == "Skip" ] || [ "$choice" == "Skip" ] && return # Exit the loop if the user selects "Cancel" or closes the dialog
"Cancel" "" "" 3>&1 1>&2 2>&3)
[ $? -eq 1 ] || [ "$choice" == "Cancel" ] && return # Exit the loop if the user selects "Cancel" or closes the dialog
[ "$choice" == "" ] && continue #restart loop if no choice made
[ "$choice" == "Manual configuration" ] && break
[ "$choice" == "Automatic configuration with URL" ] && config_url "$1"
@ -124,6 +124,11 @@ lora_settings_actions() {
done
fi
dialog --no-collapse --infobox "Getting current settings from Meshtasticd.\n\nThis can take a minute..." 6 50
while IFS=':' read -r key value; do
eval "${key}=\"${value}\"" # Create a variable with the key name and assign it the value
done < <(sudo femto-meshtasticd-config.sh -C settings)
if [ "$1" = "region" ] || [ "$1" = "wizard" ]; then
options=("UNSET" "US" "EU_433" "EU_868" "CN" "JP" "ANZ" "KR" "TW" "RU" "IN" "NZ_865" "TH" "LORA_24" "UA_433" "UA_868" "MY_433" "MY_919" "SG_923")
menu_items=()
@ -137,20 +142,19 @@ lora_settings_actions() {
done
menu_items+=("" "" "" "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" "" "")
while true; do
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --default-item "LONG_FAST" --item-help --menu "Sets the region for your node. Default is unset. As long as this is not set, the node screen will display a message and not transmit any packets.\n\nRegion (default: UNSET)?" 0 0 0 \
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --default-item "$lora_region" --item-help --menu "Sets the region for your node. As long as this is not set, the node will display a message and not transmit any packets.\n\nRegion? (current: ${lora_region})" 0 0 0 \
"${menu_items[@]}" 3>&1 1>&2 2>&3)
[ $? -eq 1 ] || [ "$choice" == "Cancel" ] || [ "$choice" == "Skip" ] && break # Exit the loop if the user selects "Cancel" or closes the dialog
[ "$choice" == "" ] && continue # Restart loop if no choice made
command+="--set lora.region $choice "
break
done
[ "$1" != "wizard" ] && return
fi
if [ "$1" = "use_modem_preset" ] || [ "$1" = "wizard" ]; then
choice="" # zero the choice before loading the submenu
while true; do
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --default-item "True" --item-help --menu "Presets are pre-defined modem settings (Bandwidth, Spread Factor, and Coding Rate) which influence both message speed and range. The vast majority of users use a preset.\n\nUse modem preset?" 0 0 0 \
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --default-item "${lora_usePreset^}" --item-help --menu "Presets are pre-defined modem settings (Bandwidth, Spread Factor, and Coding Rate) which influence both message speed and range. The vast majority of users use a preset.\n\nUse modem preset? (current: ${lora_usePreset:-unknown})" 0 0 0 \
"True" "(default)" "" \
"False" "" "" \
" " "" "" \
@ -161,7 +165,6 @@ lora_settings_actions() {
command+="--set lora.use_preset $(echo "$choice" | tr '[:upper:]' '[:lower:]') "
break
done
[ "$1" != "wizard" ] && return
fi
if [ "$1" = "wizard" ] && [ "$using_preset" = "False" ]; then
@ -180,14 +183,13 @@ lora_settings_actions() {
done
menu_items+=("" "" "" "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" "" "")
while true; do
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --default-item "LONG_FAST" --item-help --menu "The default preset will provide a strong mixture of speed and range, for most users.\n\nPreset?" 0 0 0 \
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --default-item "${$lora_modemPreset^}" --item-help --menu "The default preset will provide a strong mixture of speed and range, for most users.\n\nPreset? (current: ${lora_modemPreset:-unknown})" 0 0 0 \
"${menu_items[@]}" 3>&1 1>&2 2>&3)
[ $? -eq 1 ] || [ "$choice" == "Cancel" ] || [ "$choice" == "Skip" ] && break # Exit the loop if the user selects "Cancel" or closes the dialog
[ "$choice" == "" ] && continue # Restart loop if no choice made
command+="--set lora.modem_preset $choice "
break
done
[ "$1" != "wizard" ] && return
fi
fi
@ -196,11 +198,12 @@ lora_settings_actions() {
else
if [ "$1" = "bandwidth" ] || [ "$1" = "wizard" ]; then
while true; do
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --item-help --default-item 250 --menu "Width of the frequency \"band\" used around the calculated center frequency. Only used if modem preset is disabled.\n\nBandwidth?" 0 0 0 \
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --item-help --default-item $lora_bandwidth --menu "Width of the frequency \"band\" used around the calculated center frequency. Only used if modem preset is disabled.\n\nBandwidth? (current: ${lora_bandwidth:-unknown})" 0 0 0 \
0 "(default, automatic)" "" \
31 "" "" \
62 "" "" \
125 "" "" \
250 "(default)" "" \
250 "" "" \
500 "" "" \
" " "" "" \
"$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" "" "" 3>&1 1>&2 2>&3)
@ -209,18 +212,18 @@ lora_settings_actions() {
command+="--set lora.bandwidth $choice "
break
done
[ "$1" != "wizard" ] && return
fi
if [ "$1" = "spread_factor" ] || [ "$1" = "wizard" ]; then
while true; do
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --item-help --default-item 12 --menu "Indicates the number of chirps per symbol.\n\nSpread factor (only used if modem preset is disabled)?" 0 0 0 \
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --item-help --default-item $lora_spreadFactor --menu "Indicates the number of chirps per symbol. Only used if modem preset is disabled.\n\nSpread factor? (current: ${lora_spreadFactor:-unknown})" 0 0 0 \
0 "(default, automatic)" "" \
7 "" "" \
8 "" "" \
9 "" "" \
10 "" "" \
11 "" "" \
12 "(default)" "" \
12 "" "" \
" " "" "" \
"$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" "" "" 3>&1 1>&2 2>&3)
[ $? -eq 1 ] || [ "$choice" == "Cancel" ] || [ "$choice" == "Skip" ] && break # Exit the loop if the user selects "Cancel" or closes the dialog
@ -228,16 +231,16 @@ lora_settings_actions() {
command+="--set lora.spread_factor $choice "
break
done
[ "$1" != "wizard" ] && return
fi
if [ "$1" = "coding_rate" ] || [ "$1" = "wizard" ]; then
while true; do
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --item-help --default-item 8 --menu "The proportion of each LoRa transmission that contains actual data - the rest is used for error correction.\n\nCoding rate (only used if modem preset is disabled)?" 0 0 0 \
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --item-help --default-item $lora_codingRate --menu "The proportion of each LoRa transmission that contains actual data - the rest is used for error correction.\n\nCoding rate (only used if modem preset is disabled)? (current: ${lora_codingRate:-unknown})" 0 0 0 \
0 "(default, automatic)" "" \
5 "" "" \
6 "" "" \
7 "" "" \
8 "(default)" "" \
8 "" "" \
" " "" "" \
"$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" "" "" 3>&1 1>&2 2>&3)
[ $? -eq 1 ] || [ "$choice" == "Cancel" ] || [ "$choice" == "Skip" ] && break # Exit the loop if the user selects "Cancel" or closes the dialog
@ -245,38 +248,35 @@ lora_settings_actions() {
command+="--set lora.coding_rate $choice "
break
done
[ "$1" != "wizard" ] && return
fi
fi
if [ "$1" = "frequency_offset" ] || [ "$1" = "wizard" ]; then
while true; do
input=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --inputbox "This parameter is for advanced users with advanced test equipment.\n\nFrequency offset (default: 0)" 0 0 3>&1 1>&2 2>&3)
input=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --inputbox "This parameter is for advanced users with advanced test equipment.\n\nFrequency offset (default: 0)" 0 0 ${lora_frequencyOffset:-unknown} 3>&1 1>&2 2>&3)
[[ -z $input || ($input =~ ^([0-9]{1,6})(\.[0-9]+)?$ && $(echo "$input <= 1000000" | bc -l) -eq 1) ]] && break # exit loop if user input a number between 0 and 1000000. Decimals allowed
dialog --no-collapse --title "$title" --msgbox "Must be between 0-1000000. Decimals allowed." 6 50
done
if [ $? -ne 1 ] && [ -n "$input" ]; then
command+="--set lora.frequency_offset $input "
fi
[ "$1" != "wizard" ] && return
fi
if [ "$1" = "hop_limit" ] || [ "$1" = "wizard" ]; then
while true; do
input=$(dialog --no-collapse --colors --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --inputbox "The maximum number of intermediate nodes between Femtofox and a node it is sending to. Does not impact received messages.\n\n\Z1WARNING:\Zn Excessive hop limit increases congestion!\n\nHop limit. Must be 0-7 (default: 3)" 0 0 3>&1 1>&2 2>&3)
input=$(dialog --no-collapse --colors --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --inputbox "The maximum number of intermediate nodes between Femtofox and a node it is sending to. Does not impact received messages.\n\n\Z1WARNING:\Zn Excessive hop limit increases congestion!\n\nHop limit. Must be 0-7 (default: 3)" 0 0 ${lora_hopLimit:-unknown} 3>&1 1>&2 2>&3)
[[ -z $input || ($input =~ ^[0-7]$) ]] && break # exit loop if user input an integer between 0 and 7
dialog --no-collapse --title "$title" --msgbox "Must be an integer between 0 and 7." 6 50
done
if [ $? -ne 1 ] && [ -n "$input" ]; then
command+="--set lora.hop_limit $input "
fi
[ "$1" != "wizard" ] && return
fi
if [ "$1" = "tx_enabled" ] || [ "$1" = "wizard" ]; then
choice="" # zero the choice before loading the submenu
while true; do
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --default-item "True" --item-help --menu "Enables/disables the radio chip. Useful for hot-swapping antennas.\n\nEnable TX?" 0 0 0 \
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --default-item "${lora_txEnabled^}" --item-help --menu "Enables/disables the radio chip. Useful for hot-swapping antennas.\n\nEnable TX? (current: ${lora_txEnabled:-unknown})" 0 0 0 \
"True" "(default)" "" \
"False" "" "" \
" " "" "" \
@ -286,7 +286,6 @@ lora_settings_actions() {
command+="--set lora.tx_enabled $(echo "$choice" | tr '[:upper:]' '[:lower:]') "
break
done
[ "$1" != "wizard" ] && return
fi
if [ "$1" = "tx_power" ] || [ "$1" = "wizard" ]; then
@ -300,31 +299,29 @@ ERP above 36db violates US (unlicensed) law.\n\
If 0, will use the maximum continuous power legal in your region.
\n\
\n\
TX power in dBm. Must be 0-30 (0 for automatic)" 0 0 3>&1 1>&2 2>&3)
[[ -z $input || ($input =~ ^[0-30]$) ]] && break # exit loop if user input an integer between 0 and 30
TX power in dBm. Must be 0-30 (0 for automatic)" 0 0 ${lora_txPower:-unknown} 3>&1 1>&2 2>&3)
[[ -z $input || $input =~ ^([12]?[0-9]|30)$ ]] && break # exit loop if user input an integer between 0 and 30
dialog --no-collapse --title "$title" --msgbox "Must be an integer between 0 and 30." 6 50
done
if [ $? -ne 1 ] && [ -n "$input" ]; then
command+="--set lora.tx_power $input "
fi
[ "$1" != "wizard" ] && return
fi
if [ "$1" = "frequency_slot" ] || [ "$1" = "wizard" ]; then
while true; do
input=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --inputbox "Determines the exact frequency the radio transmits and receives. If unset or set to 0, determined automatically by the primary channel name.\n\nFrequency slot (0 for automatic)" 0 0 3>&1 1>&2 2>&3)
input=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --inputbox "Determines the exact frequency the radio transmits and receives. If unset or set to 0, determined automatically by the primary channel name.\n\nFrequency slot (0 for automatic)" 0 0 ${lora_channelNum:-unknown} 3>&1 1>&2 2>&3)
[[ -z $input || ($input =~ ^[0-9]+$) ]] && break # exit loop if user input an integer 0 or higher
dialog --no-collapse --title "$title" --msgbox "Must be an integer 0 or higher." 6 50
done
if [ $? -ne 1 ] && [ -n "$input" ]; then
command+="--set lora.channel_num $input "
fi
[ "$1" != "wizard" ] && return
fi
if [ "$1" = "override_duty_cycle" ] || [ "$1" = "wizard" ]; then
while true; do
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --default-item "False" --item-help --menu "May have legal ramifications.\n\nOverride duty cycle?" 0 0 0 \
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --default-item "$(echo "${lora_overrideDutyCycle:-False}" | sed 's/^./\U&/')" --item-help --menu "May have legal ramifications.\n\nOverride duty cycle? (current: ${lora_overrideDutyCycle:-unknown})" 0 0 0 \
"True" "" "" \
"False" "(default)" "" \
" " "" "" \
@ -334,12 +331,11 @@ TX power in dBm. Must be 0-30 (0 for automatic)" 0 0 3>&1 1>&2 2>&3)
command+="--set lora.override_duty_cycle $(echo "$choice" | tr '[:upper:]' '[:lower:]') "
break
done
[ "$1" != "wizard" ] && return
fi
if [ "$1" = "sx126x_rx_boosted_gain" ] || [ "$1" = "wizard" ]; then
while true; do
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --default-item "True" --item-help --menu "This is an option specific to the SX126x chip series which allows the chip to consume a small amount of additional power to increase RX (receive) sensitivity.\n\nEnable SX126X RX boosted gain?" 0 0 0 \
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --default-item "$(echo "${lora_sx126xRxBoostedGain:-True}" | sed 's/^./\U&/')" --item-help --menu "This is an option specific to the SX126x chip series which allows the chip to consume a small amount of additional power to increase RX (receive) sensitivity.\n\nEnable SX126X RX boosted gain? (current: ${lora_sx126xRxBoostedGain:-unknown})" 0 0 0 \
"True" "(default)" "" \
"False" "" "" \
" " "" "" \
@ -349,12 +345,11 @@ TX power in dBm. Must be 0-30 (0 for automatic)" 0 0 3>&1 1>&2 2>&3)
command+="--set lora.sx126x_rx_boosted_gain $(echo "$choice" | tr '[:upper:]' '[:lower:]') "
break
done
[ "$1" != "wizard" ] && return
fi
if [ "$1" = "override_frequency" ] || [ "$1" = "wizard" ]; then
while true; do
input=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --inputbox "Overrides frequency slot. May have legal ramifications.\n\nOverride frequency in MHz (0 for none)." 0 0 3>&1 1>&2 2>&3)
input=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --inputbox "Overrides frequency slot. May have legal ramifications.\n\nOverride frequency in MHz (0 for none)." 0 0 ${lora_overrideFrequency:-unknown} 3>&1 1>&2 2>&3)
[[ -z $input || ($input =~ ^[0-9]+(\.[0-9]+)?$) ]] && break # exit loop if user input a number 0 or higher (decimals allowed)
dialog --no-collapse --title "$title" --msgbox "Must be a number 0 or higher. Decimals allowed." 6 53
done
@ -362,12 +357,11 @@ TX power in dBm. Must be 0-30 (0 for automatic)" 0 0 3>&1 1>&2 2>&3)
if [ $? -ne 1 ] && [ -n "$input" ]; then
command+="--set lora.override_frequency $input "
fi
[ "$1" != "wizard" ] && return
fi
if [ "$1" = "ignore_mqtt" ] || [ "$1" = "wizard" ]; then
while true; do
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --default-item "False" --item-help --menu "Ignores any messages it receives via LoRa that came via MQTT somewhere along the path towards the device.\n\nIgnore MQTT?" 0 0 0 \
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --default-item "$(echo "${lora_ignoreMqtt:-unknown}" | sed 's/^./\U&/')" --item-help --menu "Ignores any messages it receives via LoRa that came via MQTT somewhere along the path towards the device.\n\nIgnore MQTT? (current: ${lora_ignoreMqtt:-unknown})" 0 0 0 \
"True" "" "" \
"False" "(default)" "" \
" " "" "" \
@ -377,12 +371,11 @@ TX power in dBm. Must be 0-30 (0 for automatic)" 0 0 3>&1 1>&2 2>&3)
command+="--set lora.ignore_mqtt $(echo "$choice" | tr '[:upper:]' '[:lower:]') "
break
done
[ "$1" != "wizard" ] && return
fi
if [ "$1" = "ok_to_mqtt" ] || [ "$1" = "wizard" ]; then
while true; do
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --default-item "False" --item-help --menu "Indicates that the user approves their packets to be uplinked to MQTT brokers.\n\nOK to MQTT?" 0 0 0 \
choice=$(dialog --no-collapse --title "$title" --cancel-label "$([[ "$1" == "wizard" ]] && echo "Skip" || echo "Cancel")" --default-item "$(echo "${lora_configOkToMqtt:-unknown}" | sed 's/^./\U&/')" --item-help --menu "Indicates that the user approves their packets to be uplinked to MQTT brokers.\n\nOK to MQTT? (current: ${lora_configOkToMqtt:-unknown})" 0 0 0 \
"True" "" "" \
"False" "(default)" "" \
" " "" "" \
@ -392,15 +385,9 @@ TX power in dBm. Must be 0-30 (0 for automatic)" 0 0 3>&1 1>&2 2>&3)
command+="--set lora.config_ok_to_mqtt $(echo "$choice" | tr '[:upper:]' '[:lower:]') "
break
done
[ "$1" != "wizard" ] && return
fi
# if we're in wizard mode AND there are no script arguments, then display a message
[ "$1" = "wizard" ] && [ -z "$args" ] && dialog --no-collapse --title "$title" --colors --msgbox "Meshtastic LoRa Settings Wizard complete!" 6 50
send_settings $1
[ "$1" = "wizard" ] && return # quit function if wizard
fi
}

View file

@ -103,7 +103,7 @@ MAC address:$(ifconfig wlan0 | grep ether | awk '{print $2}')"
Wi-Fi status:\033[4m\033[0;34menabled\033[0m\n\
Connected to:$(iwconfig 2>/dev/null | grep -i 'ESSID' | awk -F 'ESSID:"' '{print $2}' | awk -F '"' '{print $1}' | sed 's/^$/none/')\n\
Sig. strength:$(iwconfig 2>/dev/null | grep -i 'Signal level' | awk -F 'Signal level=' '{print $2}' | awk '{print $1}')\n\
Current IP:$(hostname -I | awk '{print $1}')\n
Current IP:$(ip addr show wlan0 | grep 'inet ' | awk '{print $2}' | cut -d/ -f1)\n
Hostname:$(hostname).local\n\
$mac_address_line"
else