Skip to content

Commit

Permalink
Fix theming on selection inputs, add ability to use alternate setting…
Browse files Browse the repository at this point in the history
…s database url
  • Loading branch information
kizniche committed Oct 9, 2024
1 parent 3c15c72 commit 31277ec
Show file tree
Hide file tree
Showing 29 changed files with 126 additions and 97 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ site/
env/
.venv
/databases/flask_secret_key
/mycodo/config_override.py
*.db
*.pem
*.bak
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
## 8.16.1 (Unreleased)

This release introduces the ability to override MYCODO_DB_PATH, SQLALCHEMY_DATABASE_URI, and ALEMBIC_URL in mycodo/config.py to use an alternate settings database. This is accomplished by creating these variables in mycodo/config_override.py. This new config file will be checked on startup and will persist after upgrades.

### Bugfixes

- Fix restoring mycodo/user_scripts during upgrade
- Fix documentation generation
- Fix theming on selection inputs

### Features

- Add ability to use alternate mysql server using config_override.py
- Add Output: PWM Raspberry Pi GPIO (RPi.GPIO) (for Pi <= 4, since pigpiod is deprecated)

### Miscellaneous
Expand Down
34 changes: 27 additions & 7 deletions mycodo/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,20 @@
#
import binascii
import sys
import subprocess
from datetime import timedelta

import os
from flask_babel import lazy_gettext as lg

# Append proper path for other software reading this config file
sys.path.append(os.path.abspath(os.path.dirname(__file__)))

from config_translations import TRANSLATIONS as T
try:
import config_override
except:
pass

MYCODO_VERSION = '8.16.0'
ALEMBIC_VERSION = '5966b3569c89'
Expand All @@ -27,20 +33,32 @@
# Used to determine proper upgrade page to display
FINAL_RELEASES = ['5.7.3', '6.4.7', '7.10.0']

# ENABLE FLASK PROFILER
# Flask Profiler
# Accessed at https://127.0.0.1/mycodo-flask-profiler
ENABLE_FLASK_PROFILER = False

# Install path (the parent directory of this file)
INSTALL_DIRECTORY = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + '/..')

# Database
DATABASE_PATH = os.path.join(INSTALL_DIRECTORY, 'databases')
DATABASE_NAME = "mycodo.db"
SQL_DATABASE_MYCODO = os.path.join(DATABASE_PATH, DATABASE_NAME)
try:
MYCODO_DB_PATH = config_override.MYCODO_DB_PATH
except:
MYCODO_DB_PATH = f'sqlite:///{SQL_DATABASE_MYCODO}'

# Alembic
ALEMBIC_PATH = os.path.join(INSTALL_DIRECTORY, 'alembic_db')
DATABASE_PATH = os.path.join(INSTALL_DIRECTORY, 'databases')
ALEMBIC_UPGRADE_POST = os.path.join(ALEMBIC_PATH, 'alembic_post_upgrade_versions')
SQL_DATABASE_MYCODO = os.path.join(DATABASE_PATH, DATABASE_NAME)
MYCODO_DB_PATH = f'sqlite:///{SQL_DATABASE_MYCODO}'
try: # Ensure the correct alembic url is set
ALEMBIC_URL = config_override.ALEMBIC_URL
cmd = f'/opt/Mycodo/env/bin/crudini --set /opt/Mycodo/alembic_db/alembic.ini alembic sqlalchemy.url {ALEMBIC_URL}'
subprocess.Popen(cmd, shell=True)
except:
cmd = '/opt/Mycodo/env/bin/crudini --set /opt/Mycodo/alembic_db/alembic.ini alembic sqlalchemy.url sqlite:///../databases/mycodo.db'
subprocess.Popen(cmd, shell=True)

# Misc paths
PATH_1WIRE = '/sys/bus/w1/devices/'
Expand Down Expand Up @@ -532,9 +550,11 @@

