diff --git a/.gitignore b/.gitignore index 55ad0489..36f43a44 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ settings.conf test.sh test.conf *.FCStd1 +/venv/* \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 88143d85..6ab98296 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,49 @@ # Changelog + +## [] - not released +### Added + - Added description below form input. #381 +### Changed +### Deprecated +### Removed +### Fixed + - Remove Sbas rtcm message (1107) after F9P configuration. #391 + - Tooltips buttons were a link to top page. #387 + - Fix armbian ramlog bug with log older than 1 day. https://github.com/Stefal/build/issues/16 + - Archive service will compress .sbf files too. + - Fix duplicates in .sbf to rinex conversion : https://github.com/rtklibexplorer/RTKLIB/issues/186 + - Various fixes : #374 +### Security + +## [2.5.0] - 2024-01-30 +### Added + - udev rules to create ttyGNSS port for usb connected F9P. + - Added UART connected F9P detection and configuration. + - Some scripts for using a base with a 4G Simcom A76XX modem. (Beta). + - Rules to manage rtkbase services without sudo (Bookworm or newer). + - Trying to detect the wrong cpu temp on Orange Pi Zero. #224 + - Buttons and collapsing informations on the diagnostic page. +### Changed + - RTKLib upgraded to release b34i from rtklibexplorer. + - RTKBase now use a virtual environnement for the python environnement + - install.sh -> --detect-usb-gnss renamed to --detect-gnss + - Rinex conversion -> limit to 2 frequencies removed in "full" presets + - Rinex conversion -> receiver option (-TADJ=1 for ubx) is sourced from settings.conf + - Logs -> default time overlap changed from 30s to 0s +### Fixed + - More tests before copying RTKLib binaries. #313 + - Skip unknown section or key when restoring settings. #336 + - Fix space detection in various forms inputs. + - Fix broken form input validation patterns. #353 + - Fix some issues with Orange Pi Zero images. #361 +### Security + - Update of various python modules. + - Apply some restrictions on RTKBase services. #341 + +## [2.4.2] - 2023-11-10 +### Fixed + - Pin Werkzeug module to v2.2.2 to fix dependencie failure. #330 + ## [2.4.1] - 2023-02-26 ### Fixed - GUI -> Settings: Fixed GNSS detect & configure. #303 diff --git a/README.md b/README.md index 31971501..fe507e9f 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ If you use a Raspberry Pi, thanks to [jancelin](https://github.com/jancelin), yo If you don't already know your base precise coordinates, it's time to read one of these tutorials: - [rtklibexplorer - Post-processing RTK - for single and dual frequency receivers](https://rtklibexplorer.wordpress.com/2020/02/05/rtklib-tips-for-using-a-cors-station-as-base/) - [rtklibexplorer - PPP - for dual frequency receivers](https://rtklibexplorer.wordpress.com/2017/11/23/ppp-solutions-with-the-swiftnav-piksi-multi/) - - [Centipede documentation (in french)](https://jancelin.github.io/docs-centipedeRTK/docs/base/positionnement.html) + - [Centipede documentation (in french)](https://docs.centipede.fr/docs/base/positionnement.html) ## Manual installation: The `install.sh` script can be used without the `--all` option to split the installation process into several different steps: @@ -110,12 +110,12 @@ The `install.sh` script can be used without the `--all` option to split the inst Install gpsd and chrony to set date and time from the gnss receiver. - -e | --detect-usb-gnss - Detect your GNSS receiver. It works only with usb-connected receiver like ZED-F9P. + -e | --detect-gnss + Detect your GNSS receiver. It works only with receiver like ZED-F9P. -n | --no-write-port Doesn'\''t write the detected port inside settings.conf. - Only relevant with --detect-usb-gnss argument. + Only relevant with --detect-gnss argument. -c | --configure-gnss Configure your GNSS receiver. @@ -216,13 +216,13 @@ So, if you really want it, let's go for a manual installation with some explanat sudo systemctl enable gpsd ``` -1. Connect your gnss receiver to raspberry pi/orange pi/.... with usb or uart, and check which com port it uses (ttyS1, ttyAMA0, something else...). If it's a U-Blox usb receiver, you can use `sudo ./install.sh --detect-usb-gnss`. Write down the result, you may need it later. +1. Connect your gnss receiver to raspberry pi/orange pi/.... with usb or uart, and check which com port it uses (ttyS1, ttyAMA0, something else...). If it's a U-Blox usb receiver, you can use `sudo ./install.sh --detect-gnss`. Write down the result, you may need it later. 1. If you didn't have already configure your gnss receiver, you must set it to output raw data: If it's a U-Blox ZED-F9P (usb), you can use ```bash - sudo ./install.sh --detect-usb-gnss --configure-gnss + sudo ./install.sh --detect-gnss --configure-gnss ``` If it's a U-Blox ZED-F9P (uart), you can use this command (change the ttyS1 and 115200 value if needed)): @@ -326,6 +326,8 @@ A gnss receiver with a timepulse output is a very accurate [stratum 0](https://e ^- kalimantan.ordimatic.net 3 6 177 16 -27ms[ -27ms] +/- 64ms ``` +## Requirements: +Python >= 3.7 ## History: See the [changelog](./CHANGELOG.md) diff --git a/archive_and_clean.sh b/archive_and_clean.sh index 2ec5a09e..3f5f094a 100755 --- a/archive_and_clean.sh +++ b/archive_and_clean.sh @@ -3,7 +3,7 @@ #You can customize archive_name and archive_rotate in settings.conf BASEDIR=$(dirname "$0") -source <( grep = ${BASEDIR}/settings.conf ) +source <( grep '=' ${BASEDIR}/settings.conf ) cd ${datadir} check_space(){ @@ -30,7 +30,7 @@ done #archive and compress previous day's gnss data. #find . -maxdepth 1 -type f -mtime -1 -mmin +60 -name "*.ubx*" -exec tar -jcvf ${archive_name} --remove-files {} +; -find . -maxdepth 1 -type f -mtime -960 -mmin +60 \( -name "*.rtcm*" -o -name "*.nov*" -o -name "*.oem*" -o -name "*.ubx*" -o -name "*.ss2*" -o -name "*.hemis*" -o -name "*.stq*" -o -name "*.javad*" -o -name "*.nvs*" -o -name "*.binex*" \) -exec zip -m9 ${archive_name} {} +; +find . -maxdepth 1 -type f -mtime -960 -mmin +60 \( -name "*.rtcm*" -o -name "*.nov*" -o -name "*.oem*" -o -name "*.ubx*" -o -name "*.ss2*" -o -name "*.hemis*" -o -name "*.stq*" -o -name "*.javad*" -o -name "*.nvs*" -o -name "*.binex*" -o -name "*.sbf*" \) -exec zip -m9 ${archive_name} {} +; #delete gnss data older than x days. #find . -maxdepth 1 -type f -name "*.tar.bz2" -mtime +${archive_rotate} -delete diff --git a/rtkbase_update.sh b/rtkbase_update.sh index ad41d60b..b6bbc12d 100755 --- a/rtkbase_update.sh +++ b/rtkbase_update.sh @@ -13,9 +13,54 @@ destination_directory=$2 data_dir=$3 old_version=$4 standard_user=$5 +checking=$6 + +#store service status before upgrade +str2str_active=$(systemctl is-active str2str_tcp) +str2str_ntrip_A_active=$(systemctl is-active str2str_ntrip_A) +str2str_ntrip_B_active=$(systemctl is-active str2str_ntrip_B) +str2str_local_caster=$(systemctl is-active str2str_local_ntrip_caster) +str2str_rtcm=$(systemctl is-active str2str_rtcm_svr) +str2str_serial=$(systemctl is-active str2str_rtcm_serial) +str2str_file=$(systemctl is-active str2str_file) + +check_before_update() { + TOO_OLD='You'"'"'re Operating System is too old\nPlease update it or reflash you SDCard with a more recent RTKBase image\n' + + if [[ -f /etc/os-release ]] + then + source /etc/os-release + else + printf "Warning! We can't check your Os release, upgrade at your own risk\n" + fi + + case $ID in + debian) + if (( $(echo "$VERSION_ID < 10" | bc -l) )) + then + printf "${TOO_OLD}" >/dev/stderr + exit 1 + fi + ;; + raspbian) + if (( $(echo "$VERSION_ID < 10" | bc -l) )) + then + printf "${TOO_OLD}" >/dev/stderr + exit 1 + fi + ;; + ubuntu) + if (( $(echo "$VERSION_ID < 20.04" | bc -l) )) + then + printf "${TOO_OLD}" >/dev/stderr + exit 1 + fi + ;; + esac +} update() { -echo "remove existing rtkbase.old directory" +echo 'remove existing rtkbase.old directory' rm -rf /var/tmp/rtkbase.old mkdir /var/tmp/rtkbase.old @@ -26,8 +71,13 @@ cp -r ${destination_directory}/!(${data_dir}) /var/tmp/rtkbase.old #systemctl stop rtkbase_web.service echo "copy new release to destination" -cp -rfp ${source_directory}/. ${destination_directory} - +if [[ -d ${source_directory} ]] && [[ -d ${destination_directory} ]] + then + cp -rfp ${source_directory}/. ${destination_directory} + else + echo 'can t copy' + exit 1 +fi } insert_rtcm_msg() { @@ -171,7 +221,8 @@ upd_2.3.3() { } upgrade_rtklib() { - bin_path=$(dirname $(command -v str2str)) + systemctl stop str2str_tcp + bin_path=$(dirname "$(command -v str2str)") rm "${bin_path}"'/str2str' "${bin_path}"'/rtkrcv' "${bin_path}"'/convbin' "${destination_directory}"'/tools/install.sh' --user "${standard_user}" --rtklib } @@ -206,7 +257,7 @@ upd_2.3.4() { #update python module "${destination_directory}"'/tools/install.sh' --user "${standard_user}" --rtkbase-requirements # Get F9P firmware release - source <( grep = "${destination_directory}"/settings.conf ) + source <( grep '=' "${destination_directory}"/settings.conf ) if [[ $(python3 "${destination_directory}"/tools/ubxtool -f /dev/"${com_port}" -s ${com_port_settings%%:*} -p MON-VER) =~ 'ZED-F9P' ]] then echo 'Get F9P firmware release' @@ -243,12 +294,73 @@ upd_2.4.0() { echo '####################' echo 'Update from 2.4.0' echo '####################' + upd_2.4.1 "$@" +} + +upd_2.4.1() { + echo '####################' + echo 'Update from 2.4.1' + echo '####################' + upd_2.4.2 "$@" +} + +upd_2.4.2() { + echo '####################' + echo 'Update from 2.4.2' + echo '####################' + apt-get update -y --allow-releaseinfo-change + apt-get --fix-broken install # needed for old installation (raspi image v2.1 from july 2020) + # only for Orange Pi Zero, disable sysstats-collect (https://github.com/Stefal/build/issues/14) + # and update hostapd if error (https://github.com/Stefal/build/issues/15) + computer_model=$(tr -d '\0' < /sys/firmware/devicetree/base/model) + sbc_array=('Xunlong Orange Pi Zero') + if printf '%s\0' "${sbc_array[@]}" | grep -Fxqz -- "${computer_model}" + then + echo 'Masking sysstat-collect.timer service and upgrading hostapd' + systemctl mask sysstat-collect.timer + dpkg -s hostapd | grep -q 'Version: 2:2.9' && apt-get upgrade -y hostapd + rm -r /var/log/sysstat/ + fi + # end of Orange Pi Zero section + ${destination_directory}/tools/install.sh --user "${standard_user}" --dependencies --rtkbase-requirements --unit-files + #upgrade rtklib to b34h + upgrade_rtklib + #restart str2str if it was active before upgrading rtklib + [ $str2str_active = 'active' ] && systemctl start str2str_tcp + # restart previously running services + [ $str2str_ntrip_A_active = 'active' ] && systemctl start str2str_ntrip_A + [ $str2str_ntrip_B_active = 'active' ] && systemctl start str2str_ntrip_B + [ $str2str_local_caster = 'active' ] && systemctl start str2str_local_ntrip_caster + [ $str2str_rtcm = 'active' ] && systemctl start str2str_rtcm_svr + [ $str2str_serial = 'active' ] && systemctl start str2str_rtcm_serial + [ $str2str_file = 'active' ] && systemctl start str2str_file + return 0 } -# standard update -update +upd_2.5.0 () { + # only for Orange Pi Zero, update armbian-ramlog (https://github.com/Stefal/build/issues/16) + computer_model=$(tr -d '\0' < /sys/firmware/devicetree/base/model) + sbc_array=('Xunlong Orange Pi Zero') + if printf '%s\0' "${sbc_array[@]}" | grep -Fxqz -- "${computer_model}" && + lsb_release -c | grep -qE 'bullseye|bookworm' && + grep -qE 'armbian' /etc/os-release + then + echo 'Updating armbian-ramlog' + sed -i 's/armbian-ramlog)" | while/armbian-ramlog)|\\.journal" | while/' /usr/lib/armbian/armbian-ramlog + fi + # end of Orange Pi Zero section +} +#check if we can apply the update +#FOR THE OLDER ME -> Don't forget to modify the os detection if there is a 2.5.x release !!! +[[ $checking == '--checking' ]] && check_before_update && exit + +echo '################################' +echo 'Starting standard update' +echo '################################' +update || { echo 'Update failed (update)' ; exit 1 ;} # calling specific update function. If we are using v2.2.5, it will call the function upd_2.2.5 -upd_"${old_version/b*/b}" "$@" +echo 'Starting specific update' +upd_"${old_version/b*/b}" "$@" || { echo 'Update failed (upd_release_number)' ; exit 1 ;} #note for older me: #When dealing with beta version, "${oldversion/b*/b}" will call function 2.4b when we use a release 2.4b1 or 2.4b2 or 2.4beta99 diff --git a/run_cast.sh b/run_cast.sh index 59ab482c..afdfe2c7 100755 --- a/run_cast.sh +++ b/run_cast.sh @@ -5,7 +5,7 @@ # https://github.com/tomojitakasu/RTKLIB BASEDIR=$(dirname "$0") -source <( grep = ${BASEDIR}/settings.conf ) #import settings +source <( grep '=' ${BASEDIR}/settings.conf ) #import settings receiver_info="RTKBase ${receiver},${version} ${receiver_firmware}" in_serial="serial://${com_port}:${com_port_settings}#${receiver_format}" diff --git a/settings.conf.default b/settings.conf.default index 42580f3c..cfe9f01c 100644 --- a/settings.conf.default +++ b/settings.conf.default @@ -2,9 +2,9 @@ [general] # Version -version=2.4.1 +version=2.5.0 # Rtkbase upgrade mandatory "checkpoint" -checkpoint_version=2.5.0 +checkpoint_version=2.6.0 # User who runs str2str_file service user= # NTRIP caster program @@ -24,10 +24,12 @@ web_password_hash=pbkdf2:sha256:150000$kWdEE8eU$d30b1a75e5cf898684bad60b47a45a80 maptiler_key= #Receive prerelease update (beta version) prerelease=False +#Cpu temp offset for Orange Pi Zero LTS (+30°C) +cpu_temp_offset=0 [main] #base coordinates: lat long height -position='47.0983869 -1.2655108 36.4' +position='47.0983869 -1.2655108 36.40' #gnss receiver com port com_port='' #gnss receiver com port settings @@ -60,7 +62,7 @@ file_name='%Y-%m-%d_%h-%M-%S_GNSS-1' #file rotate time in hour file_rotate_time='24' #file overlap time in seconds -file_overlap_time='30' +file_overlap_time='0' #name for the compressed archive archive_name=$(date -d "-1 days" +"%Y-%m-%d_%S").zip #archives older than this value (in days) will be deleted by archive_and_clean.sh diff --git a/tools/bin/rtklib_b34g/aarch64/convbin b/tools/bin/rtklib_b34g/aarch64/convbin deleted file mode 100755 index 506350f5..00000000 Binary files a/tools/bin/rtklib_b34g/aarch64/convbin and /dev/null differ diff --git a/tools/bin/rtklib_b34g/aarch64/rtkrcv b/tools/bin/rtklib_b34g/aarch64/rtkrcv deleted file mode 100755 index 3836542c..00000000 Binary files a/tools/bin/rtklib_b34g/aarch64/rtkrcv and /dev/null differ diff --git a/tools/bin/rtklib_b34g/aarch64/str2str b/tools/bin/rtklib_b34g/aarch64/str2str deleted file mode 100755 index b0bf326a..00000000 Binary files a/tools/bin/rtklib_b34g/aarch64/str2str and /dev/null differ diff --git a/tools/bin/rtklib_b34g/armv6l/convbin b/tools/bin/rtklib_b34g/armv6l/convbin deleted file mode 100755 index 0f17d2c2..00000000 Binary files a/tools/bin/rtklib_b34g/armv6l/convbin and /dev/null differ diff --git a/tools/bin/rtklib_b34g/armv7l/convbin b/tools/bin/rtklib_b34g/armv7l/convbin deleted file mode 100755 index ad69eee5..00000000 Binary files a/tools/bin/rtklib_b34g/armv7l/convbin and /dev/null differ diff --git a/tools/bin/rtklib_b34g/x86/convbin b/tools/bin/rtklib_b34g/x86/convbin deleted file mode 100755 index 3128c75c..00000000 Binary files a/tools/bin/rtklib_b34g/x86/convbin and /dev/null differ diff --git a/tools/bin/rtklib_b34g/x86/rtkrcv b/tools/bin/rtklib_b34g/x86/rtkrcv deleted file mode 100755 index 00a7b763..00000000 Binary files a/tools/bin/rtklib_b34g/x86/rtkrcv and /dev/null differ diff --git a/tools/bin/rtklib_b34g/x86/str2str b/tools/bin/rtklib_b34g/x86/str2str deleted file mode 100755 index e667df9d..00000000 Binary files a/tools/bin/rtklib_b34g/x86/str2str and /dev/null differ diff --git a/tools/bin/rtklib_b34i/armv6l/compiled_with_buster b/tools/bin/rtklib_b34i/armv6l/compiled_with_buster new file mode 100644 index 00000000..e69de29b diff --git a/tools/bin/rtklib_b34i/armv6l/convbin b/tools/bin/rtklib_b34i/armv6l/convbin new file mode 100755 index 00000000..5598098a Binary files /dev/null and b/tools/bin/rtklib_b34i/armv6l/convbin differ diff --git a/tools/bin/rtklib_b34g/armv7l/rtkrcv b/tools/bin/rtklib_b34i/armv6l/rtkrcv similarity index 50% rename from tools/bin/rtklib_b34g/armv7l/rtkrcv rename to tools/bin/rtklib_b34i/armv6l/rtkrcv index c742b56b..197bf415 100755 Binary files a/tools/bin/rtklib_b34g/armv7l/rtkrcv and b/tools/bin/rtklib_b34i/armv6l/rtkrcv differ diff --git a/tools/bin/rtklib_b34g/armv7l/str2str b/tools/bin/rtklib_b34i/armv6l/str2str similarity index 52% rename from tools/bin/rtklib_b34g/armv7l/str2str rename to tools/bin/rtklib_b34i/armv6l/str2str index 1e955524..899a4199 100755 Binary files a/tools/bin/rtklib_b34g/armv7l/str2str and b/tools/bin/rtklib_b34i/armv6l/str2str differ diff --git a/tools/bin/rtklib_b34i/armv7l/compiled_with_buster b/tools/bin/rtklib_b34i/armv7l/compiled_with_buster new file mode 100644 index 00000000..e69de29b diff --git a/tools/bin/rtklib_b34i/armv7l/convbin b/tools/bin/rtklib_b34i/armv7l/convbin new file mode 100755 index 00000000..5598098a Binary files /dev/null and b/tools/bin/rtklib_b34i/armv7l/convbin differ diff --git a/tools/bin/rtklib_b34g/armv6l/rtkrcv b/tools/bin/rtklib_b34i/armv7l/rtkrcv similarity index 50% rename from tools/bin/rtklib_b34g/armv6l/rtkrcv rename to tools/bin/rtklib_b34i/armv7l/rtkrcv index baf4d8ba..197bf415 100755 Binary files a/tools/bin/rtklib_b34g/armv6l/rtkrcv and b/tools/bin/rtklib_b34i/armv7l/rtkrcv differ diff --git a/tools/bin/rtklib_b34g/armv6l/str2str b/tools/bin/rtklib_b34i/armv7l/str2str similarity index 51% rename from tools/bin/rtklib_b34g/armv6l/str2str rename to tools/bin/rtklib_b34i/armv7l/str2str index 8a021f9a..899a4199 100755 Binary files a/tools/bin/rtklib_b34g/armv6l/str2str and b/tools/bin/rtklib_b34i/armv7l/str2str differ diff --git a/tools/convbin.sh b/tools/convbin.sh index 954c4612..4732b4d2 100755 --- a/tools/convbin.sh +++ b/tools/convbin.sh @@ -1,13 +1,21 @@ #!/bin/bash #convert zipped raw file to rinex -#./convbin.sh ubx.zip directory mount-name raw_type - +#./convbin.sh ubx.zip directory rinex_type +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +source <( grep '=' "${SCRIPT_DIR}"/../settings.conf ) RAW_ARCHIVE=$1 DATA_DIR=$2 -MOUNT_NAME=$3 -RAW_TYPE=$4 -RINEX_TYPE=$5 +MOUNT_NAME=$mnt_name_a +RAW_TYPE=$receiver_format +RINEX_TYPE=$3 CONVBIN_PATH=$(type -P convbin) +ANT_POSITION=$(echo "${position}" | cs2cs EPSG:4979 EPSG:4978 -f "%.2f" | sed 's/\s/\//g') +RECEIVER="${receiver}" +REC_VERSION="${receiver_firmware}" +REC_OPTION='' +[[ -n $ntrip_a_receiver_options ]] && REC_OPTION="${ntrip_a_receiver_options}" +ANT_TYPE="${antenna_info}" +RTKBASE_VERSION='RTKBase v'"${version}" extract_raw_file() { raw_file=$(unzip -l "${RAW_ARCHIVE}" "*.${RAW_TYPE}" | awk '/-----/ {p = ++p % 2; next} p {print $NF}') @@ -20,40 +28,56 @@ extract_raw_file() { # Rinex v2.11 - 30s - GPS convert_to_rinex_ign() { echo "- CREATING RINEX " "${RINEX_FILE}" - "${CONVBIN_PATH}" "${raw_file}" -v 2.11 -r "${RAW_TYPE}" -hm "${MOUNT_NAME}" \ - -f 2 -y R -y E -y J -y S -y C -y I \ - -od -os -oi -ot -ti 30 -tt 0 -ro -TADJ=1 \ - -o "${RINEX_FILE}" + "${CONVBIN_PATH}" "${raw_file}" -v 2.11 -r "${RAW_TYPE}" \ + -hc "${RTKBASE_VERSION}" -hm "${MOUNT_NAME}" \ + -hp "${ANT_POSITION}" -ha 0000/"${ANT_TYPE}" \ + -hr 0000/"${RECEIVER}"/"${REC_VERSION}" \ + -f 2 -y R -y E -y J -y S -y C -y I \ + -od -os -oi -ot -ti 30 -tt 0.005 \ + -ro "${REC_OPTION}" -o "${RINEX_FILE}" return $? } +convert_to_rinex_ign_bis() { + echo "- CREATING RINEX " "${RINEX_FILE}" + args="${raw_file}"' -v 2.11 -r '"${RAW_TYPE}"' -hc '"${RTKBASE_VERSION}"' -hm '"${MOUNT_NAME}"' -hp '"${ANT_POSITION}"' -ha 0000/'"${ANT_TYPE}"' -hr 0000/'"${RECEIVER}"'/'"${REC_VERSION}"' -f 2 -y R -y E -y J -y S -y C -y I -od -os -oi -ot -ti 30 -tt 0 -ro '"${REC_OPTION}"' -o '"${RINEX_FILE}" + "${CONVBIN_PATH}" "${args}" + return $? +} # Rinex v3.04 - 30s - GPS + GLONASS convert_to_rinex_nrcan() { echo "- CREATING RINEX " "${RINEX_FILE}" - "${CONVBIN_PATH}" "${raw_file}" -v 3.04 -r "${RAW_TYPE}" -hm "${MOUNT_NAME}" \ - -f 2 -y E -y J -y S -y C -y I \ - -od -os -oi -ot -ti 30 -tt 0 -ro -TADJ=1 \ - -o "${RINEX_FILE}" + "${CONVBIN_PATH}" "${raw_file}" -v 3.04 -r "${RAW_TYPE}" \ + -hc "${RTKBASE_VERSION}" -hm "${MOUNT_NAME}" \ + -hp "${ANT_POSITION}" -ha 0000/"${ANT_TYPE}" \ + -hr 0000/"${RECEIVER}"/"${REC_VERSION}" \ + -f 2 -y E -y J -y S -y C -y I \ + -od -os -oi -ot -ti 30 -tt 0 \ + -ro "${REC_OPTION}" -o "${RINEX_FILE}" return $? } # Rinex v3.04 - 30s - GPS + GLONASS + GALILEO + BEIDOU + QZSS + NAVIC + SBAS convert_to_rinex_30s_full() { echo "- CREATING RINEX " "${RINEX_FILE}" - "${CONVBIN_PATH}" "${raw_file}" -v 3.04 -r "${RAW_TYPE}" -hm "${MOUNT_NAME}" \ - -f 2 -od -os -oi -ot -ti 30 -tt 0 \ - -ro -TADJ=1 \ - -o "${RINEX_FILE}" + "${CONVBIN_PATH}" "${raw_file}" -v 3.04 -r "${RAW_TYPE}" \ + -hc "${RTKBASE_VERSION}" -hm "${MOUNT_NAME}" \ + -hp "${ANT_POSITION}" -ha 0000/"${ANT_TYPE}" \ + -hr 0000/"${RECEIVER}"/"${REC_VERSION}" \ + -od -os -oi -ot -ti 30 -tt 0 \ + -ro "${REC_OPTION}" -o "${RINEX_FILE}" return $? } # Rinex v3.04 - 1s - GPS + GLONASS + GALILEO + BEIDOU + QZSS + NAVIC + SBAS convert_to_rinex_1s_full() { echo "- CREATING RINEX " "${RINEX_FILE}" - "${CONVBIN_PATH}" "${raw_file}" -v 3.04 -r "${RAW_TYPE}" -hm "${MOUNT_NAME}" \ - -f 2 -od -os -oi -ot -ti 1 -tt 0 \ - -ro -TADJ=1 \ - -o "${RINEX_FILE}" + "${CONVBIN_PATH}" "${raw_file}" -v 3.04 -r "${RAW_TYPE}" \ + -hc "${RTKBASE_VERSION}" -hm "${MOUNT_NAME}" \ + -hp "${ANT_POSITION}" -ha 0000/"${ANT_TYPE}" \ + -hr 0000/"${RECEIVER}"/"${REC_VERSION}" \ + -od -os -oi -ot -ti 1 -tt 0 \ + -ro "${REC_OPTION}" -o "${RINEX_FILE}" return $? } diff --git a/tools/copy_unit.sh b/tools/copy_unit.sh index 3687f61c..1e8ac65f 100755 --- a/tools/copy_unit.sh +++ b/tools/copy_unit.sh @@ -6,6 +6,9 @@ man_help() { echo 'Options:' echo ' -h | --help' + echo ' -p | --python_path' + echo ' path to the web app python venv binary' + echo ' (usually /home/your_username/rtkbase/venv/bin/python)' echo ' -u | --user ' echo ' Specify user used in the service unit. Without this argument' echo ' the user return by the logname command will be used.' @@ -14,8 +17,9 @@ man_help() { BASEDIR=$(dirname "$0") ARG_HELP=0 +ARG_PYPATH=0 ARG_USER=0 -PARSED_ARGUMENTS=$(getopt --name copy_unit --options hu: --longoptions help,user: -- "$@") +PARSED_ARGUMENTS=$(getopt --name copy_unit --options hp:u: --longoptions help,python_path:,user: -- "$@") VALID_ARGUMENTS=$? if [ "$VALID_ARGUMENTS" != "0" ]; then #man_help @@ -27,8 +31,9 @@ if [ "$VALID_ARGUMENTS" != "0" ]; then while : do case "$1" in - -h | --help) ARG_HELP=1 ; shift ;; - -u | --user) ARG_USER="${2}" ; shift 2 ;; + -h | --help) ARG_HELP=1 ; shift ;; + -p | --python_path) ARG_PYPATH="${2}" ; shift 2 ;; + -u | --user) ARG_USER="${2}" ; shift 2 ;; # -- means the end of the arguments; drop this, and break out of the while loop --) shift; break ;; # If invalid options were passed, then getopt should have reported an error, @@ -38,6 +43,7 @@ if [ "$VALID_ARGUMENTS" != "0" ]; then esac done [ $ARG_HELP -eq 1 ] && man_help +[ "${ARG_PYPATH}" == 0 ] && echo 'Please enter the python venv path with the -p argument' && exit [ "${ARG_USER}" == 0 ] && ARG_USER=$(logname) #echo 'user=' "${ARG_USER}" @@ -50,7 +56,7 @@ for file_path in "${BASEDIR}"/../unit/*.service "${BASEDIR}"/../unit/*.timer do file_name=$(basename "${file_path}") echo copying "${file_name}" - sed -e 's|{script_path}|'"$(dirname "$(dirname "$(readlink -f "$0")")")"'|' -e 's|{user}|'"${ARG_USER}"'|' -e 's|{python_path}|'"$(which python3)"'|' "${file_path}" > /etc/systemd/system/"${file_name}" + sed -e 's|{script_path}|'"$(dirname "$(dirname "$(readlink -f "$0")")")"'|' -e 's|{user}|'"${ARG_USER}"'|' -e 's|{python_path}|'"${ARG_PYPATH}"'|' "${file_path}" > /etc/systemd/system/"${file_name}" done systemctl daemon-reload diff --git a/tools/create_release.sh b/tools/create_release.sh index ac8978ef..6efe4089 100755 --- a/tools/create_release.sh +++ b/tools/create_release.sh @@ -23,6 +23,7 @@ tar --exclude-vcs \ --exclude='rtkbase/.vscode' \ --exclude='rtkbase/.github' \ --exclude='rtkbase/settings.conf' \ + --exclude='rtkbase/venv' \ --exclude='test.sh' \ --exclude='test.conf' \ --exclude='*.pyc' \ diff --git a/tools/install.sh b/tools/install.sh index aab0726a..204ef656 100755 --- a/tools/install.sh +++ b/tools/install.sh @@ -37,8 +37,8 @@ man_help(){ echo ' Install all dependencies like git build-essential python3-pip ...' echo '' echo ' -r | --rtklib' - echo ' Get RTKlib 2.4.3b34g from github and compile it.' - echo ' https://github.com/rtklibexplorer/RTKLIB/tree/b34g' + echo ' Get RTKlib 2.4.3b34i from github and compile it.' + echo ' https://github.com/rtklibexplorer/RTKLIB/tree/b34i' echo '' echo ' -b | --rtkbase-release' echo ' Get last release of RTKBase:' @@ -60,12 +60,12 @@ man_help(){ echo ' Install gpsd and chrony to set date and time' echo ' from the gnss receiver.' echo '' - echo ' -e | --detect-usb-gnss' - echo ' Detect your GNSS receiver. It works only with usb-connected receiver like ZED-F9P.' + echo ' -e | --detect-gnss' + echo ' Detect your GNSS receiver. It works only with receiver like ZED-F9P.' echo '' echo ' -n | --no-write-port' echo ' Doesn'\''t write the detected port inside settings.conf.' - echo ' Only relevant with --detect-usb-gnss argument.' + echo ' Only relevant with --detect-gnss argument.' echo '' echo ' -c | --configure-gnss' echo ' Configure your GNSS receiver.' @@ -103,8 +103,9 @@ install_dependencies() { echo '################################' echo 'INSTALLING DEPENDENCIES' echo '################################' - apt-get "${APT_TIMEOUT}" update || exit 1 - apt-get "${APT_TIMEOUT}" install -y git build-essential pps-tools python3-pip python3-dev python3-setuptools python3-wheel libsystemd-dev bc dos2unix socat zip unzip pkg-config psmisc || exit 1 + apt-get "${APT_TIMEOUT}" update -y || exit 1 + apt-get "${APT_TIMEOUT}" install -y git build-essential pps-tools python3-pip python3-venv python3-dev python3-setuptools python3-wheel python3-serial libsystemd-dev bc dos2unix socat zip unzip pkg-config psmisc proj-bin || exit 1 + apt-get install -y libxml2-dev libxslt-dev || exit 1 # needed for lxml (for pystemd) #apt-get "${APT_TIMEOUT}" upgrade -y } @@ -129,7 +130,7 @@ install_gpsd_chrony() { sed -i s/^After=.*/After=gpsd.service/ /etc/systemd/system/chrony.service #If needed, adding backports repository to install a gpsd release that support the F9P - if lsb_release -c | grep -qE 'bionic|buster' + if lsb_release -sc | grep -qE 'bionic|buster' then if ! apt-cache policy | grep -qE 'buster-backports.* armhf' then @@ -173,35 +174,43 @@ install_rtklib() { echo 'INSTALLING RTKLIB' echo '################################' arch_package=$(uname -m) - [[ $arch_package == 'x86_64' ]] && arch_package='x86' - if [[ -f "${rtkbase_path}"'/tools/bin/rtklib_b34g/'"${arch_package}"'/str2str' ]] + #[[ $arch_package == 'x86_64' ]] && arch_package='x86' + [[ -f /sys/firmware/devicetree/base/model ]] && computer_model=$(tr -d '\0' < /sys/firmware/devicetree/base/model) + # convert "Raspberry Pi 3 Model B plus rev 1.3" or other Raspi model to the variable "Raspberry Pi" + [ -n "${computer_model}" ] && [ -z "${computer_model##*'Raspberry Pi'*}" ] && computer_model='Raspberry Pi' + sbc_array=('Xunlong Orange Pi Zero' 'Raspberry Pi') + #test if computer_model in sbc_array (https://stackoverflow.com/questions/3685970/check-if-a-bash-array-contains-a-value) + if printf '%s\0' "${sbc_array[@]}" | grep -Fxqz -- "${computer_model}" \ + && [[ -f "${rtkbase_path}"'/tools/bin/rtklib_b34i/'"${arch_package}"'/str2str' ]] \ + && lsb_release -c | grep -qE 'buster|bullseye|bookworm' then - echo 'Copying new rtklib binary for ' "${arch_package}" - cp "${rtkbase_path}"'/tools/bin/rtklib_b34g/'"${arch_package}"/str2str /usr/local/bin/ - cp "${rtkbase_path}"'/tools/bin/rtklib_b34g/'"${arch_package}"/rtkrcv /usr/local/bin/ - cp "${rtkbase_path}"'/tools/bin/rtklib_b34g/'"${arch_package}"/convbin /usr/local/bin/ + echo 'Copying new rtklib binary for ' "${computer_model}" ' - ' "${arch_package}" + cp "${rtkbase_path}"'/tools/bin/rtklib_b34i/'"${arch_package}"/str2str /usr/local/bin/ + cp "${rtkbase_path}"'/tools/bin/rtklib_b34i/'"${arch_package}"/rtkrcv /usr/local/bin/ + cp "${rtkbase_path}"'/tools/bin/rtklib_b34i/'"${arch_package}"/convbin /usr/local/bin/ else - echo 'No binary available for ' "${arch_package}" '. We will build it from source' + echo 'No binary available for ' "${computer_model}" ' - ' "${arch_package}" '. We will build it from source' + echo 'exit test' ; exit _compil_rtklib fi } _compil_rtklib() { echo '################################' - echo 'COMPILING RTKLIB' + echo 'COMPILING RTKLIB 2.4.3 b34i' echo '################################' - #Get Rtklib 2.4.3 b34g release - sudo -u "${RTKBASE_USER}" wget -qO - https://github.com/rtklibexplorer/RTKLIB/archive/refs/tags/b34g.tar.gz | tar -xvz + #Get Rtklib 2.4.3 b34i release + sudo -u "${RTKBASE_USER}" wget -qO - https://github.com/rtklibexplorer/RTKLIB/archive/refs/tags/b34i.tar.gz | tar -xvz #Install Rtklib app #TODO add correct CTARGET in makefile? - make --directory=RTKLIB-b34g/app/consapp/str2str/gcc - make --directory=RTKLIB-b34g/app/consapp/str2str/gcc install - make --directory=RTKLIB-b34g/app/consapp/rtkrcv/gcc - make --directory=RTKLIB-b34g/app/consapp/rtkrcv/gcc install - make --directory=RTKLIB-b34g/app/consapp/convbin/gcc - make --directory=RTKLIB-b34g/app/consapp/convbin/gcc install + make --directory=RTKLIB-b34i/app/consapp/str2str/gcc + make --directory=RTKLIB-b34i/app/consapp/str2str/gcc install + make --directory=RTKLIB-b34i/app/consapp/rtkrcv/gcc + make --directory=RTKLIB-b34i/app/consapp/rtkrcv/gcc install + make --directory=RTKLIB-b34i/app/consapp/convbin/gcc + make --directory=RTKLIB-b34i/app/consapp/convbin/gcc install #deleting RTKLIB - rm -rf RTKLIB-b34g/ + rm -rf RTKLIB-b34i/ } _rtkbase_repo(){ @@ -211,7 +220,6 @@ _rtkbase_repo(){ else sudo -u "${RTKBASE_USER}" git clone https://github.com/stefal/rtkbase.git fi - sudo -u "${RTKBASE_USER}" touch rtkbase/settings.conf _add_rtkbase_path_to_environment } @@ -220,7 +228,6 @@ _rtkbase_release(){ #Get rtkbase latest release sudo -u "${RTKBASE_USER}" wget https://github.com/stefal/rtkbase/releases/latest/download/rtkbase.tar.gz -O rtkbase.tar.gz sudo -u "${RTKBASE_USER}" tar -xvf rtkbase.tar.gz - sudo -u "${RTKBASE_USER}" touch rtkbase/settings.conf _add_rtkbase_path_to_environment } @@ -279,7 +286,6 @@ install_rtkbase_custom_source() { else sudo -u "${RTKBASE_USER}" wget "${1}" -O rtkbase.tar.gz sudo -u "${RTKBASE_USER}" tar -xvf rtkbase.tar.gz - sudo -u "${RTKBASE_USER}" touch rtkbase/settings.conf _add_rtkbase_path_to_environment fi } @@ -299,7 +305,6 @@ install_rtkbase_bundled() { # Check if there is some content after __ARCHIVE__ marker (more than 100 lines) [[ $(sed -n '/__ARCHIVE__/,$p' "${0}" | wc -l) -lt 100 ]] && echo "RTKBASE isn't bundled inside install.sh. Please choose another source" && exit 1 sudo -u "${RTKBASE_USER}" tail -n+${ARCHIVE} "${0}" | tar xpJv && \ - sudo -u "${RTKBASE_USER}" touch rtkbase/settings.conf _add_rtkbase_path_to_environment } @@ -326,29 +331,40 @@ rtkbase_requirements(){ echo '################################' echo 'INSTALLING RTKBASE REQUIREMENTS' echo '################################' - #as we need to run the web server as root, we need to install the requirements with - #the same user + # create virtual environnement for rtkbase + sudo -u "${RTKBASE_USER}" python3 -m venv "${rtkbase_path}"/venv + python_venv="${rtkbase_path}"/venv/bin/python platform=$(uname -m) if [[ $platform =~ 'aarch64' ]] || [[ $platform =~ 'x86_64' ]] then # More dependencies needed for aarch64 as there is no prebuilt wheel on piwheels.org apt-get "${APT_TIMEOUT}" install -y libssl-dev libffi-dev || exit 1 - fi + fi # Copying udev rules [[ ! -d /etc/udev/rules.d ]] && mkdir /etc/udev/rules.d/ - cp "${rtkbase_path}"/tools/90-usb-simcom-at.rules /etc/rules.d/ + cp "${rtkbase_path}"/tools/udev_rules/*.rules /etc/udev/rules.d/ udevadm control --reload && udevadm trigger - - python3 -m pip install --upgrade pip setuptools wheel --extra-index-url https://www.piwheels.org/simple - # install prebuilt wheel for cryptography because it is unavailable on piwheels (2023/01) - if [[ $platform == 'armv7l' ]] && [[ $(python3 --version) =~ '3.7' ]] - then - python3 -m pip install "${rtkbase_path}"/tools/wheel/cryptography-38.0.0-cp37-cp37m-linux_armv7l.whl - elif [[ $platform == 'armv6l' ]] && [[ $(python3 --version) =~ '3.7' ]] - then - python3 -m pip install "${rtkbase_path}"/tools/wheel/cryptography-38.0.0-cp37-cp37m-linux_armv6l.whl + # Copying polkitd rules and add rtkbase group + "${rtkbase_path}"/tools/install_polkit_rules.sh "${RTKBASE_USER}" + #Copying settings.conf.default as settings.conf + if [[ ! -f "${rtkbase_path}/settings.conf" ]] + then + cp "${rtkbase_path}/settings.conf.default" "${rtkbase_path}/settings.conf" fi - python3 -m pip install -r "${rtkbase_path}"/web_app/requirements.txt --extra-index-url https://www.piwheels.org/simple + #Then launch check cpu temp script for OPI zero LTS + source "${rtkbase_path}/tools/opizero_temp_offset.sh" + #venv module installation + sudo -u "${RTKBASE_USER}" "${python_venv}" -m pip install --upgrade pip setuptools wheel --extra-index-url https://www.piwheels.org/simple + # install prebuilt wheel for cryptography because it is unavailable on piwheels (2023/01) + # not needed anymore (2023/11) + #if [[ $platform == 'armv7l' ]] && [[ $("${python_venv}" --version) =~ '3.7' ]] + # then + # sudo -u "${RTKBASE_USER}" "${python_venv}" -m pip install "${rtkbase_path}"/tools/wheel/cryptography-38.0.0-cp37-cp37m-linux_armv7l.whl + #elif [[ $platform == 'armv6l' ]] && [[ $("${python_venv}" --version) =~ '3.7' ]] + # then + # sudo -u "${RTKBASE_USER}" "${python_venv}" -m pip install "${rtkbase_path}"/tools/wheel/cryptography-38.0.0-cp37-cp37m-linux_armv6l.whl + #fi + sudo -u "${RTKBASE_USER}" "${python_venv}" -m pip install -r "${rtkbase_path}"/web_app/requirements.txt --extra-index-url https://www.piwheels.org/simple #when we will be able to launch the web server without root, we will use #sudo -u $(logname) python3 -m pip install -r requirements.txt --user. } @@ -360,7 +376,7 @@ install_unit_files() { if [ -d "${rtkbase_path}" ] then #Install unit files - "${rtkbase_path}"/tools/copy_unit.sh --user "${RTKBASE_USER}" + "${rtkbase_path}"/tools/copy_unit.sh --python_path "${rtkbase_path}"/venv/bin/python --user "${RTKBASE_USER}" systemctl enable rtkbase_web.service systemctl enable rtkbase_archive.timer systemctl daemon-reload @@ -371,7 +387,7 @@ install_unit_files() { fi } -detect_usb_gnss() { +detect_gnss() { echo '################################' echo 'USB GNSS RECEIVER DETECTION' echo '################################' @@ -429,6 +445,9 @@ detect_usb_gnss() { fi # Test if speed is in detected_gnss array. If not, add the default value. [[ ${#detected_gnss[*]} -eq 2 ]] && detected_gnss[2]='115200' + # If /dev/ttyGNSS is a symlink of the detected serial port, switch to ttyGNSS + [[ '/dev/ttyGNSS' -ef '/dev/'"${detected_gnss[0]}" ]] && detected_gnss[0]='ttyGNSS' + # "send" result echo '/dev/'"${detected_gnss[0]}" ' - ' "${detected_gnss[1]}"' - ' "${detected_gnss[2]}" #Write Gnss receiver settings inside settings.conf @@ -447,11 +466,8 @@ detect_usb_gnss() { sudo -u "${RTKBASE_USER}" sed -i s/^com_port_settings=.*/com_port_settings=\'${detected_gnss[2]}:8:n:1\'/ "${rtkbase_path}"/settings.conf else - #create settings.conf with the com_port setting and the settings needed to start str2str_tcp - #as it could start before the web server merge settings.conf.default and settings.conf - sudo -u "${RTKBASE_USER}" printf "[main]\ncom_port='"${detected_gnss[0]}"'\ncom_port_settings='"${detected_gnss[2]}":8:n:1'\nreceiver=''\nreceiver_format=''\nreceiver_firmware=''\ntcp_port='5015'\n" > "${rtkbase_path}"/settings.conf - #add empty *_receiver_options on rtcm/ntrip_a/ntrip_b/serial outputs. - sudo -u "${RTKBASE_USER}" printf "[ntrip_A]\nntrip_a_receiver_options=''\n[ntrip_B]\nntrip_b_receiver_options=''\n[local_ntrip_caster]\nlocal_ntripc_receiver_options=''\n[rtcm_svr]\nrtcm_receiver_options=''\n[rtcm_serial]\nrtcm_serial_receiver_options=''\n" >> "${rtkbase_path}"/settings.conf + echo 'settings.conf is missing' + return 1 fi elif [[ ${#detected_gnss[*]} -ne 3 ]] then @@ -477,7 +493,7 @@ configure_gnss(){ echo '################################' if [ -d "${rtkbase_path}" ] then - source <( grep = "${rtkbase_path}"/settings.conf ) + source <( grep '=' "${rtkbase_path}"/settings.conf ) systemctl is-active --quiet str2str_tcp.service && sudo systemctl stop str2str_tcp.service #if the receiver is a U-Blox, launch the set_zed-f9p.sh. This script will reset the F9P and configure it with the corrects settings for rtkbase #!!!!!!!!! CHECK THIS ON A REAL raspberry/orange Pi !!!!!!!!!!! @@ -487,7 +503,7 @@ configure_gnss(){ firmware=$(python3 "${rtkbase_path}"/tools/ubxtool -f /dev/"${com_port}" -s ${com_port_settings%%:*} -p MON-VER | grep 'FWVER' | awk '{print $NF}') sudo -u "${RTKBASE_USER}" sed -i s/^receiver_firmware=.*/receiver_firmware=\'${firmware}\'/ "${rtkbase_path}"/settings.conf #configure the F9P for RTKBase - "${rtkbase_path}"/tools/set_zed-f9p.sh /dev/${com_port} ${com_port_settings%%:*} "${rtkbase_path}"/receiver_cfg/U-Blox_ZED-F9P_rtkbase.cfg && \ + "${rtkbase_path}"/tools/set_zed-f9p.sh /dev/${com_port} ${com_port_settings%%:*} "${rtkbase_path}"/receiver_cfg/U-Blox_ZED-F9P_rtkbase.cfg && \ #now that the receiver is configured, we can set the right values inside settings.conf sudo -u "${RTKBASE_USER}" sed -i s/^com_port_settings=.*/com_port_settings=\'115200:8:n:1\'/ "${rtkbase_path}"/settings.conf && \ sudo -u "${RTKBASE_USER}" sed -i s/^receiver=.*/receiver=\'U-blox_ZED-F9P\'/ "${rtkbase_path}"/settings.conf && \ @@ -497,7 +513,10 @@ configure_gnss(){ sudo -u "${RTKBASE_USER}" sed -i s/^ntrip_b_receiver_options=.*/ntrip_b_receiver_options=\'-TADJ=1\'/ "${rtkbase_path}"/settings.conf && \ sudo -u "${RTKBASE_USER}" sed -i s/^local_ntripc_receiver_options=.*/local_ntripc_receiver_options=\'-TADJ=1\'/ "${rtkbase_path}"/settings.conf && \ sudo -u "${RTKBASE_USER}" sed -i s/^rtcm_receiver_options=.*/rtcm_receiver_options=\'-TADJ=1\'/ "${rtkbase_path}"/settings.conf && \ - sudo -u "${RTKBASE_USER}" sed -i s/^rtcm_serial_receiver_options=.*/rtcm_serial_receiver_options=\'-TADJ=1\'/ "${rtkbase_path}"/settings.conf + sudo -u "${RTKBASE_USER}" sed -i s/^rtcm_serial_receiver_options=.*/rtcm_serial_receiver_options=\'-TADJ=1\'/ "${rtkbase_path}"/settings.conf && \ + #remove SBAS Rtcm message (1107) as it is disabled in the F9P configuration. + sudo -u "${RTKBASE_USER}" sed -i -r '/^rtcm_/s/1107(\([0-9]+\))?,//' "${rtkbase_path}"/settings.conf && \ + return $? else echo 'No Gnss receiver has been set. We can'\''t configure' @@ -546,15 +565,18 @@ _add_modem_port(){ sudo -u "${RTKBASE_USER}" sed -i s\!^modem_at_port=.*\!modem_at_port=\'${MODEM_AT_PORT}\'! "${rtkbase_path}"/settings.conf elif [[ -f "${rtkbase_path}/settings.conf" ]] && ! grep -qE "^modem_at_port=.*" "${rtkbase_path}"/settings.conf #check if settings.conf exists without modem_at_port entry then - sudo -u "${RTKBASE_USER}" printf "[network]\nmodem_at_port='"${MODEM_AT_PORT}"'" >> "${rtkbase_path}"/settings.conf + printf "[network]\nmodem_at_port='%s'\n" "${MODEM_AT_PORT}"| sudo tee -a "${rtkbase_path}"/settings.conf > /dev/null + elif [[ ! -f "${rtkbase_path}/settings.conf" ]] then #create settings.conf with the modem_at_port setting - sudo -u "${RTKBASE_USER}" printf "[network]\nmodem_at_port='"${MODEM_AT_PORT}"'" > "${rtkbase_path}"/settings.conf + echo 'settings.conf is missing' + return 1 fi } _configure_modem(){ + sudo -u "${RTKBASE_USER}" "${rtkbase_path}/venv/bin/python" -m pip install nmcli --extra-index-url https://www.piwheels.org/simple python3 "${rtkbase_path}"/tools/modem_config.py --config "${rtkbase_path}"/tools/lte_network_mgmt.sh --connection_rename --lte_priority } @@ -616,14 +638,14 @@ main() { ARG_RTKBASE_RQS=0 ARG_UNIT=0 ARG_GPSD_CHRONY=0 - ARG_DETECT_USB_GNSS=0 + ARG_DETECT_GNSS=0 ARG_NO_WRITE_PORT=0 ARG_CONFIGURE_GNSS=0 ARG_DETECT_MODEM=0 ARG_START_SERVICES=0 ARG_ALL=0 - PARSED_ARGUMENTS=$(getopt --name install --options hu:drbi:jf:qtgencmsa: --longoptions help,user:,dependencies,rtklib,rtkbase-release,rtkbase-repo:,rtkbase-bundled,rtkbase-custom:,rtkbase-requirements,unit-files,gpsd-chrony,detect-usb-gnss,no-write-port,configure-gnss,detect-modem,start-services,all: -- "$@") + PARSED_ARGUMENTS=$(getopt --name install --options hu:drbi:jf:qtgencmsa: --longoptions help,user:,dependencies,rtklib,rtkbase-release,rtkbase-repo:,rtkbase-bundled,rtkbase-custom:,rtkbase-requirements,unit-files,gpsd-chrony,detect-gnss,no-write-port,configure-gnss,detect-modem,start-services,all: -- "$@") VALID_ARGUMENTS=$? if [ "$VALID_ARGUMENTS" != "0" ]; then #man_help @@ -647,7 +669,7 @@ main() { -q | --rtkbase-requirements) ARG_RTKBASE_RQS=1 ; shift ;; -t | --unit-files) ARG_UNIT=1 ; shift ;; -g | --gpsd-chrony) ARG_GPSD_CHRONY=1 ; shift ;; - -e | --detect-usb-gnss) ARG_DETECT_USB_GNSS=1 ; shift ;; + -e | --detect-gnss) ARG_DETECT_GNSS=1 ; shift ;; -n | --no-write-port) ARG_NO_WRITE_PORT=1 ; shift ;; -c | --configure-gnss) ARG_CONFIGURE_GNSS=1 ; shift ;; -m | --detect-modem) ARG_DETECT_MODEM=1 ; shift ;; @@ -692,8 +714,9 @@ main() { install_rtklib && \ install_unit_files && \ install_gpsd_chrony - [[ $? != 0 ]] && ((cumulative_exit+=$?)) - detect_usb_gnss && \ + ret=$? + [[ $ret != 0 ]] && ((cumulative_exit+=ret)) + detect_gnss && \ configure_gnss start_services ; ((cumulative_exit+=$?)) [[ $cumulative_exit != 0 ]] && echo -e '\n\n Warning! Some errors happened during installation!' @@ -709,7 +732,7 @@ main() { [ $ARG_RTKBASE_RQS -eq 1 ] && { rtkbase_requirements ; ((cumulative_exit+=$?)) ;} [ $ARG_UNIT -eq 1 ] && { install_unit_files ; ((cumulative_exit+=$?)) ;} [ $ARG_GPSD_CHRONY -eq 1 ] && { install_gpsd_chrony ; ((cumulative_exit+=$?)) ;} - [ $ARG_DETECT_USB_GNSS -eq 1 ] && { detect_usb_gnss "${ARG_NO_WRITE_PORT}" ; ((cumulative_exit+=$?)) ;} + [ $ARG_DETECT_GNSS -eq 1 ] && { detect_gnss "${ARG_NO_WRITE_PORT}" ; ((cumulative_exit+=$?)) ;} [ $ARG_CONFIGURE_GNSS -eq 1 ] && { configure_gnss ; ((cumulative_exit+=$?)) ;} [ $ARG_DETECT_MODEM -eq 1 ] && { detect_usb_modem && _add_modem_port && _configure_modem ; ((cumulative_exit+=$?)) ;} [ $ARG_START_SERVICES -eq 1 ] && { start_services ; ((cumulative_exit+=$?)) ;} diff --git a/tools/install_polkit_rules.sh b/tools/install_polkit_rules.sh new file mode 100755 index 00000000..816e2ccc --- /dev/null +++ b/tools/install_polkit_rules.sh @@ -0,0 +1,19 @@ +#!/bin/bash +#script to install the policykit rules which let manage the rtkbase services without root. +#the user needs to be member of rtkbase group + +RTKBASE_USER=$1 +[[ -z "${RTKBASE_USER}" ]] && echo 'Please specify a username' && exit 1 +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +add_polkit_rules() { + cp "${SCRIPT_DIR}"/polkit/*.rules /etc/polkit-1/rules.d/ && \ + groupadd -f rtkbase && \ + usermod -a -G rtkbase "${RTKBASE_USER}" +} + +#check if polkitd package is available, else exit +apt-cache --quiet=0 show polkitd 2>&1 | grep -q 'No packages found' && exit 1 +#install it if not already installed +! dpkg-query -W --showformat='${Status}\n' polkitd >/dev/null 2>&1 && apt-get -y install polkitd +add_polkit_rules \ No newline at end of file diff --git a/tools/opizero_temp_offset.sh b/tools/opizero_temp_offset.sh new file mode 100755 index 00000000..7c4ce668 --- /dev/null +++ b/tools/opizero_temp_offset.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +detect_sbc_temp_offset(){ + #Detect if the computer is a Orange Pi Zero, and if the cpu temps is lower than 30°C, it looks like it's a Orange Pi zero LTS with a 30°C offset + [[ -f /sys/firmware/devicetree/base/model ]] && computer_model=$(tr -d '\0' < /sys/firmware/devicetree/base/model) + cpu_temp=$(($(cat /sys/class/thermal/thermal_zone0/temp)/1000)) + if [[ $computer_model = 'Xunlong Orange Pi Zero' ]] && [[ cpu_temp -lt 30 ]] + then + echo 'Adding 30°C offset' + if [[ -f "${rtkbase_path}/settings.conf" ]] && grep -qE "^cpu_temp_offset=.*" "${rtkbase_path}"/settings.conf #check if settings.conf exists + then + #change the cpu_temp_offset value/settings inside settings.conf + sed -i s/^cpu_temp_offset=.*/cpu_temp_offset=30/ "${rtkbase_path}"/settings.conf + elif [[ -f "${rtkbase_path}/settings.conf" ]] + then + sed -i '/^\[general\]/a cpu_temp_offset=30' "${rtkbase_path}"/settings.conf + else + #create settings.conf with the cpu_temp_offset setting + #as it could start before the web server merge settings.conf.default and settings.conf + printf "[general]\ncpu_temp_offset=30" > "${rtkbase_path}"/settings.conf + fi + fi +} + +if [[ -n "${rtkbase_path}" ]] + then + detect_sbc_temp_offset + else + echo 'RTKBase path unknown. Exiting' + exit 1 +fi \ No newline at end of file diff --git a/tools/polkit/99-rtkbase.rules b/tools/polkit/99-rtkbase.rules new file mode 100644 index 00000000..e5c62345 --- /dev/null +++ b/tools/polkit/99-rtkbase.rules @@ -0,0 +1,17 @@ +polkit.addRule(function(action, subject) { + if (action.id == "org.freedesktop.systemd1.manage-units" && + RegExp('str2str_[A-Za-z0-9]+.service').test(action.lookup("unit")) === true && + subject.isInGroup("rtkbase")) + { + return polkit.Result.YES; + } + }); + +polkit.addRule(function(action, subject) { + if (action.id == "org.freedesktop.systemd1.manage-units" && + RegExp('rtkbase_[A-Za-z0-9]+.service').test(action.lookup("unit")) === true && + subject.isInGroup("rtkbase")) + { + return polkit.Result.YES; + } + }); \ No newline at end of file diff --git a/tools/set_zed-f9p.sh b/tools/set_zed-f9p.sh index f1921404..9d94e1e4 100755 --- a/tools/set_zed-f9p.sh +++ b/tools/set_zed-f9p.sh @@ -25,7 +25,7 @@ set_F9P() { echo 'Sending settings....' while read setting; do - python3 ${BASEDIR}/ubxtool -s 115200 -z $setting + python3 ${BASEDIR}/ubxtool -s 115200 -z $setting > /dev/null ((return_val+=$?)) done <${CONFIG} sleep 2 diff --git a/tools/90-usb-simcom-at.rules b/tools/udev_rules/90-usb-simcom-at.rules similarity index 100% rename from tools/90-usb-simcom-at.rules rename to tools/udev_rules/90-usb-simcom-at.rules diff --git a/tools/udev_rules/91-gnss.rules b/tools/udev_rules/91-gnss.rules new file mode 100644 index 00000000..c9baa220 --- /dev/null +++ b/tools/udev_rules/91-gnss.rules @@ -0,0 +1 @@ +SUBSYSTEM=="tty", ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a9", SYMLINK+="ttyGNSS" diff --git a/tools/uninstall.sh b/tools/uninstall.sh index 80c7add9..dde38774 100755 --- a/tools/uninstall.sh +++ b/tools/uninstall.sh @@ -2,7 +2,7 @@ BASEDIR=$(dirname "$0") -#removing services +# removing services for service_name in str2str_tcp.service \ str2str_ntrip_A.service \ str2str_ntrip_B.service \ @@ -12,7 +12,9 @@ for service_name in str2str_tcp.service \ str2str_file.service \ rtkbase_web \ rtkbase_archive.service \ - rtkbase_archive.timer + rtkbase_archive.timer \ + modem_public_ip.service \ + modem_public_ip.timer do echo 'Deleting ' "${service_name}" systemctl stop "${service_name}" @@ -23,16 +25,20 @@ do systemctl reset-failed done -#removing rtklib binaries +# removing rtklib binaries echo 'Deleting RTKLib binaries' rm /usr/bin/str2str rm /usr/bin/conv2bin rm /usr/bin/rtkrcv -#removing Python modules -# Too dangerous without running RTKBase in a venv ? +# removing udev and polkitd rules +echo 'Deleting udev rules' +rm /etc/udev/rules.d/90-usb-simcom-at.rules +rm /etc/udev/rules.d/91-gnss.rules +echo 'Deleting polkitd rules' +rm /etc/polkit-1/rules.d/99-rtkbase.rules -#removing rtkbase folder +# removing rtkbase folder echo 'Deleting rtkbase directory' rtkbase_dir=$(builtin cd "${BASEDIR}"/.. ; pwd) echo 'Deleting ' "${rtkbase_dir}" diff --git a/unit/modem_public_ip.service b/unit/modem_public_ip.service index 0e82ef9a..76c553c8 100644 --- a/unit/modem_public_ip.service +++ b/unit/modem_public_ip.service @@ -7,6 +7,10 @@ Wants=network-online.target Type=simple User={user} ExecStart={python_path} {script_path}/tools/switch_to_public_ip.py +Restart=on-failure +RestartSec=30 +ProtectHome=read-only +ProtectSystem=strict [Install] WantedBy=multi-user.target diff --git a/unit/rtkbase_archive.service b/unit/rtkbase_archive.service index 4beae3f1..b05671f8 100644 --- a/unit/rtkbase_archive.service +++ b/unit/rtkbase_archive.service @@ -5,3 +5,6 @@ Description=RTKBase - Archiving and cleaning raw data Type=oneshot User={user} ExecStart={script_path}/archive_and_clean.sh +ProtectHome=read-only +ProtectSystem=strict +ReadWritePaths={script_path} diff --git a/unit/rtkbase_web.service b/unit/rtkbase_web.service index c85e6f59..09f0c6ac 100644 --- a/unit/rtkbase_web.service +++ b/unit/rtkbase_web.service @@ -8,6 +8,9 @@ User=root ExecStart={python_path} {script_path}/web_app/server.py Restart=on-failure RestartSec=30 +#ProtectHome=read-only +#ProtectSystem=strict +#ReadWritePaths={script_path} /var/tmp /usr/local/bin [Install] WantedBy=multi-user.target diff --git a/unit/str2str_file.service b/unit/str2str_file.service index a5e17ecb..2526a764 100644 --- a/unit/str2str_file.service +++ b/unit/str2str_file.service @@ -11,6 +11,9 @@ RestartSec=30 #Limiting log to 1 msg per minute LogRateLimitIntervalSec=1 minute LogRateLimitBurst=1 +ProtectHome=read-only +ProtectSystem=strict +ReadWritePaths={script_path} [Install] WantedBy=multi-user.target diff --git a/unit/str2str_local_ntrip_caster.service b/unit/str2str_local_ntrip_caster.service index 974f63a3..038f96e0 100644 --- a/unit/str2str_local_ntrip_caster.service +++ b/unit/str2str_local_ntrip_caster.service @@ -13,6 +13,9 @@ RestartSec=30 #Limiting log to 1 msg per minute LogRateLimitIntervalSec=1 minute LogRateLimitBurst=1 +ProtectHome=read-only +ProtectSystem=strict +ReadWritePaths={script_path} [Install] WantedBy=multi-user.target diff --git a/unit/str2str_ntrip_A.service b/unit/str2str_ntrip_A.service index 70c5f6d5..9cbd7641 100644 --- a/unit/str2str_ntrip_A.service +++ b/unit/str2str_ntrip_A.service @@ -13,6 +13,9 @@ RestartSec=30 #Limiting log to 1 msg per minute LogRateLimitIntervalSec=1 minute LogRateLimitBurst=1 +ProtectHome=read-only +ProtectSystem=strict +ReadWritePaths={script_path} [Install] WantedBy=multi-user.target diff --git a/unit/str2str_ntrip_B.service b/unit/str2str_ntrip_B.service index 88f9c638..29493c73 100644 --- a/unit/str2str_ntrip_B.service +++ b/unit/str2str_ntrip_B.service @@ -13,6 +13,9 @@ RestartSec=30 #Limiting log to 1 msg per minute LogRateLimitIntervalSec=1 minute LogRateLimitBurst=1 +ProtectHome=read-only +ProtectSystem=strict +ReadWritePaths={script_path} [Install] WantedBy=multi-user.target diff --git a/unit/str2str_rtcm_serial.service b/unit/str2str_rtcm_serial.service index 3d220e9b..c88be2dc 100644 --- a/unit/str2str_rtcm_serial.service +++ b/unit/str2str_rtcm_serial.service @@ -13,6 +13,9 @@ RestartSec=30 #Limiting log to 1 msg per minute LogRateLimitIntervalSec=1 minute LogRateLimitBurst=1 +ProtectHome=read-only +ProtectSystem=strict +ReadWritePaths={script_path} [Install] WantedBy=multi-user.target diff --git a/unit/str2str_rtcm_svr.service b/unit/str2str_rtcm_svr.service index 452b7f1e..80555ee2 100644 --- a/unit/str2str_rtcm_svr.service +++ b/unit/str2str_rtcm_svr.service @@ -13,6 +13,9 @@ RestartSec=30 #Limiting log to 1 msg per minute LogRateLimitIntervalSec=1 minute LogRateLimitBurst=1 +ProtectHome=read-only +ProtectSystem=strict +ReadWritePaths={script_path} [Install] WantedBy=multi-user.target diff --git a/unit/str2str_tcp.service b/unit/str2str_tcp.service index 91c6b9db..5879fb09 100644 --- a/unit/str2str_tcp.service +++ b/unit/str2str_tcp.service @@ -13,6 +13,9 @@ RestartSec=30 #Limiting log to 1 msg per minute LogRateLimitIntervalSec=1 minute LogRateLimitBurst=1 +ProtectHome=read-only +ProtectSystem=strict +ReadWritePaths={script_path} [Install] WantedBy=multi-user.target diff --git a/web_app/RTKBaseConfigManager.py b/web_app/RTKBaseConfigManager.py index 678c265f..f365c973 100644 --- a/web_app/RTKBaseConfigManager.py +++ b/web_app/RTKBaseConfigManager.py @@ -58,7 +58,18 @@ def restore_settings(self, default, to_restore): #write restored settings to the current settings for section in restore_config.sections(): for k, v in restore_config[section].items(): - self.config[section][k] = v + try: + if self.config[section].get(k) is not None: + self.config[section][k] = v + else: + raise ValueError(k) + except KeyError as e: + #this section is skipped + print("ignored section:", e) + pass + except ValueError as e: + print("ignored key", e) + self.write_file() def reload_settings(self, settings_path=None): diff --git a/web_app/RtkController.py b/web_app/RtkController.py index fb2df28e..9ef09f72 100644 --- a/web_app/RtkController.py +++ b/web_app/RtkController.py @@ -118,7 +118,8 @@ def shutdown(self): if self.launched: self.semaphore.acquire() - self.child.kill(signal.SIGUSR2) + #self.child.kill(signal.SIGUSR2) <- doesn't kill childs on Debian Bookworm + self.child.terminate(force=True) # wait for rtkrcv to shutdown try: diff --git a/web_app/requirements.txt b/web_app/requirements.txt index d84cdfa4..1780e15b 100644 --- a/web_app/requirements.txt +++ b/web_app/requirements.txt @@ -1,24 +1,48 @@ -cryptography==38.0.0 -Werkzeug=2.2.2 -itsdangerous==2.1.2 -Flask==2.2.2 -Flask-SocketIO==5.3.2 +bidict==0.22.1 +blinker==1.6.3 +Bootstrap-Flask==2.3.2 +certifi==2023.7.22 +cffi==1.16.0;python_version>="3.8" +cffi==1.15.1;python_version<"3.8" +charset-normalizer==3.3.2 +click==8.1.7 +cryptography==41.0.5 +distro==1.8.0 +dnspython==2.4.2;python_version>="3.8" +dnspython==2.3.0;python_version<"3.8" eventlet==0.33.3 -greenlet==1.1.3 -Bootstrap-Flask==2.2.0 -Flask-WTF==1.1.1 -Flask-Login==0.6.2 +Flask==3.0.0;python_version>="3.8" +Flask==2.2.5;python_version<"3.8" +Flask-Login==0.6.3 +Flask-SocketIO==5.3.6 +Flask-WTF==1.2.1;python_version>="3.8" +Flask-WTF==1.1.1;python_version<"3.8" +greenlet==3.0.1 +h11==0.14.0 +idna==3.4 +importlib-metadata==6.7.0;python_version<"3.8" +itsdangerous==2.1.2 +Jinja2==3.1.2 +lxml==4.9.3 +MarkupSafe==2.1.3 nmcli==1.3.0 -#On some linux distribution, pexpect and psutil are already installed -#and can't be upgraded with pip. In these cases, pip fail, leaving -#some package uninstalled. -#With pexpect <=4.8.0, pip will not fail. -#With psutil <= 5.8.0, pip will not fail. -pexpect<=4.8.0 -psutil<=5.9.4 -pyOpenSSL==23.0.0 +pexpect==4.8.0 +psutil==5.9.6 +ptyprocess==0.7.0 +pycparser==2.21 +pyOpenSSL==23.3.0 pyserial==3.5 -pystemd==0.10.0 -requests==2.28.1 -dnspython==2.3.0 -distro==1.8.0 \ No newline at end of file +pystemd==0.13.2 +python-engineio==4.8.0 +python-socketio==5.10.0 +requests==2.31.0 +simple-websocket==1.0.0 +six==1.16.0 +typing_extensions==4.7.1;python_version<"3.8" +urllib3==2.0.7 +Werkzeug==3.0.1;python_version>="3.8" +Werkzeug==2.2.3;python_version<"3.8" +wsproto==1.2.0 +WTForms==3.1.0;python_version>="3.8" +WTForms==3.0.1;python_version<"3.8" +zipp==3.15.0;python_version<"3.8" diff --git a/web_app/server.py b/web_app/server.py index ad729633..0b82d294 100755 --- a/web_app/server.py +++ b/web_app/server.py @@ -65,14 +65,15 @@ from flask_login import LoginManager, login_user, logout_user, login_required, current_user, UserMixin from wtforms.validators import ValidationError, DataRequired, EqualTo from flask_socketio import SocketIO, emit, disconnect +import urllib import subprocess import psutil import distro from werkzeug.security import generate_password_hash from werkzeug.security import check_password_hash -from werkzeug.urls import url_parse from werkzeug.utils import safe_join +import urllib app = Flask(__name__) app.debug = False @@ -149,11 +150,12 @@ def manager(): And it sends various system informations to the web interface """ max_cpu_temp = 0 + cpu_temp_offset = int(rtkbaseconfig.get("general", "cpu_temp_offset")) services_status = getServicesStatus(emit_pingback=False) main_service = {} while True: # Make sure max_cpu_temp is always updated - cpu_temp = get_cpu_temp() + cpu_temp = get_cpu_temp() + cpu_temp_offset max_cpu_temp = max(cpu_temp, max_cpu_temp) if connected_clients > 0: @@ -258,6 +260,13 @@ def check_update(source_url = None, current_release = None, prerelease=rtkbaseco :param emit: send the result to the web front end with socketio :return The new release version inside a dict (release version and url for this release) """ + ## test + #new_release = {'url' : 'http://localhost', 'new_release' : "3.9", "comment" : "blabla"} + #if emit: + # socketio.emit("new release", json.dumps(new_release), namespace="/test") + #return new_release + ## test + new_release = {} source_url = source_url if source_url is not None else "https://api.github.com/repos/stefal/rtkbase/releases" current_release = current_release if current_release is not None else rtkbaseconfig.get("general", "version").strip("v") @@ -289,7 +298,7 @@ def check_update(source_url = None, current_release = None, prerelease=rtkbaseco @socketio.on("update rtkbase", namespace="/test") def update_rtkbase(update_file=False): """ - Check if a RTKBase exists, download it and update rtkbase + Check if a RTKBase update exists, download it and update rtkbase if update_file is a link to a file, use it to update rtkbase (mainly used for dev purpose) """ @@ -308,7 +317,7 @@ def update_rtkbase(update_file=False): update_file.save("/var/tmp/rtkbase_update.tar.gz") update_archive = "/var/tmp/rtkbase_update.tar.gz" print("update stored in /var/tmp/") - + if update_archive is None: socketio.emit("downloading_update", json.dumps({"result": 'false'}), namespace="/test") return @@ -330,15 +339,20 @@ def update_rtkbase(update_file=False): #Extract archive tar.extractall("/var/tmp") - #launch update script - rtk.shutdownBase() source_path = os.path.join("/var/tmp/", primary_folder) script_path = os.path.join(source_path, "rtkbase_update.sh") current_release = rtkbaseconfig.get("general", "version").strip("v") standard_user = rtkbaseconfig.get("general", "user") - socketio.emit("updating_rtkbase", namespace="/test") - time.sleep(1) - os.execl(script_path, "unused arg0", source_path, rtkbase_path, app.config["DOWNLOAD_FOLDER"].split("/")[-1], current_release, standard_user) + #launch update verifications + answer = subprocess.run([script_path, source_path, rtkbase_path, app.config["DOWNLOAD_FOLDER"].split("/")[-1], current_release, standard_user, "--checking"], encoding="UTF-8", stderr=subprocess.PIPE, stdout=subprocess.PIPE) + if answer.returncode != 0: + socketio.emit("updating_rtkbase_stopped", json.dumps({"error" : answer.stderr.splitlines()}), namespace="/test") + else : #if ok, launch update script + print("Launch update") + socketio.emit("updating_rtkbase", namespace="/test") + rtk.shutdownBase() + time.sleep(1) + os.execl(script_path, "unused arg0", source_path, rtkbase_path, app.config["DOWNLOAD_FOLDER"].split("/")[-1], current_release, standard_user) def download_update(update_path): update_archive = "/var/tmp/rtkbase_update.tar.gz" @@ -430,7 +444,7 @@ def login_page(): login_user(user, remember=loginform.remember_me.data) next_page = request.args.get('next') - if not next_page or url_parse(next_page).netloc != '': + if not next_page or urllib.parse.urlsplit(next_page).netloc != '': next_page = url_for('status_page') return redirect(next_page) @@ -564,7 +578,7 @@ def deleteLog(json_msg): def detect_receiver(json_msg): print("Detecting gnss receiver") #print("DEBUG json_msg: ", json_msg) - answer = subprocess.run([os.path.join(rtkbase_path, "tools", "install.sh"), "--user", rtkbaseconfig.get("general", "user"), "--detect-usb-gnss", "--no-write-port"], encoding="UTF-8", stderr=subprocess.PIPE, stdout=subprocess.PIPE) + answer = subprocess.run([os.path.join(rtkbase_path, "tools", "install.sh"), "--user", rtkbaseconfig.get("general", "user"), "--detect-gnss", "--no-write-port"], encoding="UTF-8", stderr=subprocess.PIPE, stdout=subprocess.PIPE) if answer.returncode == 0 and "/dev/" in answer.stdout: #print("DEBUG ok stdout: ", answer.stdout) try: @@ -585,6 +599,9 @@ def detect_receiver(json_msg): @socketio.on("configure_receiver", namespace="/test") def configure_receiver(brand="u-blox", model="F9P"): # only ZED-F9P could be configured automaticaly + # After port detection, the main service will be restarted, and it will take some time. But we have to stop it to + # configure the receiver. We wait 2 seconds before stopping it to remove conflicting calls. + time.sleep(4) main_service = services_list[0] if main_service.get("active") is True: main_service["unit"].stop() @@ -594,8 +611,8 @@ def configure_receiver(brand="u-blox", model="F9P"): print("configuring {} gnss receiver model {}".format(brand, model)) answer = subprocess.run([os.path.join(rtkbase_path, "tools", "install.sh"), "--user", rtkbaseconfig.get("general", "user"), "--configure-gnss"], encoding="UTF-8", stderr=subprocess.PIPE, stdout=subprocess.PIPE) - print("DEBUG - stdout: ", answer.stdout) - print("DEBUG - returncode: ", answer.returncode) + #print("DEBUG - stdout: ", answer.stdout) + #print("DEBUG - returncode: ", answer.returncode) if answer.returncode == 0: # and "Done" in answer.stdout: result = {"result" : "success"} @@ -658,12 +675,11 @@ def restore_settings_file(json_msg): @socketio.on("rinex conversion", namespace="/test") def rinex_ign(json_msg): #print("DEBUG: json convbin: ", json_msg) - raw_type = rtkbaseconfig.get("main", "receiver_format").strip("'") - mnt_name = rtkbaseconfig.get("ntrip_A", "mnt_name_A").strip("'") rinex_type = {"rinex_ign" : "ign", "rinex_nrcan" : "nrcan", "rinex_30s_full" : "30s_full", "rinex_1s_full" : "1s_full"}.get(json_msg.get("rinex-preset")) convpath = os.path.abspath(os.path.join(rtkbase_path, "tools", "convbin.sh")) - #print("DEBUG", convpath, json_msg.get("name"), rtk.logm.log_path, mnt_name, raw_type, rinex_type) - answer = subprocess.run([convpath, json_msg.get("filename"), rtk.logm.log_path, mnt_name, raw_type, rinex_type], encoding="UTF-8", stderr=subprocess.PIPE, stdout=subprocess.PIPE) + convbin_user = rtkbaseconfig.get("general", "user").strip("'") + #print("DEBUG", convpath, json_msg.get("filename"), rtk.logm.log_path, rinex_type) + answer = subprocess.run(["sudo", "-u", convbin_user, convpath, json_msg.get("filename"), rtk.logm.log_path, rinex_type], encoding="UTF-8", stderr=subprocess.PIPE, stdout=subprocess.PIPE) if answer.returncode == 0 and "rinex_file=" in answer.stdout: rinex_file = answer.stdout.split("\n").pop().strip("rinex_file=") result = {"result" : "success", "file" : rinex_file} diff --git a/web_app/static/settings.js b/web_app/static/settings.js index 1a75e098..dc59f1c4 100644 --- a/web_app/static/settings.js +++ b/web_app/static/settings.js @@ -354,7 +354,8 @@ $(document).ready(function () { if (response['then_configure']) { // We need to wait for the service stop/restart after the previous click on form save button. // Yes, it's dirty... - setTimeout(() => { document.querySelector('#configure_receiver_button').click(); }, 2000); + //setTimeout(() => { document.querySelector('#configure_receiver_button').click(); }, 2000); + document.querySelector('#configure_receiver_button').click(); } // detectBodyElt.innerHTML = ' Configuring GNSS receiver...'; // detectApplyBtnElt.setAttribute('disabled', ''); @@ -392,10 +393,12 @@ $(document).ready(function () { detectApplyBtnElt.setAttribute('data-dismiss', 'modal'); detectApplyBtnElt.innerText = "Close"; if (response['result'] === 'success') { - detectBodyElt.innerHTML = "GNSS receiver successfully configured"; + detectBodyElt.innerHTML = "GNSS receiver successfully configured. We will log out to refresh the settings"; detectApplyBtnElt.removeAttribute('data-dismiss'); detectApplyBtnElt.onclick = function() { - window.location.reload(); + // window.location.reload(); + // looks like this way works better : + location.href = document.URL.replace(/#$/, ''); } } else { detectBodyElt.innerHTML = "GNSS receiver configuration failed" @@ -466,6 +469,19 @@ $(document).ready(function () { } }) + socket.on("updating_rtkbase_stopped", function(msg) { + response = JSON.parse(msg); + console.log("mgs: " + response.error) + $("#updateModal .modal-title").text("Error !"); + $("#updateModal .modal-body").text(""); + for (line of response.error) { + $("#updateModal .modal-body").append("

