Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
nebhead committed Sep 13, 2024
2 parents 3b47d71 + 1388eb1 commit 58d2d92
Show file tree
Hide file tree
Showing 63 changed files with 7,575 additions and 1,987 deletions.
13 changes: 12 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,15 @@ recipes/recipe/

backups/

bin/
bin/
settings-v1.8.0.json

include/

lib/

share/

lib64

pyvenv.cfg
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,11 @@ I recommend at least taking a peek at the PiFire overview video below. It cover

[Link to our channel on YouTube](https://www.youtube.com/channel/UCYYs50U5QvHHhogx_rqs0Yg)

Here is a the latest version 2.0 of the hardware w/TFT screen and hardware buttons in a custom 3D printed enclosure. We've come a long way since v1.0.
Pictured below is version 2.0 of the hardware w/TFT screen and hardware buttons in a custom 3D printed enclosure.

![Hardware v2](docs/photos/HW-V2-Display.jpg)

And if you're interested in seeing more builds from other users, we have a discussions thread [here](https://github.com/nebhead/PiFire/discussions/28) where others have posted pictures of their unique builds.
And if you're interested in seeing more builds from other users, we have a discussions thread [here](https://github.com/nebhead/PiFire/discussions/28) or on [Discord](https://discord.gg/F9mbCrbrZS) (see below) where others have posted pictures of their unique builds.

## Full Documentation / Hardware and Software Installation

Expand All @@ -109,12 +109,12 @@ I've added a discord server [here](https://discord.gg/F9mbCrbrZS) which can be a
* 10/2022 - Release v1.3.5 - Bug fixes, feature refinements and brand new features galore in this latest release. Added a new ADS1115 module (using Adafruits Circuit Python), due to some reports of issues with the existing ADS1115 module. These can be optionally selected in the configuration wizard. PWM Fan Support and a boatload of code cleanup was introduced, thanks to contributor @weberbox. Support for saving cook files was introduced in this version, so that you can go back to older cooks, edit some of the information and add images and comments. Added a Prime Mode to allow you to prime the fire pot with pellets prior to a cook, and even prime & startup. Added estimated pellet usage to the pellet manager, which will attempt to track just how many pellets you have used since your last load of pellets. Added Apprise notification capability thanks to contributor @calonmerc. 320x200 displays have been update and added timers to specific modes. And even more!
* 6/2023 - Release v1.5.0 - Arguably one of the biggest overhauls to PiFire since it's inception. The Probe system has been completely refactored to allow for multiple probe sensing devices (i.e. ADS1115, MAX31865, or even Virtual Probes to augment your inputs). This extension of the probe system, allows for any number of probe inputs to be tracked in PiFire, allowing from notifications and tracking of history for each probe. The sky is the limit! With this change the the probe architecture, a number of other things needed to be modified/updated, including the notification system, the history/charting, the dashboards, cookfiles and recipe modes. Note that if you are updating to this version, your settings will be upgraded in the process and you will not be able to roll back to a previous version (unless you restore from a backup of your settings).
* 11/2023 - Release v1.6.0 - In this month comes another huge update with lots of new features and bug fixes. Many thanks to the users from discord that have been testing along the way (as well as submitting some bugs), what a great community we have! Many of these features have been deployed on our development branch for some time, so they should be relatively stable. Please do file issues on GitHub if you find any new bugs with the formal release. With that, enjoy and happy grilling/smoking!
* **5/2024** - Release v1.7.0 - Lot's of new updates in this release with the UI, new features (i.e. exit startup temp, etc.) and new device support. Some improvements to the tuning tools (including an auto-tuning tool). Under the covers improvements for stability and cleanup. As usual, submit issues to GitHub if you run into anything. Enjoy!

* 5/2024 - Release v1.7.0 - Lot's of new updates in this release with the UI, new features (i.e. exit startup temp, etc.) and new device support. Some improvements to the tuning tools (including an auto-tuning tool). Under the covers improvements for stability and cleanup. As usual, submit issues to GitHub if you run into anything. Enjoy!
* **9/2024 - Release v1.8.0** - Overhaul of the configuration wizard and underlying platform pin definitions to support board selection and configuration versus the platform selection that was previously provided. This allows much more flexibility when it comes to custom pinouts. This version now supports the PCB v4.x modular design allowing the ability to mix and match probe devices, relay/fan hardware, etc.

### Credits

Web Application created by Ben Parmeter, copyright 2020-2023. Check out my other projects on [github](https://github.com/nebhead). If you enjoy this software and feel the need to donate a cup of coffee, a frosty beer or a bottle of wine to the developer you can click [here](https://paypal.me/benparmeter).
Web Application created by Ben Parmeter, copyright 2020-2024. Check out my other projects on [github](https://github.com/nebhead). If you enjoy this software and feel the need to donate a cup of coffee, a frosty beer or a bottle of wine to the developer you can click [here](https://paypal.me/benparmeter).

Of course, none of this project would be available without the wonderful and amazing folks below. If I forgot anyone please don't hesitate to let me know.

Expand Down
125 changes: 82 additions & 43 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def dash_config():
dash_metadata = read_generic_json(f'./dashboard/{meta_data_filename}')

if request.method == 'GET':
render_string = "{% from '_macro_dash_default.html' import render_config_card %}{{ render_config_card(dash_metadata, dash_data) }}"
render_string = "{% from '_macro_generic_config.html' import render_dash_config_card %}{{ render_dash_config_card(dash_metadata, dash_data) }}"
return render_template_string(render_string, dash_metadata=dash_metadata, dash_data=dash_data)
elif request.method == 'POST':
dash_config_request = request.form
Expand Down Expand Up @@ -958,11 +958,21 @@ def tuner_page(action=None):

data = read_autotune()
if len(data) > 10:
# If more than 10 datapoints, then calculate high / low / medium
temp_list = []
tr_list = []
for datapoint in data:
temp_list.append(datapoint['ref_T'])
tr_list.append(datapoint['probe_Tr'])
'''
Check if the ref_T value is already in the list and overwrite if so.
This assumes that the last temperature is the most recent and is likely
the most accurate resistance value to take.
'''
if datapoint['ref_T'] in temp_list:
index = temp_list.index(datapoint['ref_T'])
tr_list[index] = datapoint['probe_Tr']
else:
temp_list.append(datapoint['ref_T'])
tr_list.append(datapoint['probe_Tr'])

# Determine High Temp / Tr
status_data['high_temp'] = max(temp_list)
Expand Down Expand Up @@ -1782,7 +1792,6 @@ def settings_page(action=None):
'name' : response['Name'],
'id' : UniqueID
}
print(f'Response: {response}')
if response.get('apply_profile', False):
probe_selected = response['apply_profile']
for index, probe in enumerate(settings['probe_settings']['probe_map']['probe_info']):
Expand Down Expand Up @@ -2366,7 +2375,6 @@ def admin_page(action=None):
if control['system']['cpu_throttled'] or control['system']['cpu_under_voltage']:
event = "CPU Throttled / Undervoltage event has occurred. Check your power supply for proper voltage."
errors.append(event)
print(event)

if 'check_cpu_temp' in supported_cmds:
process_command(action='sys', arglist=['check_cpu_temp'], origin='admin') # Request supported commands
Expand Down Expand Up @@ -2593,15 +2601,17 @@ def wizard(action=None):
section = r['section']
if section in ['grillplatform', 'display', 'distance']:
moduleData = wizardData['modules'][section][module]
moduleSettings = get_settings_dependencies_values(settings, moduleData)
moduleSettings = {}
moduleSettings['settings'] = get_settings_dependencies_values(settings, moduleData)
moduleSettings['config'] = {} if section != 'display' else settings['display']['config'][module]
render_string = "{% from '_macro_wizard_card.html' import render_wizard_card %}{{ render_wizard_card(moduleData, moduleSection, moduleSettings) }}"
return render_template_string(render_string, moduleData=moduleData, moduleSection=section, moduleSettings=moduleSettings)
else:
return '<strong color="red">No Data</strong>'

''' Create Temporary Probe Device/Port Structure for Setup, Use Existing unless First Time Setup '''
if settings['globals']['first_time_setup']:
wizardInstallInfo = wizardInstallInfoDefaults(wizardData)
wizardInstallInfo = wizardInstallInfoDefaults(wizardData, settings)
else:
wizardInstallInfo = wizardInstallInfoExisting(wizardData, settings)

Expand All @@ -2621,88 +2631,110 @@ def get_settings_dependencies_values(settings, moduleData):
for setting_name in setting_location:
setting_value = setting_value[setting_name]
moduleSettings[setting] = setting_value
print(moduleSettings)
return moduleSettings

def wizardInstallInfoDefaults(wizardData):
def wizardInstallInfoDefaults(wizardData, settings):

wizardInstallInfo = {
'modules' : {
'grillplatform' : {
'module_selected' : [],
'settings' : {}
'profile_selected' : [], # Reference the profile in wizardData > wizard_manifest.json
'settings' : {},
'config' : {}
},
'display' : {
'module_selected' : [],
'settings' : {}
'profile_selected' : [],
'settings' : {},
'config' : {}
},
'distance' : {
'module_selected' : [],
'settings' : {}
'profile_selected' : [],
'settings' : {},
'config' : {}
},
'probes' : {
'module_selected' : [],
'profile_selected' : [],
'settings' : {
'units' : 'F'
}
},
'config' : {}
}
},
'probe_map' : wizardData['boards']['PiFirev2x']['probe_map']
'probe_map' : {}
}
''' Populate Modules Info with Defaults from Wizard Data including Settings '''
for component in ['grillplatform', 'display', 'distance']:
for module in wizardData['modules'][component]:
if wizardData['modules'][component][module]['default']:
''' Populate Module Filename'''
wizardInstallInfo['modules'][component]['module_selected'].append(wizardData['modules'][component][module]['filename'])
wizardInstallInfo['modules'][component]['profile_selected'].append(module) #TODO: Change wizard.py to reference the module filename instead, or in grill_platform use platform>system_type
for setting in wizardData['modules'][component][module]['settings_dependencies']:
''' Populate all settings with default value '''
wizardInstallInfo['modules'][component]['settings'][setting] = list(wizardData['modules'][component][module]['settings_dependencies'][setting]['options'].keys())[0]
if module == 'display':
wizardInstallInfo['modules'][component]['config'] = settings['display']['config'][module]

''' Populate the default probe device / probe map from the default PCB Board '''
wizardInstallInfo['probe_map'] = wizardData['boards'][wizardInstallInfo['modules']['grillplatform']['profile_selected'][0]]['probe_map']

''' Populate Probes Module List with all configured probe devices '''
for device in wizardInstallInfo['probe_map']['probe_devices']:
wizardInstallInfo['modules']['probes']['module_selected'].append(device['module'])
wizardInstallInfo['modules']['probes']['profile_selected'].append(device['module'])

return wizardInstallInfo

def wizardInstallInfoExisting(wizardData, settings):
wizardInstallInfo = {
'modules' : {
'grillplatform' : {
'module_selected' : [settings['modules']['grillplat']],
'settings' : {}
'profile_selected' : [settings['platform']['current']],
'settings' : {},
'config' : {}
},
'display' : {
'module_selected' : [settings['modules']['display']],
'settings' : {}
'profile_selected' : [settings['modules']['display']],
'settings' : {},
'config' : {}
},
'distance' : {
'module_selected' : [settings['modules']['dist']],
'settings' : {}
'profile_selected' : [settings['modules']['dist']],
'settings' : {},
'config' : {}
},
'probes' : {
'module_selected' : [],
'profile_selected' : [],
'settings' : {
'units' : settings['globals']['units']
}
},
'config' : {}
}
},
'probe_map' : settings['probe_settings']['probe_map']
}
''' Populate Probes Module List with all configured probe devices '''
for device in wizardInstallInfo['probe_map']['probe_devices']:
wizardInstallInfo['modules']['probes']['module_selected'].append(device['module'])
wizardInstallInfo['modules']['probes']['profile_selected'].append(device['module'])