class ProdConfig(object):
"""Production Configuration."""
SQL_DATABASE_MYCODO = os.path.join(DATABASE_PATH, DATABASE_NAME)
MYCODO_DB_PATH = f'sqlite:///{SQL_DATABASE_MYCODO}'
SQLALCHEMY_DATABASE_URI = f'sqlite:///{SQL_DATABASE_MYCODO}'
try:
SQLALCHEMY_DATABASE_URI = config_override.MYCODO_DB_PATH
except:
SQLALCHEMY_DATABASE_URI = MYCODO_DB_PATH

SQLALCHEMY_TRACK_MODIFICATIONS = False

FLASK_PROFILER = {
Expand Down
4 changes: 2 additions & 2 deletions mycodo/databases/models/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class Camera(CRUDMixin, db.Model):
__table_args__ = {'extend_existing': True}

id = db.Column(db.Integer, unique=True, primary_key=True)
unique_id = db.Column(db.String, nullable=False, unique=True, default=set_uuid)
unique_id = db.Column(db.String(36), nullable=False, unique=True, default=set_uuid)
name = db.Column(db.Text, unique=True, nullable=False)
library = db.Column(db.Text, nullable=False)
device = db.Column(db.Text, nullable=False, default='/dev/video0')
Expand All @@ -25,7 +25,7 @@ class Camera(CRUDMixin, db.Model):
saturation = db.Column(db.Float, default=0)
white_balance = db.Column(db.Float, default=0.0)
custom_options = db.Column(db.Text, default='')
output_id = db.Column(db.String, db.ForeignKey('output.unique_id'), default=None) # Turn output on during capture
output_id = db.Column(db.String(36), default=None) # Turn output on during capture
output_duration = db.Column(db.Float, default=3.0)
cmd_pre_camera = db.Column(db.Text, default='') # Command to execute before capture
cmd_post_camera = db.Column(db.Text, default='') # Command to execute after capture
Expand Down
6 changes: 3 additions & 3 deletions mycodo/databases/models/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class CustomController(CRUDMixin, db.Model):
__table_args__ = {'extend_existing': True}

id = db.Column(db.Integer, unique=True, primary_key=True)
unique_id = db.Column(db.String, nullable=False, unique=True, default=set_uuid)
unique_id = db.Column(db.String(36), nullable=False, unique=True, default=set_uuid)
name = db.Column(db.Text, default='Custom Function')
position_y = db.Column(db.Integer, default=0)
device = db.Column(db.Text, default='')
Expand Down Expand Up @@ -41,8 +41,8 @@ class FunctionChannel(CRUDMixin, db.Model):
__table_args__ = {'extend_existing': True}

id = db.Column(db.Integer, unique=True, primary_key=True)
unique_id = db.Column(db.String, nullable=False, unique=True, default=set_uuid)
function_id = db.Column(db.Text, default=None)
unique_id = db.Column(db.String(36), nullable=False, unique=True, default=set_uuid)
function_id = db.Column(db.String(36), default=None)
channel = db.Column(db.Integer, default=None)
name = db.Column(db.Text, default='')

Expand Down
8 changes: 4 additions & 4 deletions mycodo/databases/models/dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class Dashboard(CRUDMixin, db.Model):
__table_args__ = {'extend_existing': True}

id = db.Column(db.Integer, unique=True, primary_key=True)
unique_id = db.Column(db.String, nullable=False, unique=True, default=set_uuid)
unique_id = db.Column(db.String(36), nullable=False, unique=True, default=set_uuid)
name = db.Column(db.Text, nullable=False, unique=True)
locked = db.Column(db.Boolean, default=False)

Expand All @@ -19,9 +19,9 @@ class Widget(CRUDMixin, db.Model):
__table_args__ = {'extend_existing': True}

id = db.Column(db.Integer, unique=True, primary_key=True)
unique_id = db.Column(db.String, nullable=False, unique=True, default=set_uuid)
unique_id = db.Column(db.String(36), nullable=False, unique=True, default=set_uuid)
graph_type = db.Column(db.Text, default=None)
dashboard_id = db.Column(db.String, default=None)
dashboard_id = db.Column(db.String(36), default=None)
name = db.Column(db.Text, default='Widget')
log_level_debug = db.Column(db.Boolean, default=False)
font_em_name = db.Column(db.Float, default=1.0)
Expand Down Expand Up @@ -75,7 +75,7 @@ class Widget(CRUDMixin, db.Model):
enable_output_controls = db.Column(db.Boolean, default=True) # Show output controls on dashboard element
show_pid_info = db.Column(db.Boolean, default=True) # Display detailed information about the PID
show_set_setpoint = db.Column(db.Boolean, default=True) # Display set PID setpoint
camera_id = db.Column(db.Text, default='') # store camera ID to display
camera_id = db.Column(db.String(36), default='') # store camera ID to display
camera_image_type = db.Column(db.Text, default='') # save new image, overwrite old, display last timelapse
camera_max_age = db.Column(db.Integer, default=360) # max camera image age before "No new image" shown

Expand Down
26 changes: 13 additions & 13 deletions mycodo/databases/models/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Function(CRUDMixin, db.Model):
__table_args__ = {'extend_existing': True}

id = db.Column(db.Integer, unique=True, primary_key=True)
unique_id = db.Column(db.String, nullable=False, unique=True, default=set_uuid)
unique_id = db.Column(db.String(36), nullable=False, unique=True, default=set_uuid)
function_type = db.Column(db.Text, default='')
name = db.Column(db.Text, default='Function Name')
position_y = db.Column(db.Integer, default=0)
Expand All @@ -22,7 +22,7 @@ class Conditional(CRUDMixin, db.Model):
__table_args__ = {'extend_existing': True}

id = db.Column(db.Integer, unique=True, primary_key=True)
unique_id = db.Column(db.String, nullable=False, unique=True, default=set_uuid)
unique_id = db.Column(db.String(36), nullable=False, unique=True, default=set_uuid)
name = db.Column(db.Text, default='Conditional')
position_y = db.Column(db.Integer, default=0)

Expand All @@ -46,8 +46,8 @@ class ConditionalConditions(CRUDMixin, db.Model):
__table_args__ = {'extend_existing': True}

id = db.Column(db.Integer, unique=True, primary_key=True)
unique_id = db.Column(db.String, nullable=False, unique=True, default=set_uuid)
conditional_id = db.Column(db.String, db.ForeignKey('conditional.unique_id'), default=None)
unique_id = db.Column(db.String(36), nullable=False, unique=True, default=set_uuid)
conditional_id = db.Column(db.String(36), default=None)
condition_type = db.Column(db.Text, default=None)

# Sensor
Expand All @@ -58,10 +58,10 @@ class ConditionalConditions(CRUDMixin, db.Model):
gpio_pin = db.Column(db.Integer, default=0)

# Output State
output_id = db.Column(db.Text, default='')
output_id = db.Column(db.String(36), default='')

# Controller
controller_id = db.Column(db.Text, default='')
controller_id = db.Column(db.String(36), default='')

def __repr__(self):
return "<{cls}(id={s.id})>".format(s=self, cls=self.__class__.__name__)
Expand All @@ -72,17 +72,17 @@ class Trigger(CRUDMixin, db.Model):
__table_args__ = {'extend_existing': True}

id = db.Column(db.Integer, unique=True, primary_key=True)
unique_id = db.Column(db.String, nullable=False, unique=True, default=set_uuid)
unique_id = db.Column(db.String(36), nullable=False, unique=True, default=set_uuid)
trigger_type = db.Column(db.Text, default=None)
name = db.Column(db.Text, default='Trigger Name')
position_y = db.Column(db.Integer, default=0)
is_activated = db.Column(db.Boolean, default=False)
log_level_debug = db.Column(db.Boolean, default=False)

# Used to hold unique IDs
unique_id_1 = db.Column(db.String, default=None)
unique_id_2 = db.Column(db.String, default=None)
unique_id_3 = db.Column(db.String, default=None)
unique_id_1 = db.Column(db.String(36), default=None)
unique_id_2 = db.Column(db.String(36), default=None)
unique_id_3 = db.Column(db.String(36), default=None)

# Output
output_state = db.Column(db.Text, default='') # What action to watch output for
Expand Down Expand Up @@ -130,16 +130,16 @@ class Actions(CRUDMixin, db.Model):
__table_args__ = {'extend_existing': True}

id = db.Column(db.Integer, unique=True, primary_key=True)
unique_id = db.Column(db.String, nullable=False, unique=True, default=set_uuid)
function_id = db.Column(db.String, default=None)
unique_id = db.Column(db.String(36), nullable=False, unique=True, default=set_uuid)
function_id = db.Column(db.String(36), default=None)
function_type = db.Column(db.Text, default='')
action_type = db.Column(db.Text, default='') # what action, such as 'email', 'execute command', 'flash LCD'

custom_options = db.Column(db.Text, default='{}')

# Actions
pause_duration = db.Column(db.Float, default=5.0)
do_unique_id = db.Column(db.Text, default='')
do_unique_id = db.Column(db.String(36), default='')
do_action_string = db.Column(db.Text, default='') # string, such as the email address or command
do_output_state = db.Column(db.Text, default='') # 'on' or 'off'
do_output_amount = db.Column(db.Float, default=0.0)
Expand Down
10 changes: 5 additions & 5 deletions mycodo/databases/models/input.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Input(CRUDMixin, db.Model):
__table_args__ = {'extend_existing': True}

id = db.Column(db.Integer, unique=True, primary_key=True)
unique_id = db.Column(db.String, nullable=False, unique=True, default=set_uuid)
unique_id = db.Column(db.String(36), nullable=False, unique=True, default=set_uuid)
device = db.Column(db.Text, default='') # Device name, such as DHT11, DHT22, DS18B20
is_activated = db.Column(db.Boolean, default=False)

Expand All @@ -22,7 +22,7 @@ class Input(CRUDMixin, db.Model):
interface = db.Column(db.Text, default=None) # Communication interface (I2C, UART, etc.)
period = db.Column(db.Float, default=15.0) # Duration between readings
start_offset = db.Column(db.Float, default=0.0)
power_output_id = db.Column(db.String, default=None)
power_output_id = db.Column(db.String(36), default=None)
resolution = db.Column(db.Integer, default=0)
resolution_2 = db.Column(db.Integer, default=0)
sensitivity = db.Column(db.Integer, default=0)
Expand Down Expand Up @@ -57,7 +57,7 @@ class Input(CRUDMixin, db.Model):
switch_reset_period = db.Column(db.Integer, default=10)

# Pre-measurement output options
pre_output_id = db.Column(db.String, db.ForeignKey('output.unique_id'), default=None) # Output to turn on before sensor read
pre_output_id = db.Column(db.String(36), default=None) # Output to turn on before sensor read
pre_output_duration = db.Column(db.Float, default=10.0) # Duration to turn output on before sensor read
pre_output_during_measure = db.Column(db.Boolean, default=True)

Expand Down Expand Up @@ -108,8 +108,8 @@ class InputChannel(CRUDMixin, db.Model):
__table_args__ = {'extend_existing': True}

id = db.Column(db.Integer, unique=True, primary_key=True)
unique_id = db.Column(db.String, nullable=False, unique=True, default=set_uuid)
input_id = db.Column(db.Text, default=None)
unique_id = db.Column(db.String(36), nullable=False, unique=True, default=set_uuid)
input_id = db.Column(db.String(36), default=None)
channel = db.Column(db.Integer, default=None)
name = db.Column(db.Text, default='')

Expand Down
14 changes: 6 additions & 8 deletions mycodo/databases/models/measurement.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Measurement(CRUDMixin, db.Model):
__table_args__ = {'extend_existing': True}

id = db.Column(db.Integer, unique=True, primary_key=True)
unique_id = db.Column(db.String, nullable=False, unique=True, default=set_uuid)
unique_id = db.Column(db.String(36), nullable=False, unique=True, default=set_uuid)
name_safe = db.Column(db.Text)
name = db.Column(db.Text)
units = db.Column(db.Text)
Expand All @@ -32,7 +32,7 @@ class Unit(CRUDMixin, db.Model):
__table_args__ = {'extend_existing': True}

id = db.Column(db.Integer, unique=True, primary_key=True)
unique_id = db.Column(db.String, nullable=False, unique=True, default=set_uuid)
unique_id = db.Column(db.String(36), nullable=False, unique=True, default=set_uuid)
name_safe = db.Column(db.Text)
name = db.Column(db.Text)
unit = db.Column(db.Text)
Expand All @@ -51,7 +51,7 @@ class Conversion(CRUDMixin, db.Model):
__table_args__ = {'extend_existing': True}

id = db.Column(db.Integer, unique=True, primary_key=True)
unique_id = db.Column(db.String, nullable=False, unique=True, default=set_uuid)
unique_id = db.Column(db.String(36), nullable=False, unique=True, default=set_uuid)
convert_unit_from = db.Column(db.Text)
convert_unit_to = db.Column(db.Text)
equation = db.Column(db.Text)
Expand All @@ -71,11 +71,11 @@ class DeviceMeasurements(CRUDMixin, db.Model):
__table_args__ = {'extend_existing': True}

id = db.Column(db.Integer, unique=True, primary_key=True)
unique_id = db.Column(db.String, nullable=False, unique=True, default=set_uuid)
unique_id = db.Column(db.String(36), nullable=False, unique=True, default=set_uuid)

name = db.Column(db.Text, default='')
device_type = db.Column(db.Text, default=None)
device_id = db.Column(db.Text, default=None)
device_id = db.Column(db.String(36), default=None)

# Default measurement/unit
is_enabled = db.Column(db.Boolean, default=True)
Expand All @@ -95,9 +95,7 @@ class DeviceMeasurements(CRUDMixin, db.Model):
scale_to_min = db.Column(db.Float, default=0)
scale_to_max = db.Column(db.Float, default=20)

conversion_id = db.Column(db.Text, db.ForeignKey('conversion.unique_id'), default='')

conversion = relationship("Conversion", foreign_keys="DeviceMeasurements.conversion_id")
conversion_id = db.Column(db.String(36), default='')


class DeviceMeasurementsSchema(ma.SQLAlchemyAutoSchema):
Expand Down
10 changes: 5 additions & 5 deletions mycodo/databases/models/method.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class Method(CRUDMixin, db.Model):
__table_args__ = {'extend_existing': True}

id = db.Column(db.Integer, unique=True, primary_key=True)
unique_id = db.Column(db.String, nullable=False, unique=True, default=set_uuid)
unique_id = db.Column(db.String(36), nullable=False, unique=True, default=set_uuid)
name = db.Column(db.Text, default='Method')
method_type = db.Column(db.Text, default='')
method_order = db.Column(db.Text, default='')
Expand All @@ -23,13 +23,13 @@ class MethodData(CRUDMixin, db.Model):
__table_args__ = {'extend_existing': True}

id = db.Column(db.Integer, unique=True, primary_key=True)
unique_id = db.Column(db.String, nullable=False, unique=True, default=set_uuid)
method_id = db.Column(db.String, db.ForeignKey('method.unique_id'), default=None)
unique_id = db.Column(db.String(36), nullable=False, unique=True, default=set_uuid)
method_id = db.Column(db.String(36), default=None)
time_start = db.Column(db.Text, default=None)
time_end = db.Column(db.Text, default=None)
duration_sec = db.Column(db.Float, default=None)
duration_end = db.Column(db.Float, default=None)
output_id = db.Column(db.String, db.ForeignKey('output.unique_id'), default=None)
output_id = db.Column(db.String(36), default=None)
output_state = db.Column(db.Text, default=None)
output_duration = db.Column(db.Float, default=None)
setpoint_start = db.Column(db.Float, default=None)
Expand All @@ -46,7 +46,7 @@ class MethodData(CRUDMixin, db.Model):
y2 = db.Column(db.Float, default=None)
x3 = db.Column(db.Float, default=None)
y3 = db.Column(db.Float, default=None)
linked_method_id = db.Column(db.String, db.ForeignKey('method.unique_id'), default=None)
linked_method_id = db.Column(db.String(36), default=None)

def __repr__(self):
return "<{cls}(id={s.id})>".format(s=self, cls=self.__class__.__name__)
Loading

0 comments on commit 31277ec

Please sign in to comment.