" + line + "

"); + } + $("#start-update-button").html('Update'); + $("#start-update-button").prop("disabled", true); + $("#cancel-button").prop("disabled", false); + }) + socket.on("updating_rtkbase", function() { $("#updateModal .modal-body").text("Please wait...Updating..."); update_countdown(600, 0); diff --git a/web_app/templates/diagnostic.html b/web_app/templates/diagnostic.html index 95fd5d42..6c705f9a 100644 --- a/web_app/templates/diagnostic.html +++ b/web_app/templates/diagnostic.html @@ -1,13 +1,30 @@ +{% extends 'base.html' %} + +{% block styles %} +{{super()}} +{% endblock %} + {% block content %} - - +
{% for service in logs %} - {{ service.name }} : {{ service.active }}
- {{ service.sysctl_status|safe }}
- {{ service.journalctl|safe }}
+ {% set btncolor = 'btn-success' if service.active == 'Active' else 'btn-secondary' %} +

+ +

+
+
+

STATUS:

{{ service.sysctl_status|safe }}

+

JOURNAL:

{{ service.journalctl|safe }}

+
+
{% endfor %} - - - +
{% endblock %} +{% block scripts %} + + + + {% endblock %} diff --git a/web_app/templates/logs.html b/web_app/templates/logs.html index 75eff939..e15e6bfd 100644 --- a/web_app/templates/logs.html +++ b/web_app/templates/logs.html @@ -74,16 +74,16 @@
- -
Gnss receiver brand and model
+ + Gnss receiver brand and model
@@ -69,8 +76,8 @@