''' Populate Modules Info with current Settings '''
for module in ['grillplatform', 'display', 'distance']:
selected = wizardInstallInfo['modules'][module]['module_selected'][0]
selected = wizardInstallInfo['modules'][module]['profile_selected'][0]
''' Error condition if the item in settings doesn't match the wizard manifest '''
if selected not in wizardData['modules'][module].keys():
if module == 'grillplatform':
selected = 'custom'
settings['platform']['current'] = selected
else:
selected = 'none'
wizardInstallInfo['modules'][module]['profile_selected'] = selected

for setting in wizardData['modules'][module][selected]['settings_dependencies']:
settingsLocation = wizardData['modules'][module][selected]['settings_dependencies'][setting]['settings']
settingsValue = settings.copy()
for index in range(0, len(settingsLocation)):
settingsValue = settingsValue[settingsLocation[index]]
wizardInstallInfo['modules'][module]['settings'][setting] = str(settingsValue)

if module == 'display':
wizardInstallInfo['modules'][module]['config'] = settings['display']['config'][settings['modules']['display']]
return wizardInstallInfo

def prepare_wizard_data(form_data):
Expand All @@ -2712,27 +2744,31 @@ def prepare_wizard_data(form_data):

wizardInstallInfo['modules'] = {
'grillplatform' : {
'module_selected' : [form_data['grillplatformSelect']],
'settings' : {}
'profile_selected' : [form_data['grillplatformSelect']],
'settings' : {},
'config' : {}
},
'display' : {
'module_selected' : [form_data['displaySelect']],
'settings' : {}
'profile_selected' : [form_data['displaySelect']],
'settings' : {},
'config' : {}
},
'distance' : {
'module_selected' : [form_data['distanceSelect']],
'settings' : {}
'profile_selected' : [form_data['distanceSelect']],
'settings' : {},
'config' : {}
},
'probes' : {
'module_selected' : [],
'profile_selected' : [],
'settings' : {
'units' : form_data['probes_units']
}
},
'config' : {}
}
}

