update README, add hoosk for new dashboard, add WSGI exmples

This commit is contained in:
KF7EEL 2021-09-11 06:52:52 -07:00
parent 2d3185f94f
commit 2f8350ecc0
5 changed files with 129 additions and 50 deletions

View File

@ -9,9 +9,9 @@ This project originally started as a not so simple set of scripts to decode GPS
### User end features: ### User end features:
* Handles user registration and email verification, and more * Handles user registration and email verification
* Individual passphrases for each user * Individual hotspot passphrases for each user
* Automatic retrieval of DMR IDs on registration * Automatic retrieval of DMR IDs on registration
@ -24,13 +24,29 @@ This project originally started as a not so simple set of scripts to decode GPS
### Administrative features: ### Administrative features:
* Administrate multiple DMR servers through the web service * Administrate multiple DMR servers through a single web service
* Optional manual approval of new users * Optional manual approval of new users
* Multiple Admin user logins * Multiple Admin user logins
* Entirely configure DMR server (HBlink) in web service
### OpenBridge additions
* Enhanced unit call routing between connected servers. Every server known which server every subscribers is on.
* Optionally encrypt data sent over OpenBridge
### Data Gateway (APRS/SMS)
* Compatable with HBNet and original HBLink.
* Connect your server via OpenBridge or MMDVM.
* Decodes GPS positions and generates APRS positions
* Simple web dashboard
@ -68,32 +84,6 @@ None. The owners of this work make absolutely no warranty, express or implied. U
**PRE-REQUISITE KNOWLEDGE:** **PRE-REQUISITE KNOWLEDGE:**
This document assumes the reader is familiar with Linux/UNIX, the Python programming language and DMR. This document assumes the reader is familiar with Linux/UNIX, the Python programming language and DMR.
**Using docker version**
To work with provided docker setup you will need:
* A private repository with your configuration files (all .cfg files in repo will be copyed to the application root directory on start up)
* A service user able to read your private repository (or be brave and publish your configuration, or be really brave and give your username and password to the docker)
* A server with docker installed
* Follow this simple steps:
Build your own image from source
```bash
docker build . -t millaguie/hblink:3.0.0
```
Or user a prebuilt one in docker hub: millaguie/hblink:3.0.0
Wake up your container
```bash
touch /var/log/hblink.log
chown 65000 /var/log/hblink.log
run -v /var/log/hblink.log:/var/log/hblink.log -e GIT_USER=$USER -e GIT_PASSWORD=$PASSWORD -e GIT_REPO=$URL_TO_REPO_WITHOUT_HTTPS:// -p 54000:54000 millaguie/hblink:3.0.0
```
**MORE DOCUMENTATION TO COME** **MORE DOCUMENTATION TO COME**
***0x49 DE N0MJS*** ***0x49 DE N0MJS***

View File

