Git Product home page Git Product logo

rtkbase's Introduction

RTKBase

An easy to use and easy to install web frontend with bash scripts and services for a simple headless gnss base station.

FrontEnd:

|status|settings|logs|

Frontend's main features are:

  • View the satellites signal levels
  • View the base location on a map
  • Detect and configure the Gnss receiver (F9P)
  • Start/stop various services (Sending data to a Ntrip caster, internal Ntrip caster, Rtcm server, Sending Rtcm stream on a radio link, Log raw data to files)
  • Edit the services settings
  • Convert raw data to Rinex
  • Download/delete raw data

Base example:

status

  • Enclosure: GentleBOX JE-200 (waterproof, cable glands for antenna and ethernet cable)
  • SBC: Raspberry Pi 3 / Orange Pi Zero (512MB)
  • Gnss Receiver: U-Blox ZED-F9P (from Drotek)
  • Antenna: DA910 (Gps L1/L2, Glonass L1/L2, Beidou B1/B2/B3 and Galileo E1/E5b/E6) + sma (male) to TNC (male) outdoor cable.
  • Power: Trendnet TPE-115GI POE+ injector + Trendnet POE TPE-104GS Extractor/Splitter + DC Barrel to Micro Usb adapter

Other images are available in the ./images folder.

Ready to flash release:

A ready to flash image is available for Orange Pi Zero SBC : Armbian_RTKBase

If you use a Raspberry Pi, thanks to jancelin, you can download a ready to flash iso file here.

Easy installation:

  • Connect your gnss receiver to your raspberry pi/orange pi/....

  • Open a terminal and:

    cd ~
    wget https://raw.githubusercontent.com/Stefal/rtkbase/master/tools/install.sh -O install.sh
    chmod +x install.sh
    sudo ./install.sh --all release
  • Go grab a coffee, it's gonna take a while. The script will install the needed software, and if you use a Usb-connected U-Blox ZED-F9P receiver, it'll be detected and set to work as a base station. If you don't use a F9P, you will have to configure your receiver manually (see step 7 in manual installation), and choose the correct port from the settings page.

  • Open a web browser to http://ip_of_your_sbc (the script will try to show you this ip address). Default password is admin. The settings page allows you to enter your own settings for the base coordinates, ntrip credentials and so on...

    all settings

    If you don't already know your base precise coordinates, it's time to read one of these tutorials:

Manual installation:

The install.sh script can be used without the --all option to split the installation process into several different steps:

    ################################
    RTKBASE INSTALLATION HELP
    ################################
    Bash scripts to install a simple gnss base station with a web frontend.
    
    
    
    * Before install, connect your gnss receiver to raspberry pi/orange pi/.... with usb or uart.
    * Running install script with sudo
    
    Easy installation: sudo ./install.sh --all release
    
    Options:
            -a | --all <rtkbase source>
                             Install all you need to run RTKBase : dependencies, RTKlib, last release of Rtkbase, services,
                             crontab jobs, detect your GNSS receiver and configure it.
                             <rtkbase source> could be:
                                 release  (get the latest available release)
                                 repo     (you need to add the --rtkbase-repo argument with a branch name)
                                 url      (you need to add the --rtkbase-custom-source argument with an url)
                                 bundled  (available if the rtkbase archive is bundled with the install script)
    
            -u | --user
                             Use this username as User= inside service unit and for path to rtkbase:
                             --user=john will install rtkbase in /home/john/rtkbase
    
            -d | --dependencies
                             Install all dependencies like git build-essential python3-pip ...
    
            -r | --rtklib
                             Get RTKlib 2.4.3b34g from github and compile it.
                             https://github.com/rtklibexplorer/RTKLIB/tree/b34g
    
            -b | --rtkbase-release
                             Get last release of RTKBase:
                             https://github.com/Stefal/rtkbase/releases
    
            -i | --rtkbase-repo <branch>
                             Clone RTKBASE from github with the <branch> parameter used to select the branch.
    
            -j | --rtkbase-bundled
                             Extract the rtkbase files bundled with this script, if available.
    
            -f | --rtkbase-custom <source>
                             Get RTKBASE from an url.
    
            -t | --unit-files
                             Deploy services.
    
            -g | --gpsd-chrony
                             Install gpsd and chrony to set date and time
                             from the gnss receiver.
    
            -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-gnss argument.
    
            -c | --configure-gnss
                             Configure your GNSS receiver.
    
            -s | --start-services
                             Start services (rtkbase_web, str2str_tcp, gpsd, chrony)
    
            -h | --help
                              Display this help message.

