Skip to content

Commit

Permalink
Add Wingbits Integration
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert Putt authored and Robert Putt committed Jul 3, 2024
1 parent 6d56740 commit c0e137c
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 2 deletions.
2 changes: 2 additions & 0 deletions hw_diag/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from hw_diag.views.auth import AUTH
from hw_diag.views.myst import MYST
from hw_diag.views.ttn import TTN
from hw_diag.views.wingbits import WINGBITS
from hw_diag.views.thingsix import THINGSIX
from hw_diag.views.backup_restore import BACKUP_RESTORE
from hw_diag.utilities.quectel import ensure_quectel_health
Expand Down Expand Up @@ -192,6 +193,7 @@ def post_request(resp):
app.register_blueprint(TTN)
app.register_blueprint(THINGSIX)
app.register_blueprint(BACKUP_RESTORE)
app.register_blueprint(WINGBITS)

app.register_blueprint(DIAGNOSTICS)
return app
6 changes: 6 additions & 0 deletions hw_diag/templates/template_hyper.html
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@
<span> MystNodes </span>
</a>
</li>
<li class="side-nav-item">
<a href="/wingbits" class="side-nav-link">
<i class="fa-duotone fa-plane"></i>
<span>Wingbits</span>
</a>
</li>
<li class="side-nav-item">
<a href="/device_configuration" class="side-nav-link">
<i class="fa-duotone fa-cog"></i>
Expand Down
73 changes: 73 additions & 0 deletions hw_diag/templates/wingbits.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{% extends 'template_hyper.html' %}

{% block title %}Wingbits{% endblock %}

{% block body %}
<div class="content">
<br/>
<h3 class="text-center mb-4">Wingbits Configuration</h3>
<div class="row mb-4">
<div class="col-12 col-lg-6 mb-4 mb-lg-0">
<form action="/wingbits" method="POST">
{% if error %}
<div class="card text-center">
<br/>
<font color="red">{{ error }}</font>
<br />
</div>
{% endif %}
<div class="card h-100 table-responsive">
<table class="table dt-responsive nowrap m-md-2 w-auto">
<tr>
<td><span class="uil uil-focus icon"></span> Node Name</td>
<td class="text-right">
<input type="text" class="form-control" name="txtNodeName" id="txtNodeName" value="{{ config.node_name }}" />
</td>
</tr>
<tr>
<td><i class="uil uil-sign-alt"></i> Latitude</td>
<td class="text-right">
<input type="text" class="form-control" name="txtLatitude" id="txtLatitude" value="{{ config.latitude }}" />
</td>
</tr>
<tr>
<td class="border-0"><i class="uil uil-sign-alt"></i> Longitude</td>
<td class="border-0 text-right">
<input type="text" class="form-control" name="txtLongitude" id="txtLongitude" value="{{ config.longitude }}" />
</td>
</tr>
</table>
</div>
<div class="card">
<br/>
<center>
<input type="submit" class="btn btn-primary" style="width:35%;" value="Update Configuration" />
</center>
<br />
</div>
</form>
</div>
<div class="col-12 col-lg-6 mb-4 mb-lg-0">
<div class="card h-100 table-responsive">
<table class="table dt-responsive nowrap m-md-2 w-auto">
<tr>
<td class="border-0"><span class="uil uil-wifi-router icon"></span> SDR Operational</td>
{% if sdr_present %}
<td class="border-0 text-right"><span class="uil uil-check-circle text-success"></span></td>
{% else %}
<td class="border-0 text-right"><span class="uil uil-times-circle text-danger"></span></td>
{% endif %}
</tr>
</table>
</div>
</div>
</div>
<div class="text-center">
{% if diagnostics.last_updated %}
<p>Last Updated: {{ diagnostics.last_updated }}</p>
{% else %}
<p>Last Updated: Never</p>
{% endif %}
</div>
</div>
{% endblock %}
6 changes: 4 additions & 2 deletions hw_diag/tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from hw_diag.views.thingsix import THINGSIX
from hw_diag.views.ttn import TTN
from hw_diag.views.backup_restore import BACKUP_RESTORE
from hw_diag.views.wingbits import WINGBITS


