Skip to content

Commit

Permalink
Merge pull request #655 from thorrak/dev
Browse files Browse the repository at this point in the history
Compatibility Enhancements
  • Loading branch information
thorrak authored Dec 8, 2021
2 parents 8e91ec4 + b2069a9 commit 5719c02
Show file tree
Hide file tree
Showing 17 changed files with 334 additions and 39 deletions.
40 changes: 40 additions & 0 deletions .github/workflows/docker-hub-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: 'Build & Push to Docker Hub'

on:
push:
branches:
- no_bluez

jobs:
buildx:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v2
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
with:
platforms: all
-
name: Dockerhub login
env:
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
run: |
echo "${DOCKER_PASSWORD}" | docker login --username ${DOCKER_USERNAME} --password-stdin
-
name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
with:
version: latest
-
name: Build dockerfile (armv7/amd64/arm64)
run: |
docker buildx build \
--platform=linux/arm/v7,linux/amd64,linux/i386 \
--output "type=image,push=true" \
--file ./compose/production/django/Dockerfile . \
--tag jdbeeler/fermentrack:nobluez
2 changes: 1 addition & 1 deletion app/api/lcd.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

def getLCDs(req):
ret = []
all_devices = BrewPiDevice.objects.all()
all_devices = BrewPiDevice.objects.all().order_by('device_name')
for dev in all_devices:
ret.append({"device_name": dev.device_name, "lcd_data": dev.read_lcd(),
'device_url': reverse('device_dashboard', kwargs={'device_id': dev.id,}),
Expand Down
18 changes: 18 additions & 0 deletions app/migrations/0003_allow_blank_wifi_host_ip.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.0.13 on 2021-04-09 03:30

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('app', '0002_fermentationprofile_notes'),
]

operations = [
migrations.AlterField(
model_name='brewpidevice',
name='wifi_host_ip',
field=models.CharField(blank=True, default='', help_text='Cached IP address in case of mDNS issues (only used if connection_type is wifi)', max_length=46),
),
]
26 changes: 17 additions & 9 deletions app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ class Meta:
wifi_host = models.CharField(max_length=40, default='None',
help_text="mDNS host name or IP address for WiFi connected hardware (only used if " +
"connection_type is wifi)")
wifi_host_ip = models.CharField(max_length=46, default='', help_text="Cached IP address in case of mDNS issues (only used if connection_type is wifi)")
wifi_host_ip = models.CharField(max_length=46, blank=True, default='', help_text="Cached IP address in case of mDNS issues (only used if connection_type is wifi)")
wifi_port = models.IntegerField(default=23, validators=[MinValueValidator(10,"Port must be 10 or higher"),
MaxValueValidator(65535, "Port must be 65535 or lower")],
help_text="The internet socket to use (only used if connection_type is wifi)")
Expand Down Expand Up @@ -977,26 +977,34 @@ def status_process(self):
status = fc.application_status(name=circus_process_name)
return status

def get_cached_ip(self, save_to_cache=True):
def get_cached_ip(self):
# This only gets called from within BrewPi-script

# I really hate the name of the function, but I can't think of anything else. This basically does three things:
# 1. Looks up the mDNS hostname (if any) set as self.wifi_host and gets the IP address
# 2. (Optional) Saves that IP address to self.wifi_host_ip (if we were successful in step 1)
# 2. Saves that IP address to self.wifi_host_ip (if we were successful in step 1)
# 3. Returns the found IP address (if step 1 was successful), the cached (self.wifi_host_ip) address if it
# wasn't, or 'None' if we don't have a cached address and we weren't able to resolve the hostname
if len(self.wifi_host) > 4:
try:
ip_list = []
ipv6_list = []
ais = socket.getaddrinfo(self.wifi_host, 0, 0, 0, 0)
for result in ais:
ip_list.append(result[-1][0])
if result[0] == socket.AddressFamily.AF_INET:
# IPv4 only
ip_list.append(result[-1][0])
elif result[0] == socket.AddressFamily.AF_INET6:
ipv6_list.append(result[-1][0])
ip_list = list(set(ip_list))
resolved_address = ip_list[0]
if self.wifi_host_ip != resolved_address and save_to_cache:
# If we were able to find an IP address, save it to the cache
self.wifi_host_ip = resolved_address
self.save()
ipv6_list = list(set(ip_list))
if len(ip_list) > 0:
resolved_address = ip_list[0]
else:
resolved_address = ipv6_list[0]
# If we were able to find an IP address, save it to the cache
self.wifi_host_ip = resolved_address
self.save()
return resolved_address
except:
# TODO - Add an error message here
Expand Down
4 changes: 4 additions & 0 deletions app/setup_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class GuidedSetupConfigForm(forms.Form):
(True, 'Yes'),
(False, 'No')
]
theme_select = settings.CONSTANCE_ADDITIONAL_FIELDS['custom_theme_select'][1]['choices']