for device in wizardInstallInfo['probe_map']['probe_devices']:
wizardInstallInfo['modules']['probes']['module_selected'].append(device['module'])
wizardInstallInfo['modules']['probes']['profile_selected'].append(device['module'])

for module in ['grillplatform', 'display', 'distance']:
module_ = module + '_'
Expand All @@ -2742,6 +2778,9 @@ def prepare_wizard_data(form_data):
settingName = module_ + setting
if(settingName in form_data):
wizardInstallInfo['modules'][module]['settings'][setting] = form_data[settingName]
for config, value in form_data.items():
if config.startswith(module_ + 'config_'):
wizardInstallInfo['modules'][module]['config'][config.replace(module_ + 'config_', '')] = value

return(wizardInstallInfo)

Expand Down Expand Up @@ -3702,9 +3741,9 @@ def get_app_data(action=None, type=None):
'cpuinfo' : os.popen('cat /proc/cpuinfo').readlines(),
'ifconfig' : os.popen('ifconfig').readlines(),
'temp' : _check_cpu_temp(),
'outpins' : settings['outpins'],
'inpins' : settings['inpins'],
'dev_pins' : settings['dev_pins'],
'outpins' : settings['platform']['outputs'],
'inpins' : settings['platform']['inputs'],
'dev_pins' : settings['platform']['devices'],
'server_version' : settings['versions']['server'],
'server_build' : settings['versions']['build'] }

