Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
f4282d8
Setup and dependecies
tommasopolonelli Feb 28, 2025
8c72c5b
Install requirements local build
tommasopolonelli Mar 1, 2025
fae8ffb
Update README.md
tommasopolonelli Mar 1, 2025
efb1aeb
fixed install dependecies sudo rtkbase_riscv/tools/install.sh -u debi…
tommasopolonelli Mar 5, 2025
5d0614c
Success run on MilkV Duo - geventmp installed - removed monkey-patch.all
tommasopolonelli Mar 11, 2025
60ba1de
Default config to run stably
tommasopolonelli Mar 11, 2025
504fe7e
E2E test with UBlox F9P and NTRIP - CPU temp and Uptime still not fun…
tommasopolonelli Mar 17, 2025
d7a82ad
Update install.sh
tommasopolonelli Mar 24, 2025
060ec54
Update rtkbase_web.service
tommasopolonelli Mar 24, 2025
178b59a
CPU Temp
tommasopolonelli Mar 30, 2025
74bbd8e
Test UM980
tommasopolonelli Apr 2, 2025
fc4a00e
Satellite test Unicore UM980 - via UART0
tommasopolonelli Apr 7, 2025
d73dafe
Fixed detect and configure on the Web page
tommasopolonelli Apr 7, 2025
4e211e1
Update swap.sh
tommasopolonelli Apr 7, 2025
d1b79eb
Fix configure and detect via webpage
tommasopolonelli Apr 9, 2025
aba15ed
update default settings
tommasopolonelli Apr 9, 2025
2b0a59e
Update install.sh
tommasopolonelli Apr 16, 2025
c60db5f
display_app
tommasopolonelli Apr 23, 2025
bbcccaa
Executable for 2in15 display with auto mutliplexer configuration
tommasopolonelli Apr 24, 2025
be889f2
- Deleted app specific files
May 14, 2025
8bf31e7
code cleanup
May 14, 2025
5c2e757
Update README.md
tommasopolonelli May 14, 2025
cb49eb8
Back to default config
May 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ test.sh
test.conf
*.FCStd1
**/venv*/*
**/build/
**/build/
*.o
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ A gnss receiver with a timepulse output is a very accurate [stratum 0](https://e
```
## Requirements:
Debian base distro >= 11 (Bullseye)
Python >= 3.8
3.8 >= Python <= 3.13

## History:
See the [changelog](./CHANGELOG.md)
Expand Down
35 changes: 22 additions & 13 deletions receiver_cfg/Unicore_UM980_rtcm3.cfg
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
# Config file for using a Unicore UM980 with RTKBase (RTCM3)
# SIGNALGROUP will reset the device
CONFIG SIGNALGROUP 2
# CONFIG SIGNALGROUP 2
CONFIG SBAS ENABLE AUTO
MODE BASE 1 TIME 60 1
rtcm1019 1
rtcm1020 1
rtcm1042 1
rtcm1044 1
rtcm1045 1
rtcm1046 1
rtcm1077 1
rtcm1087 1
rtcm1097 1
rtcm1107 1
rtcm1117 1
rtcm1127 1
rtcm1003 com2 1
rtcm1006 com2 10
rtcm1011 com2 1
rtcm1019 com2 1
rtcm1020 com2 1
rtcm1033 com2 10
rtcm1042 com2 1
rtcm1044 com2 1
rtcm1045 com2 1
rtcm1046 com2 1
rtcm1074 com2 1
rtcm1077 com2 1
rtcm1084 com2 1
rtcm1087 com2 1
rtcm1094 com2 1
rtcm1097 com2 1
rtcm1107 com2 1
rtcm1117 com2 1
rtcm1124 com2 1
rtcm1127 com2 1
CONFIG PPS ENABLE GPS POSITIVE 500000 1000 0 0*6E
2 changes: 1 addition & 1 deletion settings.conf.default
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ cpu_temp_offset=0

[main]
#base coordinates: lat long height
position='47.0983869 -1.2655108 36.40'
position='47.1983869 -1.1655108 36.40'
#gnss receiver com port
com_port=''
#gnss receiver com port settings
Expand Down
104 changes: 60 additions & 44 deletions tools/install.sh

Large diffs are not rendered by default.

13 changes: 11 additions & 2 deletions unit/rtkbase_web.service
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,21 @@ Description=RTKBase Web Server

[Service]
User=root
ExecStart={python_path} {script_path}/web_app/server.py
WorkingDirectory=/home/debian
Environment="PATH=/usr/local/bin:/usr/bin:/bin"
Environment="HOME=/home/debian"
Environment="LOGNAME=debian"
#StandardOutput=append:/var/log/rtkbase_web.log

# Run the install.sh command before starting the main service
ExecStartPre=/home/debian/rtkbase_riscv/tools/install.sh -u debian --pin-mux

ExecStart=/home/debian/rtkbase_riscv/venv/bin/python /home/debian/rtkbase_riscv/web_app/server.py
Restart=on-failure
RestartSec=30
#ProtectHome=read-only
#ProtectSystem=strict
#ReadWritePaths={script_path} /var/tmp /usr/local/bin
#ReadWritePaths=/home/debian/rtkbase_riscv /var/tmp /usr/local/bin

[Install]
WantedBy=multi-user.target
2 changes: 1 addition & 1 deletion web_app/network_infos.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def get_up_if():
if_stats.pop('lo')
log.debug(if_stats)
if_stats = {k:v for (k,v) in if_stats.items() if if_stats[k].isup} # keep only up interface
if_stats = {k:v for (k,v) in if_stats.items() if if_stats[k].speed > 0 or 'pointopoint' in if_stats[k].flags} # keep only interface with speed > 0
#if_stats = {k:v for (k,v) in if_stats.items() if if_stats[k].speed > 0 or 'pointopoint' in if_stats[k].flags} # keep only interface with speed > 0
if_stats = {k:v for (k,v) in if_stats.items() if not k.startswith('docker')} # remove docker interface
return if_stats

Expand Down
6 changes: 0 additions & 6 deletions web_app/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,26 @@ bidict==0.22.1
blinker==1.6.3
Bootstrap-Flask==2.4.0
certifi==2024.2.2
cffi==1.16.0
charset-normalizer==3.3.2
click==8.1.7
cryptography==42.0.7
distro==1.8.0
dnspython==2.6.1
Flask==3.0.3
Flask-Login==0.6.3
Flask-SocketIO==5.3.6
Flask-WTF==1.2.1
gevent==24.2.1
gunicorn==22.0.0
h11==0.14.0
idna==3.7
itsdangerous==2.1.2
Jinja2==3.1.4
lxml==4.9.3
MarkupSafe==2.1.3
nmcli==1.3.0
pexpect==4.8.0
psutil==5.9.6
ptyprocess==0.7.0
pycparser==2.21
pyOpenSSL==24.1.0
pyserial==3.5
pystemd==0.13.2
python-engineio==4.8.0
python-socketio==5.10.0
requests==2.32.3
Expand Down
88 changes: 50 additions & 38 deletions web_app/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
# along with ReachView. If not, see <http://www.gnu.org/licenses/>.

from gevent import monkey
monkey.patch_all()
#monkey.patch_all()

import time
import json
Expand All @@ -47,12 +47,6 @@
from RTKBaseConfigManager import RTKBaseConfigManager
import network_infos

#print("Installing all required packages")
#provisioner.provision_reach()

#import reach_bluetooth.bluetoothctl
#import reach_bluetooth.tcp_bridge

from flask_bootstrap import Bootstrap4
from flask import Flask, render_template, session, request, flash, url_for
from flask import send_from_directory, redirect, abort
Expand All @@ -73,6 +67,10 @@
from werkzeug.utils import safe_join
import gunicorn.app.base

#Delay before rtkrcv will stop if no user is on status.html page
rtkcv_standby_delay = 600
connected_clients = 0

app = Flask(__name__)
app.debug = False
app.config["SECRET_KEY"] = "secret!"
Expand Down Expand Up @@ -111,10 +109,6 @@
{'service_unit' : 'rtkbase_gnss_web_proxy.service', "name": "RTKBase Reverse Proxy for Gnss receiver Web Server"}
]

#Delay before rtkrcv will stop if no user is on status.html page
rtkcv_standby_delay = 600
connected_clients = 0

class StandaloneApplication(gunicorn.app.base.BaseApplication):
def __init__(self, app, options=None):
self.options = options or {}
Expand Down Expand Up @@ -158,46 +152,58 @@ def update_password(config_object):
config_object.update_setting("general", "web_password_hash", generate_password_hash(new_password))
config_object.update_setting("general", "new_web_password", "")


def update_sys_informations():

if not hasattr(update_sys_informations, "max_cpu_temp"):
update_sys_informations.max_cpu_temp = 0 # it doesn't exist yet, so initialize it

cpu_temp_offset = int(rtkbaseconfig.get("general", "cpu_temp_offset"))

cpu_temp = get_cpu_temp() + cpu_temp_offset
update_sys_informations.max_cpu_temp = max(cpu_temp, update_sys_informations.max_cpu_temp)

try:
interfaces_infos = network_infos.get_interfaces_infos()
except Exception:
# network-manager not installed ?
interfaces_infos = None

volume_usage = get_volume_usage()
sys_infos = {"cpu_temp" : cpu_temp,
"max_cpu_temp" : update_sys_informations.max_cpu_temp,
"uptime" : get_uptime(),
"volume_free" : round(volume_usage.free / 10E8, 2),
"volume_used" : round(volume_usage.used / 10E8, 2),
"volume_total" : round(volume_usage.total / 10E8, 2),
"volume_percent_used" : volume_usage.percent,
"network_infos" : interfaces_infos}

return sys_infos

def manager():
""" This manager runs inside a separate thread
It checks how long rtkrcv is running since the last user leaves the
status web page, and stop rtkrcv when sleep_count reaches rtkrcv_standby delay
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_offset
max_cpu_temp = max(cpu_temp, max_cpu_temp)

if connected_clients > 0:

# We only need to emit to the socket if there are clients able to receive it.
updated_services_status = getServicesStatus(emit_pingback=False)
main_service = updated_services_status[0]
if services_status != updated_services_status:
services_status = updated_services_status
socketio.emit("services status", json.dumps(services_status), namespace="/test")
#print("service status", services_status)

try:
interfaces_infos = network_infos.get_interfaces_infos()
except Exception:
# network-manager not installed ?
interfaces_infos = None

volume_usage = get_volume_usage()
sys_infos = {"cpu_temp" : cpu_temp,
"max_cpu_temp" : max_cpu_temp,
"uptime" : get_uptime(),
"volume_free" : round(volume_usage.free / 10E8, 2),
"volume_used" : round(volume_usage.used / 10E8, 2),
"volume_total" : round(volume_usage.total / 10E8, 2),
"volume_percent_used" : volume_usage.percent,
"network_infos" : interfaces_infos}
socketio.emit("sys_informations", json.dumps(sys_infos), namespace="/test")
print("service status", services_status)

# Make sure max_cpu_temp is always updated
sys_infos = update_sys_informations()
socketio.emit("sys_informations", json.dumps(sys_infos), namespace="/test")

if rtk.sleep_count > rtkcv_standby_delay and rtk.state != "inactive" or \
main_service.get("active") == False and rtk.state != "inactive":
Expand Down Expand Up @@ -245,7 +251,7 @@ def old_get_cpu_temp():
def get_cpu_temp():
try:
temps = psutil.sensors_temperatures()
current_cpu_temp = round(temps.get('cpu_thermal')[0].current, 1)
current_cpu_temp = round(temps.get('soc_thermal_0')[0].current, 1)
except:
current_cpu_temp = 0
return current_cpu_temp
Expand Down Expand Up @@ -556,11 +562,13 @@ def clientConnect():
rtkbaseconfig.write_file()
socketio.emit("update_successful", json.dumps({"result": 'true'}), namespace="/test")
rtk.sendState()
sys_infos = update_sys_informations()
socketio.emit("sys_informations", json.dumps(sys_infos), namespace="/test")

@socketio.on("disconnect", namespace="/test")
def clientDisconnect():
global connected_clients
connected_clients -=1
connected_clients -= 1
print("Browser client disconnected")

#### Log list handling ###
Expand Down Expand Up @@ -627,9 +635,11 @@ def deleteLog(json_msg):

@socketio.on("detect_receiver", namespace="/test")
def detect_receiver(json_msg):
print("Detecting gnss receiver")
#print("Detecting gnss receiver")
#print("DEBUG json_msg: ", json_msg)
#print([os.path.join(rtkbase_path, "tools", "install.sh"), "--user", rtkbaseconfig.get("general", "user"), "--detect-gnss", "--no-write-port"])
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, check=False)
#print(answer)
if answer.returncode == 0 and "/dev/" in answer.stdout:
#print("DEBUG ok stdout: ", answer.stdout)
try:
Expand Down Expand Up @@ -665,13 +675,15 @@ def configure_receiver(brand="", model=""):
# configure the receiver. We wait a few seconds before stopping it to remove conflicting calls.
time.sleep(4)
main_service = services_list[0]
#print(main_service)
if main_service.get("active") is True:
main_service["unit"].stop()
restart_main = True
else:
restart_main = False

print("configuring {} gnss receiver model {}".format(brand, model))
#print("configuring {} gnss receiver model {}".format(brand, model))
#print([os.path.join(rtkbase_path, "tools", "install.sh"), "--user", rtkbaseconfig.get("general", "user"), "--configure-gnss"])
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, check=False)
#print("DEBUG - stdout: ", answer.stdout)
#print("DEBUG - returncode: ", answer.returncode)
Expand Down