Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add remote logging (external push) support (#277) * Remove the constant polling for LCD refreshes (#278) * Add "NewCCModelForm" for "modern" controllers (#282) * Support debugging connection for ports other than 23 (Fixes #279) * Add support for temperature calibration offsets (Closes #281) * Update documentation * Catch ObjectNotFound errors generated by the iSpindle calibration API * Fix link to favicon (Fixes #313) * Remove error not available in Python 3.4 (Fixes #321) * Catch error when API called for nonexistant gravity sensor (Fixes #330) * Map "Log1Temp" to "RoomTemp" value
- Loading branch information
Showing
29 changed files
with
871 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ Changelog, Licensing, and Development | |
changelog | ||
components | ||
contribute | ||
push support | ||
license | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
.. include:: ../global.rst | ||
|
||
"Push" Support | ||
============================== | ||
|
||
Although Fermentrack is focused on the "fermentation" phase of your brewing operation, Fermentrack is designed to | ||
integrate with your brewing operation as a whole. To support the use of data collected by Fermentrack in other | ||
applications, Fermentrack allows for data to be "pushed" on a periodic basis via HTTP requests (and will - in the | ||
future - support pushing via TCP (sockets)). | ||
|
||
|
||
Supported "Push" Targets | ||
------------------------------ | ||
|
||
Fermentrack currently supports one push target, though more are likely to be added in the near future: | ||
|
||
- "Generic" Push Target - Fermentrack's "native" push format - Pushes both specific gravity & temperature data | ||
|
||
|
||
|
||
|
||
Generic Push Target Format | ||
****************************** | ||
|
||
The "generic" push target format is the one recommended for use by developers who are adding native Fermentrack | ||
support to their apps. This format contains temperature/gravity data collected by Fermentrack for each available | ||
specific gravity sensor and BrewPi controller. | ||
|
||
This format is supported by the `Fermentrack Push Target app <http://github.com/thorrak/fermentrack_push_target>`__ for | ||
testing/development purposes. | ||
|
||
:: | ||
|
||
{'api_key': 'abcde', | ||
'brewpi_devices': [{'control_mode': 'f', | ||
'internal_id': 1, | ||
'name': 'Legacy 2', | ||
'temp_format': 'F'}, | ||
{'beer_temp': 31.97, | ||
'control_mode': 'f', | ||
'fridge_temp': 36.26, | ||
'internal_id': 2, | ||
'name': 'Kegerator', | ||
'temp_format': 'F'}], | ||
'gravity_sensors': [{'gravity': 1.247, | ||
'internal_id': 1, | ||
'name': 'Pinky', | ||
'sensor_type': 'tilt', | ||
'temp': 78.0, | ||
'temp_format': 'F'}, | ||
{'internal_id': 3, | ||
'name': 'Spindly', | ||
'sensor_type': 'ispindel', | ||
'temp': 86.225, | ||
'temp_format': 'F'}], | ||
'version': '1.0'} | ||
|
||
|
||
Implementation Notes | ||
------------------------------ | ||
|
||
Push support within Fermentrack is implemented through the use of a "helper script" which currently is launched once | ||
every minute. The helper script polls the defined push targets to determine which (if any) are overdue for data to be | ||
pushed, and - for those targets - then executes the push based on how those targets are configured. Fermentrack polls | ||
Redis for the latest available data point for specific gravity sensors, and polls BrewPi controllers for the latest data | ||
point directly. This data is then encoded based on the selected push format and sent downstream to the requested target. | ||
|
||
Push requests are handled asynchronously. Due to the way that the polling script is implemented, push "frequencies" may | ||
be up to one polling cycle (currently 1 minute) later than expected. For 1 minute push cycles, this means that the | ||
actual frequency could be as high as 2 minutes. | ||
|
||
|
||
Feedback | ||
------------------------------ | ||
|
||
Push support was designed to support future applications that do not yet exist, and as such, may not be perfect for | ||
*your* application. That said, feedback is always appreciated and welcome. Feel free to reach out (HBT forums, | ||
GitHub, Reddit...) if you have something in mind that you'd like to integrate Fermentrack into, and don't think the | ||
existing push options will quite work. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
from django.contrib import admin | ||
|
||
from external_push.models import GenericPushTarget | ||
|
||
|
||
@admin.register(GenericPushTarget) | ||
class GenericPushTargetAdmin(admin.ModelAdmin): | ||
list_display = ('name', 'status', 'target_host') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from __future__ import unicode_literals | ||
|
||
from django.apps import AppConfig | ||
|
||
|
||
class AppConfig(AppConfig): | ||
name = 'external_push' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from django import forms | ||
|
||
from external_push.models import GenericPushTarget | ||
from django.core import validators | ||
import fermentrack_django.settings as settings | ||
|
||
from django.forms import ModelForm | ||
|
||
|
||
class GenericPushTargetModelForm(ModelForm): | ||
class Meta: | ||
model = GenericPushTarget | ||
fields = ['name', 'push_frequency', 'api_key', 'brewpi_push_selection', 'brewpi_to_push', | ||
'gravity_push_selection', 'gravity_sensors_to_push', 'target_type', 'target_host', 'target_port'] | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# -*- coding: utf-8 -*- | ||
# Generated by Django 1.11.13 on 2018-12-02 21:43 | ||
from __future__ import unicode_literals | ||
|
||
import django.core.validators | ||
from django.db import migrations, models | ||
import django.utils.timezone | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [ | ||
('gravity', '0002_tilt_refactor'), | ||
('app', '0009_auto_20180709_0256'), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='GenericPushTarget', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('name', models.CharField(help_text='Unique name for this push target', max_length=48, unique=True)), | ||
('status', models.CharField(choices=[('active', 'Active'), ('disabled', 'Disabled')], default='active', help_text='Status of this push target', max_length=24)), | ||
('push_frequency', models.IntegerField(choices=[(59, '1 minute'), (119, '2 minutes'), (299, '5 minutes'), (599, '10 minutes'), (899, '15 minutes'), (1799, '30 minutes'), (3599, '1 hour')], default=900, help_text='How often to push data to the target')), | ||
('api_key', models.CharField(blank=True, default='', help_text='API key required by the push target (if any)', max_length=256)), | ||
('brewpi_push_selection', models.CharField(choices=[('all', 'All Active Sensors/Devices'), ('list', 'Specific Sensors/Devices'), ('none', 'Nothing of this type')], default='all', help_text='How the BrewPi devices to push are selected', max_length=12)), | ||
('gravity_push_selection', models.CharField(choices=[('all', 'All Active Sensors/Devices'), ('list', 'Specific Sensors/Devices'), ('none', 'Nothing of this type')], default='all', help_text='How the gravity sensors to push are selected', max_length=12)), | ||
('target_type', models.CharField(choices=[('http (post)', 'HTTP/HTTPS'), ('tcp', 'TCP (Telnet/Socket)')], default='http (post)', help_text='Protocol to use to connect to the push target', max_length=24)), | ||
('target_host', models.CharField(blank=True, default='http://127.0.0.1/', help_text='The URL to push to (for HTTP/HTTPS) or hostname/IP address (for TCP)', max_length=256)), | ||
('target_port', models.IntegerField(default=80, help_text='The port to use (not used for HTTP/HTTPS)', validators=[django.core.validators.MinValueValidator(10, 'Port must be 10 or higher'), django.core.validators.MaxValueValidator(65535, 'Port must be 65535 or lower')])), | ||
('data_format', models.CharField(choices=[('generic', 'All Data (Generic)'), ('brewersfriend', 'Brewers Friend')], default='generic', help_text='The data format to send to the push target', max_length=24)), | ||
('last_triggered', models.DateTimeField(default=django.utils.timezone.now, help_text='The last time we pushed data to this target')), | ||
('brewpi_to_push', models.ManyToManyField(help_text="BrewPi Devices to push (ignored if 'all' devices selected)", related_name='push_targets', to='app.BrewPiDevice')), | ||
('gravity_sensors_to_push', models.ManyToManyField(help_text="Gravity Sensors to push (ignored if 'all' sensors selected)", related_name='push_targets', to='gravity.GravitySensor')), | ||
], | ||
options={ | ||
'verbose_name': 'Generic Push Target', | ||
'verbose_name_plural': 'Generic Push Targets', | ||
}, | ||
), | ||
] |
Empty file.
Oops, something went wrong.