Services:

- -
Gnss receiver format (ubx,stq,rtcm3,tersus,...)
+ + Gnss receiver format (ubx,sbf,stq,rtcm3,tersus,...)
@@ -79,8 +86,8 @@

Services:

- -
Antenna information (model,serial number) - default value is NULLANTENNA
+ + ADVNULLANTENNA or information (model,serial number) for IGS calibrated antenna
@@ -89,8 +96,8 @@

Services:

- -
Local tcp port
+ + Local tcp port
@@ -106,7 +113,7 @@

Services:

- + @@ -118,22 +125,22 @@

Services:

- -
Caster url address
+ + Caster url address
- -
Caster port
+ + Caster port
- +
-
Caster password
+ Caster password
- -
Mount name
+ + Mount name
- -
Rtcm messages list
+ + Rtcm messages list: msg(interval in seconds),msg(interval in seconds),...
- -
Receiver dependent options
+ + Receiver dependent options, e.g. -TADJ=1 for U-Blox F9P
@@ -180,7 +187,7 @@

Services:

-
+ @@ -192,22 +199,22 @@

Services:

- -
Caster url address
+ + Caster url address
- -
Caster port
+ + Caster port
- +
-
Caster password
+ Caster password
- -
Mount name
+ + Mount name
- -
Rtcm messages list
+ + Rtcm messages list: msg(interval in seconds),msg(interval in seconds),...
- -
Receiver dependent options
+ + Receiver dependent options, e.g. -TADJ=1 for U-Blox F9P
@@ -254,7 +261,7 @@