Expand Down
62 changes: 12 additions & 50 deletions auto-install/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,17 @@ echo "** Cloning PiFire from GitHub... **"
echo "** **"
echo "*************************************************************************"
cd /usr/local/bin
# Use a shallow clone to reduce download size
$SUDO git clone --depth 1 https://github.com/nebhead/pifire
# Replace the below command to fetch development branch
#$SUDO git clone --depth 1 --branch development https://github.com/nebhead/pifire

# Check if -dev option is used
if [ "$1" = "-dev" ]; then
echo "Cloning development branch..."
# Replace the below command to fetch development branch
$SUDO git clone --depth 1 --branch development https://github.com/nebhead/pifire
else
echo "Cloning main branch..."
# Use a shallow clone to reduce download size
$SUDO git clone --depth 1 https://github.com/nebhead/pifire
fi

# Setup Python VENV & Install Python dependencies
clear
Expand Down Expand Up @@ -113,59 +120,14 @@ source bin/activate

echo " - Installing module dependencies... "
# Install module dependencies
python -m pip install "flask==2.3.3"
python -m pip install flask-mobility
python -m pip install flask-qrcode
python -m pip install flask-socketio
if ! python -c "import sys; assert sys.version_info[:2] >= (3,11)" > /dev/null; then
echo "System is running a python version lower than 3.11, installing eventlet==0.30.2";
python -m pip install "eventlet==0.30.2"
else
echo "System is running a python version 3.11 or greater, installing latest eventlet"
python -m pip install eventlet
fi
python -m pip install gunicorn
python -m pip install gpiozero
python -m pip install redis
python -m pip install uuid
python -m pip install influxdb-client[ciso]
python -m pip install apprise
python -m pip install scikit-fuzzy
python -m pip install "scikit-learn==1.4.2"
python -m pip install ratelimitingfilter
python -m pip install "pillow>=9.2.0"
python -m pip install paho-mqtt
python -m pip install psutil

# Setup config.txt to enable busses
clear
echo "*************************************************************************"
echo "** **"
echo "** Configuring config.txt **"
echo "** **"
echo "*************************************************************************"

# Enable SPI - Needed for some displays
$SUDO raspi-config nonint do_spi 0

# Enable I2C - Needed for some displays, ADCs, distance sensors
$SUDO raspi-config nonint do_i2c 0

# Enable Hardware PWM - Needed for hardware PWM support
if test -f /boot/firmware/config.txt; then
echo "dtoverlay=pwm,gpiopin=13,func=4" | $SUDO tee -a /boot/firmware/config.txt > /dev/null
else
echo "dtoverlay=pwm,gpiopin=13,func=4" | $SUDO tee -a /boot/config.txt > /dev/null
fi

# Setup backlight / power permissions if a DSI screen is installed
clear
echo "*************************************************************************"
echo "** **"
echo "** Configuring Backlight UDEV Rules **"
echo "** **"
echo "*************************************************************************"
echo 'SUBSYSTEM=="backlight",RUN+="/bin/chmod 666 /sys/class/backlight/%k/brightness /sys/class/backlight/%k/bl_power"' | $SUDO tee -a /etc/udev/rules.d/backlight-permissions.rules > /dev/null
python -m pip install -r /usr/local/bin/pifire/auto-install/requirements.txt

### Setup nginx to proxy to gunicorn
clear
Expand Down
Loading

0 comments on commit 58d2d92

Please sign in to comment.