From 2f8350ecc0bbd69170a29e799a466813751ba3fa Mon Sep 17 00:00:00 2001 From: KF7EEL Date: Sat, 11 Sep 2021 06:52:52 -0700 Subject: [PATCH] update README, add hoosk for new dashboard, add WSGI exmples --- README.md | 50 ++++++++++++---------------- data_gateway.py | 87 +++++++++++++++++++++++++++++++++++++------------ web/app.py | 20 ++++++++++++ web/wsgi.ini | 11 +++++++ web/wsgi.py | 11 +++++++ 5 files changed, 129 insertions(+), 50 deletions(-) create mode 100644 web/wsgi.ini create mode 100644 web/wsgi.py diff --git a/README.md b/README.md index 9ea80d2..9bb79a0 100755 --- a/README.md +++ b/README.md @@ -9,9 +9,9 @@ This project originally started as a not so simple set of scripts to decode GPS ### 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 @@ -24,13 +24,29 @@ This project originally started as a not so simple set of scripts to decode GPS ### 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 * 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:** 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** ***0x49 DE N0MJS*** diff --git a/data_gateway.py b/data_gateway.py index 7e14012..94c13e3 100644 --- a/data_gateway.py +++ b/data_gateway.py @@ -103,6 +103,49 @@ __maintainer__ = 'Eric Craw, KF7EEL' __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: @@ -158,27 +201,30 @@ def aprs_send(packet): logger.info('Packet sent to APRS-IS.') def dashboard_loc_write(call, lat, lon, time, comment): - dash_entries = ast.literal_eval(os.popen('cat ' + loc_file).read()) - dash_entries.insert(0, {'call': call, 'lat': lat, 'lon': lon, 'time':time, 'comment':comment}) -# Clear old entries - list_index = 0 - call_count = 0 - new_dash_entries = [] - for i in dash_entries: - if i['call'] == call: - if call_count >= 25: - pass - else: - new_dash_entries.append(i) - call_count = call_count + 1 + if CONFIG['WEB_SERVICE']['REMOTE_CONFIG_ENABLED'] == True: + send_dash_loc(CONFIG, call, lat, lon, time, comment, dmr_id) + else: + dash_entries = ast.literal_eval(os.popen('cat ' + loc_file).read()) + dash_entries.insert(0, {'call': call, 'lat': lat, 'lon': lon, 'time':time, 'comment':comment}) + # Clear old entries + list_index = 0 + call_count = 0 + new_dash_entries = [] + for i in dash_entries: + if i['call'] == call: + if call_count >= 25: + pass + else: + new_dash_entries.append(i) + call_count = call_count + 1 - if call != i['call']: - new_dash_entries.append(i) - pass - list_index = list_index + 1 - with open(loc_file, 'w') as user_loc_file: - user_loc_file.write(str(new_dash_entries[:500])) - user_loc_file.close() + if call != i['call']: + new_dash_entries.append(i) + pass + list_index = list_index + 1 + with open(loc_file, 'w') as user_loc_file: + user_loc_file.write(str(new_dash_entries[:500])) + user_loc_file.close() logger.info('User location saved for dashboard') #logger.info(dash_entries) @@ -1192,6 +1238,7 @@ def rule_timer_loop(): del UNIT_MAP[unit] logger.debug('Removed unit(s) %s from UNIT_MAP', remove_list) + ping(CONFIG) class OBP(OPENBRIDGE): diff --git a/web/app.py b/web/app.py index 49ff466..91ef244 100644 --- a/web/app.py +++ b/web/app.py @@ -2419,6 +2419,20 @@ TG #: ''' + str(tg_d.tg) + ''' ) db.session.add(burn_list) 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): update_b = BurnList.query.filter_by(dmr_id=_dmr_id).first() @@ -5849,6 +5863,12 @@ TG #: ''' + str(tg_d.tg) + ''' 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']] 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: if hblink_req['get_config']: diff --git a/web/wsgi.ini b/web/wsgi.ini new file mode 100644 index 0000000..f51bb24 --- /dev/null +++ b/web/wsgi.ini @@ -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 diff --git a/web/wsgi.py b/web/wsgi.py new file mode 100644 index 0000000..3dfb2cc --- /dev/null +++ b/web/wsgi.py @@ -0,0 +1,11 @@ +from app import create_app + +app = create_app() + + +if __name__ == "__main__": +# app = create_app() + + app.run() + +