Services:

-
+ @@ -266,15 +273,15 @@

Services:

- -
Local Ntrip caster username for the rover
+ + Local Ntrip caster username you will use in your rover to connect
- +
-
Local Ntrip caster password for the rover
+ Local Ntrip caster password you will use in your rover to connect
- -
Local Ntrip Caster port number, e.g. 2101
+ + Local Ntrip Caster port number, e.g. 2101
- -
Local Ntrip caster mount name
+ + Local Ntrip caster mount name
- -
Local caster Rtcm messages list
+ + Local caster Rtcm messages list: msg(interval in seconds),msg(interval in seconds),...
- -
Local Ntrip Caster Receiver dependent options, e.g. -TADJ=1 for u-blox
+ + Receiver dependent options, e.g. -TADJ=1 for U-Blox F9P
@@ -328,7 +335,7 @@

Services:

-
+ @@ -340,22 +347,22 @@

Services:

- -
Rtcm server port
+ + Rtcm server port
- -
Rtcm server messages list
+ + Rtcm messages list: msg(interval in seconds),msg(interval in seconds),...
- -
Receiver dependent options
+ + Receiver dependent options, e.g. -TADJ=1 for U-Blox F9P
@@ -370,7 +377,7 @@

Services:

-
+ @@ -382,29 +389,29 @@

Services:

- -
Serial output com port (without /dev/)
+ + Serial output com port (without /dev/)
- -
Serial output port settings
+ + Serial output port settings: 'baud rate':'data bits':'parity':'stop bits'
- -
Rtcm serial output messages list
+ + Rtcm messages list: msg(interval in seconds),msg(interval in seconds),...
- -
Receiver dependent options
+ + Receiver dependent options. ie: -TADJ=1 for U-Blox F9P
@@ -419,7 +426,7 @@

Services:

-
+ @@ -431,36 +438,36 @@

Services:

- -
Path to data directory
+ + Absolute path to the directory where the data will be stored
- -
File name construction (should start with %Y-%m-%d_%h-%M-%S)
+ + Data file name construction (should start with %Y-%m-%d_%h-%M-%S)
- +
- -
File rotation time (in hour)
+ + File rotation time (in hours)
- +
- -
File rotation time (in seconds)
+ + File overlap time (in seconds)
- -
Archive duration before deletion (in days)
+ + Archives older than this value (in days) will be deleted