update_options = settings.CONSTANCE_ADDITIONAL_FIELDS['git_update_type_select'][1]['choices'][1:]

Expand All @@ -64,6 +65,8 @@ class GuidedSetupConfigForm(forms.Form):
# database table hasn't been created yet (ie - at initial setup)
brewery_name = forms.CharField() # initial=config.BREWERY_NAME

custom_theme = forms.ChoiceField(choices=theme_select)

date_time_format_display = forms.ChoiceField( # initial=config.DATE_TIME_FORMAT_DISPLAY
choices=date_time_display_select_choices,
)
Expand Down Expand Up @@ -109,6 +112,7 @@ def __init__(self, *args, **kwargs):

self.fields['brewery_name'].initial = config.BREWERY_NAME
self.fields['brewery_name'].help_text = config.BREWERY_NAME
self.fields['custom_theme'].initial = config.CUSTOM_THEME
self.fields['date_time_format_display'].initial = config.DATE_TIME_FORMAT_DISPLAY
self.fields['require_login_for_dashboard'].initial = config.REQUIRE_LOGIN_FOR_DASHBOARD
self.fields['temperature_format'].initial = config.TEMPERATURE_FORMAT
Expand Down
1 change: 1 addition & 0 deletions app/setup_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ def setup_config(request):
if form.is_valid():
f = form.cleaned_data
config.BREWERY_NAME = f['brewery_name']
config.CUSTOM_THEME = f['custom_theme']
config.DATE_TIME_FORMAT_DISPLAY = f['date_time_format_display']
config.REQUIRE_LOGIN_FOR_DASHBOARD = f['require_login_for_dashboard']
config.TEMPERATURE_FORMAT = f['temperature_format']
Expand Down
176 changes: 176 additions & 0 deletions app/static/css/nord.fermentrack.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/* Nord Theme for Fermentrack */
/* Default Colors from https://github.com/arcticicestudio/nord */
:root {
--bgcolor: #2e3440; /* Background color of the page */
--textcolor: #e5e9f0; /* Main text color */
--linkcolor: #88c0d0; /* Link color */
--linkhover: #8fbcbb; /* Link color when hovering */
--navbgcolor: #3b4252; /* Navigation bar background color */
--bgsensorbox: #d08770; /* Sensor box background color */
--bgsgbox: #b48ead; /* Specific gravity box background color */
--bgabvbox: #4c566a; /* ABV box background color */
--bgtempbox: #5e81ac; /* Temperature box background color */
--bgtempconbox: #81a1c1; /* Temperature control box background color */
--graphlabels: #eceff4; /* Graph axis text color */
--bgdatapt: #bf616a; /* Add data point button background color */
--bgconbut: #88c0d0; /* Control logging button background color */
--bgprior: #a3be8c; /* Load prior log button background color */
--bgalert: #a3be8c; /* Pop-up alert background color */
--borderalert: #a3be8c; /* Pop-up alert border color */
--textalert: #e5e9f0; /* Pop-up alert text color */
--bghovermenu: #88c0d0; /* Menu hover color */
--legendrow: #4c566a; /* Legend row background color */
--bordercolor: #d8dee9; /* Border color for legend row */
--caret: #4c566a; /* Menu caret color */
}