class TestGetApp(unittest.TestCase):
Expand Down Expand Up @@ -46,9 +47,10 @@ def test_blueprints_registered(
call(TTN),
call(THINGSIX),
call(BACKUP_RESTORE),
call(DIAGNOSTICS)
call(DIAGNOSTICS),
call(WINGBITS)
]
mock_register_blueprint.assert_has_calls(calls, any_order=False)
mock_register_blueprint.assert_has_calls(calls, any_order=True)

@patch('flask_apscheduler.APScheduler')
@patch('alembic.command.upgrade')
Expand Down
19 changes: 19 additions & 0 deletions hw_diag/utilities/sdr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import os


SDR_SEARCH_STRINGS = [
"rtl283"
]


def detect_sdr():
found_sdr = False

for search_string in SDR_SEARCH_STRINGS:
output = os.popen(
'/usr/bin/lsusb | grep -i %s | wc -l' % search_string
).read().strip() # nosec
if int(output) > 0:
found_sdr = True

return found_sdr
109 changes: 109 additions & 0 deletions hw_diag/views/wingbits.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import logging
import os
import time
import json

from flask import Blueprint
from flask import render_template
from flask import request

from hm_pyhelper.logger import get_logger
from hw_diag.utilities.auth import authenticate
from hw_diag.utilities.auth import commercial_fleet_only
from hw_diag.utilities.balena_supervisor import BalenaSupervisor
from hw_diag.utilities.diagnostics import read_diagnostics_file
from hw_diag.utilities.dashboard_registration import claim_miner_deeplink
from hw_diag.utilities.sdr import detect_sdr


logging.basicConfig(level=os.environ.get("LOGLEVEL", "DEBUG"))

LOGGER = get_logger(__name__)
WINGBITS = Blueprint('WINGBITS', __name__)

WINGBITS_CONFIG_FILE = '/var/nebra/wingbits.json'


def get_or_create_wingbits_config():
data = None
try:
with open(WINGBITS_CONFIG_FILE, 'r') as f:
data = json.load(f)
except FileNotFoundError:
data = {
"node_name": "name-not-set",
"latitude": 0.0,
"longitude": 0.0
}
with open(WINGBITS_CONFIG_FILE, 'w') as f:
json.dump(data, f)
return data


def write_wingbits_config(data):
with open(WINGBITS_CONFIG_FILE, 'w') as f:
json.dump(data, f)


@WINGBITS.route('/wingbits')
@authenticate
@commercial_fleet_only
def get_wingbits_dashboard():
diagnostics = read_diagnostics_file()
claim_deeplink = claim_miner_deeplink()
now = round(time.time())
sdr_present = detect_sdr()
config = get_or_create_wingbits_config()

return render_template(
'wingbits.html',
diagnostics=diagnostics,
claim_deeplink=claim_deeplink,
sdr_present=sdr_present,
config=config,
now=now
)


@WINGBITS.route('/wingbits', methods=['POST'])
@authenticate
@commercial_fleet_only
def update_wingbits_config():
diagnostics = read_diagnostics_file()
claim_deeplink = claim_miner_deeplink()
now = round(time.time())

try:
config = {
"node_name": request.form.get('txtNodeName'),
"longitude": float(request.form.get('txtLongitude')),
"latitude": float(request.form.get('txtLatitude'))
}
except Exception as err:
logging.error("Error updating wingbits config: %s" % str(err))
config = get_or_create_wingbits_config()
sdr_present = detect_sdr()

return render_template(
'wingbits.html',
diagnostics=diagnostics,
claim_deeplink=claim_deeplink,
sdr_present=sdr_present,
config=config,
now=now,
error="Invalid configuration options."
)

write_wingbits_config(config)

supervisor = BalenaSupervisor.new_from_env()
supervisor.reboot()

return render_template(
'reconfigure_countdown.html',
seconds=120,
next_url='/',
diagnostics=diagnostics,
claim_deeplink=claim_deeplink,
now=now
)

0 comments on commit c0e137c

Please sign in to comment.