So, if you really want it, let's go for a manual installation with some explanations:

  1. Install dependencies with sudo ./install.sh --dependencies, or do it manually with:

     sudo apt update
     sudo apt 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
  2. Install RTKLIB with sudo ./install.sh --rtklib, or:

    • get RTKlib

      cd ~
      wget -qO - https://github.com/rtklibexplorer/RTKLIB/archive/refs/tags/b34g.tar.gz | tar -xvz
    • compile and install str2str:

      Optionally, you can edit the CTARGET line in makefile in RTKLIB/app/str2str/gcc

      cd RTKLIB/app/str2str/gcc
      nano makefile

      For an Orange Pi Zero SBC, i use:

      CTARGET = -mcpu=cortex-a7 -mfpu=neon-vfpv4 -funsafe-math-optimizations

      Then you can compile and install str2str:

      make
      sudo make install
    • Compile/install rtkrcv and convbin the same way as str2str.

  3. Get latest rtkbase release sudo ./install.sh --rtkbase-release, or:

    wget https://github.com/stefal/rtkbase/releases/latest/download/rtkbase.tar.gz -O rtkbase.tar.gz
    tar -xvf rtkbase.tar.gz
    

    If you prefer, you can clone this repository to get the latest code.

  4. Install the rtkbase requirements:

    python3 -m pip install --upgrade pip setuptools wheel  --extra-index-url https://www.piwheels.org/simple
    python3 -m pip install -r rtkbase/web_app/requirements.txt  --extra-index-url https://www.piwheels.org/simple
    
  5. Install the systemd services with sudo ./install.sh --unit-files, or do it manually with:

    • Edit them (rtkbase/unit/) to replace {user} with your username.
    • If you log the raw data inside the base station, you may want to compress these data and delete the too old archives. archive_and_clean.sh will do it for you. The default settings compress the previous day data and delete all archives older than 90 days. To automate these 2 tasks, enable the rtkbase_archive.timer. The default value runs the script every day at 04H00.
    • Copy these services to /etc/systemd/system/ then enable the web server, str2str_tcp and rtkbase_archive.timer:
    sudo systemctl daemon-reload
    sudo systemctl enable rtkbase_web
    sudo systemctl enable str2str_tcp
    sudo systemctl enable rtkbase_archive.timer
  6. Install and configure chrony and gpsd with sudo ./install.sh --gpsd-chrony, or:

    • Install chrony with sudo apt install chrony then add this parameter in the chrony conf file (/etc/chrony/chrony.conf):

      refclock SHM 0 refid GPS precision 1e-1 offset 0.2 delay 0.2

      Edit the chrony unit file. You should set After=gpsd.service

    • Install a gpsd release >= 3.2 or it won't work with a F9P. Its conf file should contains:

       # Devices gpsd should connect to at boot time.
       # They need to be read/writeable, either by user gpsd or the group dialout.
       DEVICES="tcp://localhost:5015"
    
       # Other options you want to pass to gpsd
       GPSD_OPTIONS="-n -b"
    
    

    Edit the gpsd unit file. You should have something like this in the "[Unit]" section:

       [Unit]
       Description=GPS (Global Positioning System) Daemon
       Requires=gpsd.socket
       BindsTo=str2str_tcp.service
       After=str2str_tcp.service
    
    • Reload the services and enable them:
       sudo systemctl daemon-reload
       sudo systemctl enable chrony
       sudo systemctl enable gpsd
  7. 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.

  8. 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

    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)):

    rtkbase/tools/set_zed-f9p.sh /dev/ttyS1 115200 rtkbase/receiver_cfg/U-Blox_ZED-F9P_rtkbase.cfg

    If you need to use a config tool from another computer (like U-center), you can use socat:

    sudo socat tcp-listen:128,reuseaddr /dev/ttyS1,b115200,raw,echo=0

    Change the ttyS1 and 115200 value if needed. Then you can use a network connection in U-center with the base station ip address and the port n°128.

  9. Now you can start the services with sudo ./install.sh --start-services, or:

    sudo systemctl start rtkbase_web
    sudo systemctl start str2str_tcp
    sudo systemctl start gpsd
    sudo systemctl start chrony
    sudo systemctl start rtkbase_archive.timer

    Everything should be ready, now you can open a web browser to your base station ip address.

How it works:

RTKBase use several RTKLIB str2str instances started with run_cast.sh as systemd services. run_cast.sh gets its settings from settings.conf

  • str2str_tcp.service is the main instance. It is connected to the gnss receiver and broadcast the raw data on TCP for all the others services.
  • str2str_ntrip_A.service get the data from the main instance, convert the data to rtcm and stream them to a Ntrip caster.
  • str2str_ntrip_B.service get the data from the main instance, convert the data to rtcm and stream them to another Ntrip caster.
  • str2str_local_ntrip_caster.service get the data from the main instance, convert the data to rtcm, and act as a local Ntrip caster.
  • str2str_rtcm_svr.service get the data from the main instance, convert the data to rtcm and stream them to clients
  • str2str_rtcm_serial.service get the data from the main instance, convert the data to rtcm and stream them to a serial port (radio link, or other peripherals)
  • str2str_file.service get the data from the main instance, and log the data to files.

internal

The web GUI is available when the rtkbase_web service is running.

Advanced:

  • Aerial images: The default map background is OpenStreetMap, but you can switch to a worldwide aerial layer if you have a Maptiler key. To enable this layer, create a free account on Maptiler, create a key and add it to settings.conf inside the [general] section: maptiler_key=your_key

  • Receiver options: str2str accept some receiver dependent options. If you use a U-Blox, the -TADJ=1 parameter is recommended as a workaround to non-rounded second values in Rtcm and Ntrip outputs. You can enter this parameter inside the settings forms. More information here and here.

    status

Development release:

If you want to install RTKBase from the dev branch, you can do it with these commands:

cd ~
wget https://raw.githubusercontent.com/Stefal/rtkbase/dev/tools/install.sh -O install.sh
chmod +x install.sh
sudo ./install.sh --alldev dev

Other usages:

A gnss receiver with a timepulse output is a very accurate stratum 0 clock thus, your gnss base station could act as a stratum 1 ntp peer for your local network and/or the ntp pool. There are a few steps to do this:

  • Connect the timepulse output + GND to some GPIO inputs on your SBC.

  • Configure this input as PPS in your operating system.

    • Raspberry Pi example:

      • Inside /boot/config.txt, add dtoverlay=pps-gpio,gpiopin=18 on a new line. '18' is the input used for timepulse.
      • Inside /etc/modules, add pps-gpio on a new line, if it is not already present.
    • Orange Pi Zero example, inside /boot/armbianEnv.txt:

      • Add pps-gpio to the overlays line.
      • One a new line, add param_pps_pin=PA19 <- change 'PA19' to your input.
  • Set gpsd and chrony to use PPS

    • gpsd: comment the DEVICE line in /etc/defaut/gpsd and uncomment #DEVICES="tcp:\\127.0.0.1:5015 \dev\pps0

    • chrony: inside /etc/chrony/chrony.conf uncomment the refclock pps line and add noselect to the 'refclock SHM 0`. You should have something like this:

       refclock SHM 0 refid GPS precision 1e-1 offset 0 delay 0.2 noselect
       refclock PPS /dev/pps0 refid PPS lock GPS
    
    • reboot your sbc and check the result of chronyc sources -v You should read something like this, notice the '*' before 'PPS':
       basegnss@orangepizero:~$ chronyc sources -v
       210 Number of sources = 6
       .-- Source mode  '^' = server, '=' = peer, '#' = local clock.
       / .- Source state '*' = current synced, '+' = combined , '-' = not combined,
       | /   '?' = unreachable, 'x' = time may be in error, '~' = time too variable.
       ||                                                 .- xxxx [ yyyy ] +/- zzzz
       ||      Reachability register (octal) -.           |  xxxx = adjusted offset,
       ||      Log2(Polling interval) --.      |          |  yyyy = measured offset,
       ||                                \     |          |  zzzz = estimated error.
       ||                                 |    |           \
       MS Name/IP address         Stratum Poll Reach LastRx Last sample
       ===============================================================================
       #? GPS                           0   4   377    17    +64ms[  +64ms] +/-  200ms
       #* PPS                           0   4   377    14   +363ns[ +506ns] +/- 1790ns
       ^- ntp0.dillydally.fr            2   6   177    16    -12ms[  -12ms] +/-   50ms
       ^? 2a01:e35:2fba:7c00::21        0   6     0     -     +0ns[   +0ns] +/-    0ns
       ^- 62-210-213-21.rev.poneyt>     2   6   177    17  -6488us[-6487us] +/-   67ms
       ^- kalimantan.ordimatic.net      3   6   177    16    -27ms[  -27ms] +/-   64ms
    
    

Requirements:

Python >= 3.7

History:

See the changelog

License:

RTKBase is licensed under AGPL 3 (see LICENSE file).

RTKBase uses some parts of other software:

RTKBase uses OpenStreetMap tiles. Thank you to all the contributors!

rtkbase's People

Contributors

by avatar danilkramorov avatar dependabot[bot] avatar egorf avatar gpsfan avatar gwndaan avatar hurdmanbegins avatar jaapvandenhandel avatar jancelin avatar kamcnally avatar khancyr avatar stefal avatar zmonteiro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rtkbase's Issues

ubxconfig.sh sometimes doesn't find the version until the last try

root@centipede:/rtkbase# ./ubxconfig.sh /dev/ttyACM0 receiver_cfg/U-Blox_ZED-F9P_rtkbase.txt
stty: /dev/ttyACM0: unable to perform all requested operations
dos2unix: converting file receiver_cfg/U-Blox_ZED-F9P_rtkbase.txt to Unix format...

Checking compatibility...
Version mismatch! Checking again...
Version mismatch! Checking again...
Version mismatch! Checking again...
Version mismatch! Checking again...
Version mismatch! Checking again...
Version mismatch! Checking again...
Version mismatch! Checking again...
Version mismatch! Checking again...
xxd: Broken pipe
cat: write error: Broken pipe
Version match!
Configuring u-blox GPS at /dev/ttyACM0 from receiver_cfg/U-Blox_ZED-F9P_rtkbase.txt...

wrong user used by copy_unit.sh

str2str_file should use the normal user, and copy_unit.sh script should take care of that, but as you need to sudo this script, root is used for all services.

Detect automaticaly the gnss receiver

It would be easier to detect the tty* used with the Usb connected gnss receiver.
This script could be a good solution

#!/bin/bash
# source https://unix.stackexchange.com/a/144735
for sysdevpath in $(find /sys/bus/usb/devices/usb*/ -name dev); do

        syspath="${sysdevpath%/dev}"
        devname="$(udevadm info -q name -p $syspath)"
        if [[ "$devname" == "bus/"* ]]; then continue; fi
        eval "$(udevadm info -q property --export -p $syspath)"
        if [[ -z "$ID_SERIAL" ]]; then continue; fi
        echo "/dev/$devname - $ID_SERIAL"

done

$ ./find_ublox_usb.sh | grep 'u-blox' 
/dev/ttyACM1 - u-blox_AG_-_www.u-blox.com_u-blox_GNSS_receiver

Flask secret key isn't stored

With the actual code from Reachview, the flask secret key is generated during each web server startup.
So all users need to re-enter their password.

We need to generate this secret key during the installation and store it in the python .env or in the bash console with something like
export flask_secret_key="random key"
and use it in the server.py script with
os.environ.get("flask_secret_key")

Managing update

Starting an update from the web front-end:

  • Check if a new release is available
  • Notify the user
  • Download the new .tar release
  • Expand the archive
  • Run a script to apply the new release
  • Reboot or only restart the web server.

cron or systemd.time for archiving gnss data

At this time, the daily data archiving process is launch with a crontab. But as other parts are using systemd, maybe it would be a good idea to use systemd.time to start this process.