/* Overall colors */
body{
color: var(--textcolor);
background-color: var(--bgcolor);
}

/* Link colors */
a {
color: var(--linkcolor);
}

a:hover, a:focus {
color: var(--linkhover);
}

/* Background color of the navigation bar */
.navbar-inverse {
background-color: var(--navbgcolor);
}

/* Drop down menu from navigation bar */
.navbar-inverse .navbar-nav>.open>.dropdown-menu {
background-color: var(--navbgcolor);
}

.navbar-inverse .navbar-brand {
color: var(--textcolor);
}

.navbar-inverse .navbar-nav>li>a {
color: var(--textcolor);
}

.navbar-inverse .navbar-nav>li>a:hover, .navbar-inverse .navbar-nav>li>a:focus {
color: var(--linkhover);
}

.navbar-inverse .navbar-nav>.open>a, .navbar-inverse .navbar-nav>.open>a:hover, .navbar-inverse .navbar-nav>.open>a:focus {
color: var(--textcolor);
background-color: var(--linkhover);
}

.navbar-inverse .navbar-nav>.dropdown>a:hover .caret, .navbar-inverse .navbar-nav>.dropdown>a:focus .caret {
border-top-color: var(--linkhover);
border-bottom-color: var(--linkhover);
}

.navbar-inverse .navbar-brand:hover, .navbar-inverse .navbar-brand:focus {
color: var(--linkhover);
background-color: transparent;
}

.navbar-inverse .navbar-nav>.dropdown>a .caret {
border-top-color: var(--caret);
border-bottom-color: var(--caret);
}

.navbar-inverse .navbar-nav>.open>.dropdown-menu>li>a:hover,
.navbar-inverse .navbar-nav>.open>.dropdown-menu>li>a:focus {
color: var(--textcolor);
background-color: var(--linkhover)
}

/* Gravity Sensor Box */
.bg-carrot {
background: var(--bgsensorbox)!important;
}

/* SG Box */
.bg-amethyst {
background: var(--bgsgbox)!important;
}

/* ABV Box */
.bg-wet-asphalt {
background: var(--bgabvbox)!important;
}

/* Temperature Box */
.bg-petermann {
background: var(--bgtempbox)!important;
}

/* Temp Controller Box */
.bg-concrete {
background: var(--bgtempconbox)!important;
}

/* Graph colors */
.dygraph-axis-label {
color: var(--graphlabels);
}

/* Bottom Buttons */
.btn-danger {
background-color: var(--bgdatapt);
}

.btn-info {
background-color: var(--bgconbut);
}

.btn-success {
background-color: var(--bgprior);
}

/* Buttons (e.g. login, etc.) */
.btn-primary:hover, .btn-primary.hover, .btn-primary:focus, .btn-primary:active, .btn-primary.active, .open>.dropdown-toggle.btn-primary {
color: var(--textcolor);
background-color: var(--bghovermenu);
border-color: var(--bghovermenu);
}

.btn-primary {
color: var(--textcolor);
background-color: var(--bgprior);
}

/* Alert pop-up */
.alert-success {
color: var(--textcolor);
background-color: var(--bgalert);
border-color: var(--bgalert);
}

.panel-red > .panel-heading {
border-color: var(--bgdatapt);
color: var(--textcolor);
background-color: var(--bgdatapt);
}

.panel-red {
border-color: var(--bgdatapt);
background-color: var(--legendrow);
}

.chart-legend-row {
background-color: var(--legendrow);
border-top: 1px solid #ddd;
}