@ -103,6 +103,49 @@ __maintainer__ = 'Eric Craw, KF7EEL'
__email__ = 'kf7eel@qsl.net' __email__ = 'kf7eel@qsl.net'
def ping(CONFIG):
user_man_url = CONFIG['WEB_SERVICE']['URL']
shared_secret = str(sha256(CONFIG['WEB_SERVICE']['SHARED_SECRET'].encode()).hexdigest())
ping_data = {
'ping': CONFIG['WEB_SERVICE']['THIS_SERVER_NAME'],
'secret':shared_secret
}
json_object = json.dumps(ping_data, indent = 4)
try:
req = requests.post(user_man_url, data=json_object, headers={'Content-Type': 'application/json'})
## resp = json.loads(req.text)
## print(resp)
## return resp['rules']
except requests.ConnectionError:
logger.error('Config server unreachable')
## return config.build_config(cli_file)
def send_dash_loc(CONFIG, call, lat, lon, time, comment, dmr_id):
user_man_url = CONFIG['WEB_SERVICE']['URL']
shared_secret = str(sha256(CONFIG['WEB_SERVICE']['SHARED_SECRET'].encode()).hexdigest())
ping_data = {
'dashboard': CONFIG['WEB_SERVICE']['THIS_SERVER_NAME'],
'secret':shared_secret,
'call': call,
'lat' : lat,
'lon' : lon,
'comment' : comment,
'dmr_id' : dmr_id
}
json_object = json.dumps(ping_data, indent = 4)
try:
req = requests.post(user_man_url, data=json_object, headers={'Content-Type': 'application/json'})
## resp = json.loads(req.text)
## print(resp)
## return resp['rules']
except requests.ConnectionError:
logger.error('Config server unreachable')
## return config.build_config(cli_file)
################################################################################################## ##################################################################################################
# Headers for GPS by model of radio: # Headers for GPS by model of radio:
@ -158,27 +201,30 @@ def aprs_send(packet):
logger.info('Packet sent to APRS-IS.') logger.info('Packet sent to APRS-IS.')
def dashboard_loc_write(call, lat, lon, time, comment): def dashboard_loc_write(call, lat, lon, time, comment):
dash_entries = ast.literal_eval(os.popen('cat ' + loc_file).read()) if CONFIG['WEB_SERVICE']['REMOTE_CONFIG_ENABLED'] == True:
dash_entries.insert(0, {'call': call, 'lat': lat, 'lon': lon, 'time':time, 'comment':comment}) send_dash_loc(CONFIG, call, lat, lon, time, comment, dmr_id)
# Clear old entries else:
list_index = 0 dash_entries = ast.literal_eval(os.popen('cat ' + loc_file).read())
call_count = 0 dash_entries.insert(0, {'call': call, 'lat': lat, 'lon': lon, 'time':time, 'comment':comment})
new_dash_entries = [] # Clear old entries
for i in dash_entries: list_index = 0
if i['call'] == call: call_count = 0
if call_count >= 25: new_dash_entries = []
pass for i in dash_entries:
else: if i['call'] == call:
new_dash_entries.append(i) if call_count >= 25:
call_count = call_count + 1 pass
else:
new_dash_entries.append(i)
call_count = call_count + 1
if call != i['call']: if call != i['call']:
new_dash_entries.append(i) new_dash_entries.append(i)
pass pass
list_index = list_index + 1 list_index = list_index + 1
with open(loc_file, 'w') as user_loc_file: with open(loc_file, 'w') as user_loc_file:
user_loc_file.write(str(new_dash_entries[:500])) user_loc_file.write(str(new_dash_entries[:500]))
user_loc_file.close() user_loc_file.close()
logger.info('User location saved for dashboard') logger.info('User location saved for dashboard')
#logger.info(dash_entries) #logger.info(dash_entries)
@ -1192,6 +1238,7 @@ def rule_timer_loop():
del UNIT_MAP[unit] del UNIT_MAP[unit]
logger.debug('Removed unit(s) %s from UNIT_MAP', remove_list) logger.debug('Removed unit(s) %s from UNIT_MAP', remove_list)
ping(CONFIG)
class OBP(OPENBRIDGE): class OBP(OPENBRIDGE):

View File

@ -2419,6 +2419,20 @@ TG #: <strong> ''' + str(tg_d.tg) + '''</strong>
) )
db.session.add(burn_list) db.session.add(burn_list)
db.session.commit() db.session.commit()
def dash_loc_add(_call, _lat, _lon, _time, _comment, _dmr_id, _server):
add_loc = GPS_LocLog(
callsign = _callsign,
lat = _lat,
lon = _lon,
time = _time,
comment = _comment,
dmr_id = _dmr_id,
server = _server,
system_name = ''
)
db.session.add(add_bridge)
db.session.commit()
def update_burnlist(_dmr_id, _version): def update_burnlist(_dmr_id, _version):
update_b = BurnList.query.filter_by(dmr_id=_dmr_id).first() update_b = BurnList.query.filter_by(dmr_id=_dmr_id).first()
@ -5849,6 +5863,12 @@ TG #: <strong> ''' + str(tg_d.tg) + '''</strong>
else: else:
peer_locations[hblink_req['dmr_id']] = [hblink_req['loc_callsign'], hblink_req['lat'], hblink_req['lon'], hblink_req['url'], hblink_req['description'], hblink_req['loc'], hblink_req['software']] peer_locations[hblink_req['dmr_id']] = [hblink_req['loc_callsign'], hblink_req['lat'], hblink_req['lon'], hblink_req['url'], hblink_req['description'], hblink_req['loc'], hblink_req['software']]
response = '' response = ''
elif 'dashboard' in hblink_req:
if 'lat' in hblink_req:
# Assuming this is a GPS loc
dash_loc_add(hblink_req['call'], hblink_req['lat'], hblink_req['lon'], time(), hblink_req['comment'], hblink_req['dmr_id'], hblink_req['dashboard'])
elif 'get_config' in hblink_req: elif 'get_config' in hblink_req:
if hblink_req['get_config']: if hblink_req['get_config']:

11
web/wsgi.ini Normal file
View File

@ -0,0 +1,11 @@
[uwsgi]
module = wsgi:app
master = true
processes = 2
socket = /tmp/hbnet_web_service.sock
chmod-socket = 666
vacuum = true
die-on-term = true

11
web/wsgi.py Normal file
View File

@ -0,0 +1,11 @@
from app import create_app
app = create_app()
if __name__ == "__main__":
# app = create_app()
app.run()