One problem is that it needs the systemd.time file and a unit file and the script. With cron we need only the crontab and the script.
It seems simpler to stay with cron.

System clock not synchronized

On a fresh armbian buster the system clock seems to stay unsync (NTPSynchronized=no). Thus, check_timesync.sh never ends, and the log to file doesn't start.

Raspbian Buster doesn't use ntp

The str2str_file service check if the rtc is in sync with ntpstat which need the ntp.service unit file.
But with Raspbian Buster release, ntp doesn't exist anymore, it is replaced with systemd-timesyncd.

str2str_file doesn't start

str2str_file depends on systemd-timesyncd which doesn't always start on armbian (chrony is installed).

add a button to detect and configure usb gnss receiver

Some people upgrade F9P and are forced to switch to ssh to put the parameters back into the receiver.
Solution: add a web button with a function
sudo /home/basegnss/rtkbase/tools/install.sh --detect-usb-gnss --configure-gnss

root own rtkbase directory after an udpate

Then services like str2str_file running with current user can't create 'data' directory.

Need more tests

A workaround would be
chown -R $(logname) path/to/rtkbase inside update.sh

SBAS and F9P

Are SBAS satellites really useful for a base station. I don't think so.
As Sbas is default enabled on F9P with firmware 1.13, I think it would be better to disable sbas during the configuration.

FR: Add aerial images layer

Maptiler.org offer a free plan
Mapbox too, but the aerial images is older than Maptiler (at least for France)

FR: view service logs

It could be useful to view the various systemd services logs (str2str_tcp.service and so on)

Eventlet installation failed on Orange pi zero + armbian buster

The eventlet installation seems to fail during sudo python3 -m pip install -r requirements.txt
But if I restart the installation separataly with sudo python3 -m pip install eventlet, it works.
trace:

Collecting Flask==1.1.1 (from -r rtkbase/web_app/requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/9b/93/628509b8d5dc749656a9641f4caf13540e2cdec85276964ff8f4                            3bbb1d3b/Flask-1.1.1-py2.py3-none-any.whl (94kB)
    100% |████████████████████████████████| 102kB 983kB/s
Collecting Flask-SocketIO==4.2.1 (from -r rtkbase/web_app/requirements.txt (line 2))
  Downloading https://files.pythonhosted.org/packages/66/44/edc4715af85671b943c18ac8345d0207972284a0cd630126ff52                            51faa08b/Flask_SocketIO-4.2.1-py2.py3-none-any.whl
Collecting eventlet==0.25.2 (from -r rtkbase/web_app/requirements.txt (line 3))
  Downloading https://files.pythonhosted.org/packages/9d/4d/43a042ef699624b5e65dee7cc7c1cd9452348d301ea0d8510747                            20615c91/eventlet-0.25.2-py2.py3-none-any.whl (222kB)
    100% |████████████████████████████████| 225kB 738kB/s
Collecting Bootstrap-Flask==1.2.0 (from -r rtkbase/web_app/requirements.txt (line 4))
  Downloading https://files.pythonhosted.org/packages/e5/c4/befc90aa517c8e5644e09bb9062879da8c72fb08d3de9253798a                            bee71b5f/Bootstrap_Flask-1.2.0-py2.py3-none-any.whl (863kB)
    100% |████████████████████████████████| 870kB 219kB/s
Collecting Flask-WTF==0.14.3 (from -r rtkbase/web_app/requirements.txt (line 5))
  Downloading https://files.pythonhosted.org/packages/36/a9/8c01171066bd7a524ee005d81bb4a8aa446ab178043a1ad6cb5d                            c8f0bd83/Flask_WTF-0.14.3-py2.py3-none-any.whl
Collecting Flask-Login==0.5.0 (from -r rtkbase/web_app/requirements.txt (line 6))
  Downloading https://files.pythonhosted.org/packages/2b/83/ac5bf3279f969704fc1e63f050c50e10985e50fd340e6069ec7e                            09df5442/Flask_Login-0.5.0-py2.py3-none-any.whl
Collecting pexpect==4.7.0 (from -r rtkbase/web_app/requirements.txt (line 7))
  Downloading https://files.pythonhosted.org/packages/0e/3e/377007e3f36ec42f1b84ec322ee12141a9e10d808312e5738f52                            f80a232c/pexpect-4.7.0-py2.py3-none-any.whl (58kB)
    100% |████████████████████████████████| 61kB 1.3MB/s
Collecting pyOpenSSL==19.1.0 (from -r rtkbase/web_app/requirements.txt (line 8))
  Downloading https://files.pythonhosted.org/packages/9e/de/f8342b68fa9e981d348039954657bdf681b2ab93de27443be518                            65ffa310/pyOpenSSL-19.1.0-py2.py3-none-any.whl (53kB)
    100% |████████████████████████████████| 61kB 1.3MB/s
Collecting pyserial==3.4 (from -r rtkbase/web_app/requirements.txt (line 9))
  Downloading https://files.pythonhosted.org/packages/0d/e4/2a744dd9e3be04a0c0907414e2a01a7c88bb3915cbe3c8cc06e2                            09f59c30/pyserial-3.4-py2.py3-none-any.whl (193kB)
    100% |████████████████████████████████| 194kB 827kB/s
Collecting pystemd==0.7.0 (from -r rtkbase/web_app/requirements.txt (line 10))
  Downloading https://files.pythonhosted.org/packages/c3/1a/6ec2ac628eabdce55f317f7ba560a8f14daebf86187cd6075c50                            054d528b/pystemd-0.7.0.tar.gz (265kB)
    100% |████████████████████████████████| 266kB 635kB/s
Collecting requests==2.23.0 (from -r rtkbase/web_app/requirements.txt (line 11))
  Downloading https://files.pythonhosted.org/packages/1a/70/1935c770cb3be6e3a8b78ced23d7e0f3b187f5cbfab4749523ed                            65d7c9b1/requests-2.23.0-py2.py3-none-any.whl (58kB)
    100% |████████████████████████████████| 61kB 1.3MB/s
Collecting click>=5.1 (from Flask==1.1.1->-r rtkbase/web_app/requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/d2/3d/fa76db83bf75c4f8d338c2fd15c8d33fdd7ad23a9b5e57eb6c5d                            e26b430e/click-7.1.2-py2.py3-none-any.whl (82kB)
    100% |████████████████████████████████| 92kB 1.2MB/s
Collecting itsdangerous>=0.24 (from Flask==1.1.1->-r rtkbase/web_app/requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/76/ae/44b03b253d6fade317f32c24d100b3b35c2239807046a4c953c7                            b89fa49e/itsdangerous-1.1.0-py2.py3-none-any.whl
Collecting Jinja2>=2.10.1 (from Flask==1.1.1->-r rtkbase/web_app/requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/30/9e/f663a2aa66a09d838042ae1a2c5659828bb9b41ea3a6efa20a20                            fd92b121/Jinja2-2.11.2-py2.py3-none-any.whl (125kB)
    100% |████████████████████████████████| 133kB 1.1MB/s
Collecting Werkzeug>=0.15 (from Flask==1.1.1->-r rtkbase/web_app/requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/cc/94/5f7079a0e00bd6863ef8f1da638721e9da21e5bacee597595b31                            8f71d62e/Werkzeug-1.0.1-py2.py3-none-any.whl (298kB)
    100% |████████████████████████████████| 307kB 576kB/s
Collecting python-socketio>=4.3.0 (from Flask-SocketIO==4.2.1->-r rtkbase/web_app/requirements.txt (line 2))
  Downloading https://files.pythonhosted.org/packages/10/cb/631c0b713daea3938e66d4c0923e88f3c0b57b026f860ea76e03                            37bc9c7a/python_socketio-4.5.1-py2.py3-none-any.whl (51kB)
    100% |████████████████████████████████| 61kB 1.4MB/s
Collecting monotonic>=1.4 (from eventlet==0.25.2->-r rtkbase/web_app/requirements.txt (line 3))
  Downloading https://files.pythonhosted.org/packages/ac/aa/063eca6a416f397bd99552c534c6d11d57f58f2e94c14780f3bb                            f818c4cf/monotonic-1.5-py2.py3-none-any.whl
Collecting dnspython>=1.15.0 (from eventlet==0.25.2->-r rtkbase/web_app/requirements.txt (line 3))
  Downloading https://files.pythonhosted.org/packages/ec/d3/3aa0e7213ef72b8585747aa0e271a9523e713813b9a20177ebe1                            e939deb0/dnspython-1.16.0-py2.py3-none-any.whl (188kB)
    100% |████████████████████████████████| 194kB 842kB/s
Collecting six>=1.10.0 (from eventlet==0.25.2->-r rtkbase/web_app/requirements.txt (line 3))
  Downloading https://files.pythonhosted.org/packages/65/eb/1f97cb97bfc2390a276969c6fae16075da282f5058082d4cb10c                            6c5c1dba/six-1.14.0-py2.py3-none-any.whl
Collecting greenlet>=0.3 (from eventlet==0.25.2->-r rtkbase/web_app/requirements.txt (line 3))
  Downloading https://files.pythonhosted.org/packages/f8/e8/b30ae23b45f69aa3f024b46064c0ac8e5fcb4f22ace0dca8d6f9                            c8bbe5e7/greenlet-0.4.15.tar.gz (59kB)
    100% |████████████████████████████████| 61kB 1.2MB/s
Collecting WTForms (from Flask-WTF==0.14.3->-r rtkbase/web_app/requirements.txt (line 5))
  Downloading https://files.pythonhosted.org/packages/f0/1b/af089b3d54955e0a3b0045ddd40773c2ef5dc7375ccffd09366c                            e469b755/WTForms-2.3.1-py2.py3-none-any.whl (169kB)
    100% |████████████████████████████████| 174kB 883kB/s
Collecting ptyprocess>=0.5 (from pexpect==4.7.0->-r rtkbase/web_app/requirements.txt (line 7))
  Downloading https://files.pythonhosted.org/packages/d1/29/605c2cc68a9992d18dada28206eeada56ea4bd07a239669da416                            74648b6f/ptyprocess-0.6.0-py2.py3-none-any.whl
Collecting cryptography>=2.8 (from pyOpenSSL==19.1.0->-r rtkbase/web_app/requirements.txt (line 8))
  Downloading https://files.pythonhosted.org/packages/56/3b/78c6816918fdf2405d62c98e48589112669f36711e50158a0c15                            d804c30d/cryptography-2.9.2.tar.gz (517kB)
    100% |████████████████████████████████| 522kB 350kB/s
  Installing build dependencies ... error
  Complete output from command /usr/bin/python3 -m pip install --ignore-installed --no-user --prefix /tmp/pip-bu                            ild-env-via3n3s9 --no-warn-script-location --no-binary :none: --only-binary :none: -i https://pypi.org/simple --                             setuptools>=40.6.0 wheel "cffi>=1.8,!=1.11.3; platform_python_implementation != 'PyPy'":
  Collecting setuptools>=40.6.0
    Downloading https://files.pythonhosted.org/packages/a0/df/635cdb901ee4a8a42ec68e480c49f85f4c59e8816effbf57d9                            e6ee8b3588/setuptools-46.1.3-py3-none-any.whl (582kB)
  Collecting wheel
    Downloading https://files.pythonhosted.org/packages/8c/23/848298cccf8e40f5bbb59009b32848a4c38f4e7f3364297ab3                            c3e2e2cd14/wheel-0.34.2-py2.py3-none-any.whl
  Collecting cffi!=1.11.3,>=1.8
    Downloading https://files.pythonhosted.org/packages/05/54/3324b0c46340c31b909fcec598696aaec7ddc8c18a63f2db35                            2562d3354c/cffi-1.14.0.tar.gz (463kB)
  Collecting pycparser (from cffi!=1.11.3,>=1.8)
    Downloading https://files.pythonhosted.org/packages/ae/e7/d9c3a176ca4b02024debf82342dab36efadfc5776f9c8db077                            e8f6e71821/pycparser-2.20-py2.py3-none-any.whl (112kB)
  Building wheels for collected packages: cffi
    Running setup.py bdist_wheel for cffi: started
    Running setup.py bdist_wheel for cffi: finished with status 'error'
    Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-                            28twnv43/cffi/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close(                            );exec(compile(code, __file__, 'exec'))" bdist_wheel -d /tmp/pip-wheel-bl8ngr7t --python-tag cp37:
    running bdist_wheel
    running build
    running build_py
    creating build
    creating build/lib.linux-armv7l-3.7
    creating build/lib.linux-armv7l-3.7/cffi
    copying cffi/recompiler.py -> build/lib.linux-armv7l-3.7/cffi
    copying cffi/verifier.py -> build/lib.linux-armv7l-3.7/cffi
    copying cffi/cffi_opcode.py -> build/lib.linux-armv7l-3.7/cffi
    copying cffi/setuptools_ext.py -> build/lib.linux-armv7l-3.7/cffi
    copying cffi/__init__.py -> build/lib.linux-armv7l-3.7/cffi
    copying cffi/lock.py -> build/lib.linux-armv7l-3.7/cffi
    copying cffi/api.py -> build/lib.linux-armv7l-3.7/cffi
    copying cffi/vengine_gen.py -> build/lib.linux-armv7l-3.7/cffi
    copying cffi/pkgconfig.py -> build/lib.linux-armv7l-3.7/cffi
    copying cffi/ffiplatform.py -> build/lib.linux-armv7l-3.7/cffi
    copying cffi/cparser.py -> build/lib.linux-armv7l-3.7/cffi
    copying cffi/backend_ctypes.py -> build/lib.linux-armv7l-3.7/cffi
    copying cffi/error.py -> build/lib.linux-armv7l-3.7/cffi
    copying cffi/commontypes.py -> build/lib.linux-armv7l-3.7/cffi
    copying cffi/model.py -> build/lib.linux-armv7l-3.7/cffi
    copying cffi/vengine_cpy.py -> build/lib.linux-armv7l-3.7/cffi
    copying cffi/_cffi_include.h -> build/lib.linux-armv7l-3.7/cffi
    copying cffi/parse_c_type.h -> build/lib.linux-armv7l-3.7/cffi
    copying cffi/_embedding.h -> build/lib.linux-armv7l-3.7/cffi
    copying cffi/_cffi_errors.h -> build/lib.linux-armv7l-3.7/cffi
    running build_ext
    building '_cffi_backend' extension
    creating build/temp.linux-armv7l-3.7
    creating build/temp.linux-armv7l-3.7/c
    arm-linux-gnueabihf-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=                            format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -DUSE__THREAD -DHAVE_SYNC_SYNCHRONIZE -I/usr/include/ffi -                            I/usr/include/libffi -I/usr/include/python3.7m -c c/_cffi_backend.c -o build/temp.linux-armv7l-3.7/c/_cffi_backe                            nd.o
    c/_cffi_backend.c:15:10: fatal error: ffi.h: No such file or directory
     #include <ffi.h>
              ^~~~~~~
    compilation terminated.
    error: command 'arm-linux-gnueabihf-gcc' failed with exit status 1

    ----------------------------------------
    Failed building wheel for cffi
    Running setup.py clean for cffi
  Failed to build cffi
  Installing collected packages: setuptools, wheel, pycparser, cffi
    Running setup.py install for cffi: started
      Running setup.py install for cffi: finished with status 'error'
      Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-instal                            l-28twnv43/cffi/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.clos                            e();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-record-ih_ae5vi/install-record.txt --single                            -version-externally-managed --prefix /tmp/pip-build-env-via3n3s9 --compile:
      running install
      running build
      running build_py
      creating build
      creating build/lib.linux-armv7l-3.7
      creating build/lib.linux-armv7l-3.7/cffi
      copying cffi/recompiler.py -> build/lib.linux-armv7l-3.7/cffi
      copying cffi/verifier.py -> build/lib.linux-armv7l-3.7/cffi
      copying cffi/cffi_opcode.py -> build/lib.linux-armv7l-3.7/cffi
      copying cffi/setuptools_ext.py -> build/lib.linux-armv7l-3.7/cffi
      copying cffi/__init__.py -> build/lib.linux-armv7l-3.7/cffi
      copying cffi/lock.py -> build/lib.linux-armv7l-3.7/cffi
      copying cffi/api.py -> build/lib.linux-armv7l-3.7/cffi
      copying cffi/vengine_gen.py -> build/lib.linux-armv7l-3.7/cffi
      copying cffi/pkgconfig.py -> build/lib.linux-armv7l-3.7/cffi
      copying cffi/ffiplatform.py -> build/lib.linux-armv7l-3.7/cffi
      copying cffi/cparser.py -> build/lib.linux-armv7l-3.7/cffi
      copying cffi/backend_ctypes.py -> build/lib.linux-armv7l-3.7/cffi
      copying cffi/error.py -> build/lib.linux-armv7l-3.7/cffi
      copying cffi/commontypes.py -> build/lib.linux-armv7l-3.7/cffi
      copying cffi/model.py -> build/lib.linux-armv7l-3.7/cffi
      copying cffi/vengine_cpy.py -> build/lib.linux-armv7l-3.7/cffi
      copying cffi/_cffi_include.h -> build/lib.linux-armv7l-3.7/cffi
      copying cffi/parse_c_type.h -> build/lib.linux-armv7l-3.7/cffi
      copying cffi/_embedding.h -> build/lib.linux-armv7l-3.7/cffi
      copying cffi/_cffi_errors.h -> build/lib.linux-armv7l-3.7/cffi
      running build_ext
      building '_cffi_backend' extension
      creating build/temp.linux-armv7l-3.7
      creating build/temp.linux-armv7l-3.7/c
      arm-linux-gnueabihf-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werro                            r=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -DUSE__THREAD -DHAVE_SYNC_SYNCHRONIZE -I/usr/include/ffi                             -I/usr/include/libffi -I/usr/include/python3.7m -c c/_cffi_backend.c -o build/temp.linux-armv7l-3.7/c/_cffi_bac                            kend.o
      c/_cffi_backend.c:15:10: fatal error: ffi.h: No such file or directory
       #include <ffi.h>
                ^~~~~~~
      compilation terminated.
      error: command 'arm-linux-gnueabihf-gcc' failed with exit status 1

      ----------------------------------------
  Command "/usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-28twnv43/cffi/setup.py                            ';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, _                            _file__, 'exec'))" install --record /tmp/pip-record-ih_ae5vi/install-record.txt --single-version-externally-mana                            ged --prefix /tmp/pip-build-env-via3n3s9 --compile" failed with error code 1 in /tmp/pip-install-28twnv43/cffi/

  ----------------------------------------
Command "/usr/bin/python3 -m pip install --ignore-installed --no-user --prefix /tmp/pip-build-env-via3n3s9 --no-                            warn-script-location --no-binary :none: --only-binary :none: -i https://pypi.org/simple -- setuptools>=40.6.0 wh                            eel "cffi>=1.8,!=1.11.3; platform_python_implementation != 'PyPy'"" failed with error code 1 in None

On the fly gnss receiver configuration? Or write settings in flash?

We have two ways to configure the U-blox gnss receivers:

  • Send the settings to flash with ubxconfig.sh. It's slow, it doesn't work everytime, but you do have to run it only once.
  • Send the settings to ram during each startup with the str2str -c mySettings.cmd. It's easier if you already have the good settings file, but it needs to use the rtklibexplorer's RTKLIB fork

rtkrcv is always running

With the web app enabled, the rtkrcv app is always running even though there are no users connected. It's a waste of ressources.
We should find a way to start rtkrcv only when a user is connected on the status page, and rtkrcv will stop after the user close this page + a few minutes delay in case he comes back. If there is no delay, rtkrcv will have to recompute the position from scratch.

unit files look for the script in the user home

If the rtkbase folder is not inside "home" but in a subdirectory, the unit file can't start the scripts

ie:
with /home/basegnss/rtkbase it works
with /home/basegnss/foo/rtkbase it doesn't work

venv or not ?

I don't know if we should run the web_app inside a virtual environnement or not.

Too much log from str2str

All str2str instances write their output in syslog. That's too much unuseful data like this:

Jun 05 16:32:09 orangepizero run_cast.sh[583]: 2020/06/05 16:32:27 [CW---]   31076196 B   31042 bps (0) 127.0.0.1 (1) waiting...
Jun 05 16:32:09 orangepizero run_cast.sh[598]: 2020/06/05 16:32:27 [CC---]   31076196 B   31089 bps (0) /dev/ttyACM0 (1) 3 clients
Jun 05 16:32:09 orangepizero run_cast.sh[615]: 2020/06/05 16:32:27 [CC---]   31049708 B   30883 bps (0) 127.0.0.1
Jun 05 16:32:14 orangepizero run_cast.sh[583]: 2020/06/05 16:32:32 [CW---]   31095024 B   30660 bps (0) 127.0.0.1 (1) waiting...
Jun 05 16:32:14 orangepizero run_cast.sh[598]: 2020/06/05 16:32:32 [CC---]   31095024 B   30818 bps (0) /dev/ttyACM0 (1) 3 clients
Jun 05 16:32:14 orangepizero run_cast.sh[615]: 2020/06/05 16:32:32 [CC---]   31068984 B   30404 bps (0) 127.0.0.1
Jun 05 16:32:19 orangepizero run_cast.sh[583]: 2020/06/05 16:32:37 [CW---]   31113744 B   31075 bps (0) 127.0.0.1 (1) waiting...
Jun 05 16:32:19 orangepizero run_cast.sh[598]: 2020/06/05 16:32:37 [CC---]   31113744 B   35438 bps (0) /dev/ttyACM0 (1) 3 clients
Jun 05 16:32:19 orangepizero run_cast.sh[615]: 2020/06/05 16:32:37 [CC---]   31087256 B   31091 bps (0) 127.0.0.1
Jun 05 16:32:24 orangepizero run_cast.sh[583]: 2020/06/05 16:32:42 [CW---]   31133380 B   29552 bps (0) 127.0.0.1 (1) waiting...
Jun 05 16:32:24 orangepizero run_cast.sh[598]: 2020/06/05 16:32:42 [CC---]   31133380 B   29370 bps (0) /dev/ttyACM0 (1) 3 clients
Jun 05 16:32:24 orangepizero run_cast.sh[615]: 2020/06/05 16:32:42 [CC---]   31106892 B   29163 bps (0) 127.0.0.1
Jun 05 16:32:29 orangepizero run_cast.sh[583]: 2020/06/05 16:32:47 [CW---]   31151772 B   28972 bps (0) 127.0.0.1 (1) waiting...
Jun 05 16:32:29 orangepizero run_cast.sh[598]: 2020/06/05 16:32:47 [CC---]   31151772 B   29463 bps (0) /dev/ttyACM0 (1) 3 clients
Jun 05 16:32:29 orangepizero run_cast.sh[615]: 2020/06/05 16:32:47 [CC---]   31125284 B   29227 bps (0) 127.0.0.1
Jun 05 16:32:34 orangepizero run_cast.sh[583]: 2020/06/05 16:32:52 [CW---]   31171532 B   31473 bps (0) 127.0.0.1 (1) waiting...
Jun 05 16:32:34 orangepizero run_cast.sh[598]: 2020/06/05 16:32:52 [CC---]   31171532 B   31856 bps (0) /dev/ttyACM0 (1) 3 clients
Jun 05 16:32:34 orangepizero run_cast.sh[615]: 2020/06/05 16:32:52 [CC---]   31145044 B   31570 bps (0) 127.0.0.1
Jun 05 16:32:39 orangepizero run_cast.sh[583]: 2020/06/05 16:32:57 [CW---]   31190444 B   30850 bps (0) 127.0.0.1 (1) waiting...
Jun 05 16:32:39 orangepizero run_cast.sh[598]: 2020/06/05 16:32:57 [CC---]   31190444 B   31088 bps (0) /dev/ttyACM0 (1) 3 clients
Jun 05 16:32:39 orangepizero run_cast.sh[615]: 2020/06/05 16:32:57 [CC---]   31163956 B   31104 bps (0) 127.0.0.1
Jun 05 16:32:44 orangepizero run_cast.sh[583]: 2020/06/05 16:33:02 [CW---]   31209492 B   30852 bps (0) 127.0.0.1 (1) waiting...
Jun 05 16:32:44 orangepizero run_cast.sh[598]: 2020/06/05 16:33:02 [CC---]   31209492 B   30725 bps (0) /dev/ttyACM0 (1) 3 clients
Jun 05 16:32:44 orangepizero run_cast.sh[615]: 2020/06/05 16:33:02 [CC---]   31183508 B   30771 bps (0) 127.0.0.1
Jun 05 16:32:49 orangepizero run_cast.sh[583]: 2020/06/05 16:33:07 [CW---]   31228276 B   37328 bps (0) 127.0.0.1 (1) waiting...
Jun 05 16:32:49 orangepizero run_cast.sh[598]: 2020/06/05 16:33:07 [CC---]   31228276 B   30594 bps (0) /dev/ttyACM0 (1) 3 clients
Jun 05 16:32:49 orangepizero run_cast.sh[615]: 2020/06/05 16:33:07 [CC---]   31201788 B   30624 bps (0) 127.0.0.1

Web GUI

A web gui would be useful to view/change the settings. Perhaps we could reuse these projects:
https://github.com/GPSFan/ReachView/tree/GPSView
Use python, and some old python modules: flask, jinja, ... to control str2str and rtkrcv
I think I could customize it for rtkbase.

https://github.com/aircool00/SMARTNAV-RTK
Use Gulp, node.js, angular, ....
It controls some systemd services which controls str2str and rtkrcv
It seems more "modern", but I don't have enough skills to really customize it.

Parsing settings.conf

For now to import settings in run_cast.sh and some others scripts, we simply use source ${BASEDIR}/settings.conf

this solution has some drawbacks:

  • You should not put any space around '='
  • "ini Sections" like "[ntrip]" create a non-blocking error

For the coming web gui, I use the python module RawConfigParser which needs ini sections. It's possible to create a fake section when you read the file, but it will write back this section when you save the settings.

One way to remove the error when reading the settings.conf in bash is to use source <( grep=${BASEDIR}/settings.conf) (stackoverflow).
Another one is using "crudini" (available as a python script or a debian package) but it's a new dependency.

The flask web server needs root

It needs to be root to start/stop some systemd's services, reboot/restart/update....
We need to find a way to run it without root.

run_cast.sh crash when the flask secret key contains a backtick

During a test, the flask secret key stored in settings.conf was:
flask_secret_key=b"\x18\x07P[A\x7f\x0fe\x92=`\x86\xb8\xc4\x84\x80\xe3\xe5T\xa9G\xa9w\x06u1\x00\x806S+&\xc3(\x0b\xcd;[o\x08Aj\x8c'\x9e;\xb6P"

because of this backtick, source <( grep = ${BASEDIR}/settings.conf ) could not work correctly, and str2str doesn't start

FR: View cpu temp

View cpu temperature in settings page.

example:

with open('/sys/class/thermal/thermal_zone0/temp', 'r') as ftemp:
    current_temp = int(ftemp.read()) / 1000
    print(current_temp)

FR: copy coordinates

Add a button on the status page to copy the base realtime coordinates in the clipboard

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.