Skip to content

Commit

Permalink
Add Output: GP8XXX (8403) 2-Channel DAC (0-10 VDC) (#1354)
Browse files Browse the repository at this point in the history
  • Loading branch information
kizniche committed Apr 2, 2024
1 parent d66831a commit f7a1864
Show file tree
Hide file tree
Showing 39 changed files with 500 additions and 202 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,21 @@ This release changes the install directory from ~/Mycodo to /opt/Mycodo. This ne
- Add Output: GPIO On/Off using pinctrl (First Pi 5-compatible Output)
- Add Output: PWM MQTT Publish
- Add Output: GP8403 2-Channel DAC (0-10 VDC) ([#1354](https://github.com/kizniche/Mycodo/issues/1354))
- Add Output: GP8XXX (8403) 2-Channel DAC (0-10 VDC) ([#1354](https://github.com/kizniche/Mycodo/issues/1354))
- Add API Endpoint: /notes/create to create a Note ([#1357](https://github.com/kizniche/Mycodo/issues/1357))
- Add ability to switch displaying hostname with custom text
- Add Step Line Series Type to Graph (Synchronous) Widget
- Add controller_restart as client endpoint
- Add option for custom CSS
- Add options for changing title and brand text

### Miscellaneous

- Move install location from ~/Mycodo to /opt/Mycodo
- Change Dashboard grid width from 20 to 24
- Add endpoint option to RAM Input for when Mycodo is using a non-standard IP/port
- Add self.control to the Python 3 Code Action
- Update adafruit-circuitpython-ads1x15 to 2.2.25
- Update Gridstack to 10.0.1
- Update alembic to 1.13.1
- Update bcrypt to 1.4.2
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"""Add brand config options
Revision ID: d6b624da47f4
Revises: a338ed3dce74
Create Date: 2024-03-29 20:13:51.807396
"""
import sys
import os

sys.path.append(os.path.abspath(os.path.join(__file__, "../../../..")))

from alembic_db.alembic_post_utils import write_revision_post_alembic

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = 'd6b624da47f4'
down_revision = 'a338ed3dce74'
branch_labels = None
depends_on = None


def upgrade():
# write_revision_post_alembic(revision)

with op.batch_alter_table("misc") as batch_op:
batch_op.add_column(sa.Column('brand_display', sa.Text))
batch_op.add_column(sa.Column('title_display', sa.Text))
batch_op.add_column(sa.Column('brand_image', sa.BLOB))
batch_op.add_column(sa.Column('brand_image_height', sa.Integer))

op.execute(
'''
UPDATE misc
SET brand_display='hostname'
'''
)

op.execute(
'''
UPDATE misc
SET title_display='hostname'
'''
)

op.execute(
'''
UPDATE misc
SET brand_image_height=55
'''
)


def downgrade():
with op.batch_alter_table("misc") as batch_op:
batch_op.drop_column('brand_display')
batch_op.drop_column('title_display')
batch_op.drop_column('brand_image')
batch_op.drop_column('brand_image_height')
2 changes: 1 addition & 1 deletion mycodo/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from config_translations import TRANSLATIONS as T

MYCODO_VERSION = '8.15.13'
ALEMBIC_VERSION = 'a338ed3dce74'
ALEMBIC_VERSION = 'd6b624da47f4'

# FORCE UPGRADE MASTER
# Set True to enable upgrading to the master branch of the Mycodo repository.
Expand Down
4 changes: 4 additions & 0 deletions mycodo/databases/models/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ class Misc(CRUDMixin, db.Model):
net_test_port = db.Column(db.Integer, default=53)
net_test_timeout = db.Column(db.Integer, default=3)
default_login_page = db.Column(db.String, default='password')
brand_display = db.Column(db.String, default='hostname')
title_display = db.Column(db.String, default='hostname')
hostname_override = db.Column(db.String, default='')
brand_image = db.Column(db.BLOB, default='')
brand_image_height = db.Column(db.Integer, default=55)
custom_css = db.Column(db.String, default='')

# Measurement database
Expand Down
2 changes: 1 addition & 1 deletion mycodo/inputs/ads1015_circuitpython.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def constraints_pass_measurement_repetitions(mod_input, value):
'dependencies_module': [
('pip-pypi', 'usb.core', 'pyusb==1.1.1'),
('pip-pypi', 'adafruit_extended_bus', 'Adafruit-extended-bus==1.0.2'),
('pip-pypi', 'adafruit_ads1x15', 'adafruit-circuitpython-ads1x15==2.2.12')
('pip-pypi', 'adafruit_ads1x15', 'adafruit-circuitpython-ads1x15==2.2.25')
],
'interfaces': ['I2C'],
'i2c_location': ['0x48', '0x49', '0x4A', '0x4B'],
Expand Down
2 changes: 1 addition & 1 deletion mycodo/inputs/ads1115_analog_ph_ec.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def execute_at_modification(
'dependencies_module': [
('pip-pypi', 'usb.core', 'pyusb==1.1.1'),
('pip-pypi', 'adafruit_extended_bus', 'Adafruit-extended-bus==1.0.2'),
('pip-pypi', 'adafruit_ads1x15', 'adafruit-circuitpython-ads1x15==2.2.12')
('pip-pypi', 'adafruit_ads1x15', 'adafruit-circuitpython-ads1x15==2.2.25')
],
'interfaces': ['I2C'],
'i2c_location': ['0x48', '0x49', '0x4A', '0x4B'],
Expand Down
2 changes: 1 addition & 1 deletion mycodo/inputs/ads1115_circuitpython.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def constraints_pass_measurement_repetitions(mod_input, value):
'dependencies_module': [
('pip-pypi', 'usb.core', 'pyusb==1.1.1'),
('pip-pypi', 'adafruit_extended_bus', 'Adafruit-extended-bus==1.0.2'),
('pip-pypi', 'adafruit_ads1x15', 'adafruit-circuitpython-ads1x15==2.2.12')
('pip-pypi', 'adafruit_ads1x15', 'adafruit-circuitpython-ads1x15==2.2.25')
],
'interfaces': ['I2C'],
'i2c_location': ['0x48', '0x49', '0x4A', '0x4B'],
Expand Down
2 changes: 1 addition & 1 deletion mycodo/mycodo_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ def module_function(self, controller_type, unique_id, button_id, args_dict, thre
return self.proxy(timeout=timeout).module_function(
controller_type, unique_id, button_id, args_dict, thread=thread, return_from_function=return_from_function)
except Exception:
return 0, traceback.format_exc()
return 1, traceback.format_exc()

def widget_add_refresh(self, unique_id):
return self.proxy().widget_add_refresh(unique_id)
Expand Down
2 changes: 1 addition & 1 deletion mycodo/mycodo_daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ def module_function(self, controller_type, unique_id, button_id, args_dict, thre
message = "Cannot execute custom action. Is the controller activated? " \
"If it is and this error is still occurring, check the Daemon Log."
self.logger.exception(message)
return 1, message
return 0, message


def input_force_measurements(self, input_id):
Expand Down
6 changes: 5 additions & 1 deletion mycodo/mycodo_flask/forms/forms_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,11 @@ class SettingsGeneral(FlaskForm):
language = StringField(lazy_gettext('Language'))
rpyc_timeout = StringField(lazy_gettext('Pyro Timeout'))
custom_css = StringField(lazy_gettext('Custom CSS'), widget=TextArea())
hostname_override = StringField(lazy_gettext('Hostname Override'))
brand_display = StringField(lazy_gettext('Brand Display'))
title_display = StringField(lazy_gettext('Title Display'))
hostname_override = StringField(lazy_gettext('Brand Text'))
brand_image = FileField(lazy_gettext('Brand Image'))
brand_image_height = IntegerField(lazy_gettext('Brand Image Height'))
daemon_debug_mode = BooleanField(lazy_gettext('Enable Daemon Debug Logging'))
force_https = BooleanField(lazy_gettext('Force HTTPS'))
hide_success = BooleanField(lazy_gettext('Hide success messages'))
Expand Down
56 changes: 33 additions & 23 deletions mycodo/mycodo_flask/routes_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import os

import flask_login
from flask import flash, jsonify, redirect, render_template, request, url_for
from io import BytesIO
from flask import flash, jsonify, send_file, redirect, render_template, request, url_for
from flask.blueprints import Blueprint

from mycodo.config import (PATH_ACTIONS_CUSTOM, PATH_FUNCTIONS_CUSTOM,
Expand Down Expand Up @@ -63,43 +64,52 @@ def settings_alerts():
form_email_alert=form_email_alert)


@blueprint.route('/settings/general_submit', methods=['POST'])
@blueprint.route('/logo.jpg', methods=['GET'])
@flask_login.login_required
def settings_general_submit():
"""Submit form for General Settings page"""
def brand_logo():
"""Return logo from database"""
misc = Misc.query.first()
if misc.brand_image:
return send_file(
BytesIO(misc.brand_image),
mimetype='image/jpg'
)


@blueprint.route('/settings/general', methods=('GET', 'POST'))
@flask_login.login_required
def settings_general():
"""Display general settings."""
messages = {
"success": [],
"info": [],
"warning": [],
"error": []
}

form_settings_general = forms_settings.SettingsGeneral()

if not utils_general.user_has_permission('edit_settings'):
messages["error"].append("Your permissions do not allow this action")

if not messages["error"]:
messages = utils_settings.settings_general_mod(form_settings_general)

return jsonify(data={
'messages': messages,
})


@blueprint.route('/settings/general', methods=('GET', 'POST'))
@flask_login.login_required
def settings_general():
"""Display general settings."""
if not utils_general.user_has_permission('view_settings'):
return redirect(url_for('routes_general.home'))

misc = Misc.query.first()
form_settings_general = forms_settings.SettingsGeneral()

if request.method == 'POST':
if not utils_general.user_has_permission('edit_settings'):
messages["error"].append("Your permissions do not allow this action")

if not messages["error"]:
messages = utils_settings.settings_general_mod(form_settings_general)

for each_error in messages["error"]:
flash(each_error, "error")
for each_warn in messages["warning"]:
flash(each_warn, "warning")
for each_info in messages["info"]:
flash(each_info, "info")
for each_success in messages["success"]:
flash(each_success, "success")

return render_template('settings/general.html',
form_settings_general=form_settings_general,
misc=misc,
report_path=os.path.normpath(USAGE_REPORTS_PATH))


Expand Down
22 changes: 4 additions & 18 deletions mycodo/mycodo_flask/routes_static.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,6 @@ def inject_variables():
"{err}".format(err=e))
daemon_status = '0'

if misc.hostname_override:
host = misc.hostname_override
else:
host = socket.gethostname()

languages_sorted = sorted(LANGUAGES.items(), key=operator.itemgetter(1))

return dict(current_user=flask_login.current_user,
Expand All @@ -80,11 +75,12 @@ def inject_variables():
hide_alert_success=misc.hide_alert_success,
hide_alert_warning=misc.hide_alert_warning,
hide_tooltips=misc.hide_tooltips,
host=host,
host=socket.gethostname(),
languages=languages_sorted,
mycodo_version=MYCODO_VERSION,
permission_view_settings=user_has_permission('view_settings', silent=True),
dict_translation=TRANSLATIONS,
settings=misc,
template_exists=template_exists,
themes=THEMES,
upgrade_available=misc.mycodo_upgrade_available)
Expand Down Expand Up @@ -135,22 +131,12 @@ def page_error(error):
except:
model_output = None

try:
firmware = subprocess.Popen(
"/opt/vc/bin/vcgencmd version", stdout=subprocess.PIPE, shell=True)
(firmware_output, _) = firmware.communicate()
firmware.wait()
if firmware_output:
firmware_output = firmware_output.decode("latin1").replace("\n", "<br/>")
except:
firmware_output = None

dict_return = {
"trace": trace,
"version_mycodo": MYCODO_VERSION,
"version_alembic": ALEMBIC_VERSION,
"lsb_release": lsb_release_output,
"model": model_output,
"firmware": firmware_output
"model": model_output
}

return render_template('500.html', dict_return=dict_return), 500
2 changes: 1 addition & 1 deletion mycodo/mycodo_flask/static/css/gridstack.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion mycodo/mycodo_flask/static/js/gridstack-all.js

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion mycodo/mycodo_flask/templates/500.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ <h2>{{_('Error 500: Internal Server Error')}}</h2>
<br/>Model: {{dict_return["model"]}}
</p>
<p>Release:<br/>{{dict_return["lsb_release"]|safe}}</p>
<p>Firmware:<br/>{{dict_return["firmware"]|safe}}</p>

<p>Error (Full Traceback):</p>
<pre>{{dict_return["trace"]}}</pre>
Expand Down
Loading

0 comments on commit f7a1864

Please sign in to comment.