.form-control, .select2-search input[type=text] {
border: 2px solid var(--bordercolor);
}

.panel-footer {
background-color: var(--legendrow);
border-top: 1px solid #ddd;
}
1 change: 1 addition & 0 deletions app/templates/setup/constance_app_configuration.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ <h3 class="form-header">App Configuration</h3>
{% form_generic form.enable_gravity_support %}
{% form_generic form.gravity_display_format %}
{% form_generic form.update_preference %}
{% form_generic form.custom_theme %}
{% form_generic form.enable_sentry_support %}
<input type="submit" value="Save Configuration" class="btn btn-primary"/>
</div>
Expand Down
5 changes: 4 additions & 1 deletion app/templates/sitewide/flat_ui_template.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
{# TODO - Move dygraph out to only the pages that use it #}
<script type="text/javascript" src="{% static "vendor/dygraph/js/dygraph.min.js" %}"></script>
<link src="{% static "vendor/dygraph/css/dygraph.css" %}" rel="stylesheet">

{% if config.CUSTOM_THEME == 'nord' %}
<link href="{% static "css/nord.fermentrack.css" %}" rel="stylesheet">
{% endif %}

<!-- HTML5 shim, for IE6-8 support of HTML5 elements. -->
<!--[if lt IE 9]>
<script src="{% static "vendor/other/js/html5shiv.js" %}"></script>
Expand Down
1 change: 1 addition & 0 deletions app/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,7 @@ def site_settings(request):
if form.is_valid():
f = form.cleaned_data
config.BREWERY_NAME = f['brewery_name']
config.CUSTOM_THEME = f['custom_theme']
config.DATE_TIME_FORMAT_DISPLAY = f['date_time_format_display']
config.REQUIRE_LOGIN_FOR_DASHBOARD = f['require_login_for_dashboard']
config.TEMPERATURE_FORMAT = f['temperature_format']
Expand Down
23 changes: 11 additions & 12 deletions brewpi-script/scriptlibs/BrewPiUtil.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,28 +188,27 @@ def setupSerial(dbConfig: models.BrewPiDevice, baud_rate:int=57600, time_out=0.1
error = ""

if dbConfig.wifi_port is None:
logMessage("Invalid WiFi configuration - Port '{}' cannot be converted to integer".format(config['wifiPort']))
logMessage("Invalid WiFi configuration - Port '{}' cannot be converted to integer".format(dbConfig.wifi_port))
logMessage("Exiting.")
exit(1)
port = dbConfig.wifi_port

if dbConfig.wifi_host_ip is None or len(dbConfig.wifi_host_ip) < 7:
if dbConfig.wifi_host is None or len(dbConfig.wifi_host) <= 4:
logMessage("Invalid WiFi configuration - No wifi_host or wifi_host_ip set")
logMessage("Exiting.")
exit(1)
connect_to = dbConfig.wifi_host
else:
# the wifi_host_ip is set - use that as the host to connect to
connect_to = dbConfig.wifi_host_ip
ip_address = dbConfig.get_cached_ip() # Resolve wifi_host to an IP address or get the cached IP

if ip_address is None:
logMessage("Invalid WiFi configuration - No wifi_host or wifi_host_ip set")
logMessage("Exiting.")
exit(1)

if dbConfig.wifi_host is None or len(dbConfig.wifi_host) <= 4:
if not dbConfig.wifi_host:
# If we don't have a hostname at all, set it to None
hostname = None
else:
hostname = dbConfig.wifi_host

ser = tcpSerial.TCPSerial(host=connect_to, port=port, hostname=hostname)
# The way TCPSerial is implemented, hostname is just a memo field. We always connect to the host (which
# in this case is a resolved IP address)
ser = tcpSerial.TCPSerial(host=ip_address, port=port, hostname=hostname)

if ser:
break
Expand Down
Loading

0 comments on commit 5719c02

Please sign in to comment.