From c32caaa607aaaed0fa74a310d393d3f68010dfd7 Mon Sep 17 00:00:00 2001 From: Kyle Date: Mon, 9 Sep 2024 15:25:09 -0400 Subject: [PATCH] Fix PWM Outputs not recording values of 0 to database, add ability to edit Input and Input Measurement unique_id --- CHANGELOG.md | 2 ++ mycodo/config_translations.py | 3 +++ mycodo/mycodo_flask/forms/forms_input.py | 4 ++++ .../pages/data_options/input_options.html | 7 +++++++ .../pages/form_options/Measurements_Configure.html | 7 +++++++ mycodo/mycodo_flask/utils/utils_input.py | 11 +++++++++++ mycodo/mycodo_flask/utils/utils_measurement.py | 14 ++++++++++++++ mycodo/outputs/pwm_gpio.py | 2 +- mycodo/outputs/pwm_mqtt.py | 2 +- mycodo/outputs/pwm_pca9685.py | 2 +- mycodo/outputs/pwm_python.py | 2 +- mycodo/outputs/pwm_shell.py | 2 +- 12 files changed, 53 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d6b103a0..22a89a64f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ This release changes the install directory from ~/Mycodo to /opt/Mycodo. This ne - Fix displaying Tags on Highcharts Widget - Fix dependencies of Mijia LYWSD03MMC - Fix Restart Frontend returning an error + - Fix PWM Outputs not recording values of 0 to database ### Features @@ -36,6 +37,7 @@ This release changes the install directory from ~/Mycodo to /opt/Mycodo. This ne - Add controller_restart as client endpoint - Add option for custom CSS - Add options for changing title and brand text + - Add ability to edit Input and Input Measurement unique_id ### Miscellaneous diff --git a/mycodo/config_translations.py b/mycodo/config_translations.py index 79e523cd8..e1528f4a2 100644 --- a/mycodo/config_translations.py +++ b/mycodo/config_translations.py @@ -416,6 +416,9 @@ 'uart_location': { 'title': lazy_gettext('UART Device'), 'phrase': lazy_gettext('The UART device location (e.g. /dev/ttyUSB1)')}, + 'unique_id': { + 'title': lazy_gettext('Unique ID'), + 'phrase': lazy_gettext('A unique ID to distinguish this from others')}, 'use_pylint': { 'title': lazy_gettext('Analyze Python with Pylint'), 'phrase': lazy_gettext('Analyze the Python code with pylint and return the output')}, diff --git a/mycodo/mycodo_flask/forms/forms_input.py b/mycodo/mycodo_flask/forms/forms_input.py index 4b6b3884d..6d00a4f82 100644 --- a/mycodo/mycodo_flask/forms/forms_input.py +++ b/mycodo/mycodo_flask/forms/forms_input.py @@ -79,6 +79,10 @@ class InputMod(FlaskForm): TRANSLATIONS['name']['title'], validators=[DataRequired()] ) + unique_id = StringField( + TRANSLATIONS['unique_id']['title'], + validators=[DataRequired()] + ) period = DecimalField( TRANSLATIONS['period']['title'], validators=[DataRequired(), diff --git a/mycodo/mycodo_flask/templates/pages/data_options/input_options.html b/mycodo/mycodo_flask/templates/pages/data_options/input_options.html index ac36157c8..f11a4d4f2 100644 --- a/mycodo/mycodo_flask/templates/pages/data_options/input_options.html +++ b/mycodo/mycodo_flask/templates/pages/data_options/input_options.html @@ -141,6 +141,13 @@
{{_('Options')}}
+
+ {{form_mod_input.unique_id.label(class_='control-label')}} +
+ {{form_mod_input.unique_id(class_='form-control', value=each_input.unique_id, **{'title': dict_translation['unique_id']['phrase']})}} +
+
+ {% if each_input.device != 'input_spacer' %}
diff --git a/mycodo/mycodo_flask/templates/pages/form_options/Measurements_Configure.html b/mycodo/mycodo_flask/templates/pages/form_options/Measurements_Configure.html index efa243d96..51cd1d3e5 100644 --- a/mycodo/mycodo_flask/templates/pages/form_options/Measurements_Configure.html +++ b/mycodo/mycodo_flask/templates/pages/form_options/Measurements_Configure.html @@ -65,6 +65,13 @@
Configure Measurements
{% endif %} +
+ +
+ +
+
+
diff --git a/mycodo/mycodo_flask/utils/utils_input.py b/mycodo/mycodo_flask/utils/utils_input.py index 4a1c394e6..d9de3e51a 100644 --- a/mycodo/mycodo_flask/utils/utils_input.py +++ b/mycodo/mycodo_flask/utils/utils_input.py @@ -366,6 +366,17 @@ def input_mod(form_mod, request_form): mod_input.name = form_mod.name.data messages["name"] = form_mod.name.data + if mod_input.unique_id != form_mod.unique_id.data: + test_unique_id = Input.query.filter(Input.unique_id == form_mod.unique_id.data).first() + if test_unique_id: + messages["error"].append( + f"Input ID must be unique. " + f"ID already exists: '{form_mod.unique_id.data}'") + elif not form_mod.unique_id.data: + messages["error"].append(f"Input ID is required") + else: + mod_input.unique_id = form_mod.unique_id.data + if form_mod.location.data: mod_input.location = form_mod.location.data if form_mod.i2c_location.data: diff --git a/mycodo/mycodo_flask/utils/utils_measurement.py b/mycodo/mycodo_flask/utils/utils_measurement.py index 6e7a45edd..7dec2d0d7 100644 --- a/mycodo/mycodo_flask/utils/utils_measurement.py +++ b/mycodo/mycodo_flask/utils/utils_measurement.py @@ -54,6 +54,20 @@ def measurement_mod_form(messages, page_refresh, form): f"{gettext('Deactivate controller before modifying its settings')}: {mod_device.name}") break + if ("measurement_id_{}".format(each_meas_id) in form and + form["measurement_id_{}".format(each_meas_id)] and + mod_meas.unique_id != form["measurement_id_{}".format(each_meas_id)]): + test_meas_id = DeviceMeasurements.query.filter( + DeviceMeasurements.unique_id == form["measurement_id_{}".format(each_meas_id)]).first() + if test_meas_id: + messages["error"].append( + f"Measurement ID must be unique. " + f"ID already exists: '{form['measurement_id_{}'.format(each_meas_id)]}'") + elif not form["measurement_id_{}".format(each_meas_id)]: + messages["error"].append(f"Measurement ID is required") + else: + mod_meas.unique_id = form["measurement_id_{}".format(each_meas_id)] + if ("measurement_meas_name_{}".format(each_meas_id) in form and form["measurement_meas_name_{}".format(each_meas_id)]): mod_meas.name = form["measurement_meas_name_{}".format(each_meas_id)] diff --git a/mycodo/outputs/pwm_gpio.py b/mycodo/outputs/pwm_gpio.py index 80991d153..98b9284cf 100644 --- a/mycodo/outputs/pwm_gpio.py +++ b/mycodo/outputs/pwm_gpio.py @@ -286,7 +286,7 @@ def output_switch(self, state, output_type=None, amount=None, output_channel=Non if self.options_channels['pwm_invert_stored_signal'][0]: amount = 100.0 - abs(amount) - measure_dict[0]['value'] = amount + measure_dict[0]['value'] = float(amount) add_measurements_influxdb(self.unique_id, measure_dict) return "success" diff --git a/mycodo/outputs/pwm_mqtt.py b/mycodo/outputs/pwm_mqtt.py index afdbf7112..cca1364fc 100644 --- a/mycodo/outputs/pwm_mqtt.py +++ b/mycodo/outputs/pwm_mqtt.py @@ -304,7 +304,7 @@ def output_switch(self, state, output_type=None, amount=None, output_channel=0): self.output_states[output_channel] = amount - measure_dict[0]['value'] = amount + measure_dict[0]['value'] = float(amount) add_measurements_influxdb(self.unique_id, measure_dict) return "success" diff --git a/mycodo/outputs/pwm_pca9685.py b/mycodo/outputs/pwm_pca9685.py index 1dc7f2ccc..600d93b3e 100644 --- a/mycodo/outputs/pwm_pca9685.py +++ b/mycodo/outputs/pwm_pca9685.py @@ -287,7 +287,7 @@ def output_switch(self, state, output_type=None, amount=0, output_channel=None): if self.options_channels['pwm_invert_stored_signal'][output_channel]: amount = 100.0 - abs(amount) - measure_dict[output_channel]['value'] = amount + measure_dict[output_channel]['value'] = float(amount) add_measurements_influxdb(self.unique_id, measure_dict) return "success" diff --git a/mycodo/outputs/pwm_python.py b/mycodo/outputs/pwm_python.py index 4d49e72a3..674fa8c09 100644 --- a/mycodo/outputs/pwm_python.py +++ b/mycodo/outputs/pwm_python.py @@ -398,7 +398,7 @@ def output_switch(self, state, output_type=None, amount=None, output_channel=Non if self.options_channels['pwm_invert_stored_signal'][0]: amount = 100.0 - abs(amount) - measure_dict[0]['value'] = amount + measure_dict[0]['value'] = float(amount) add_measurements_influxdb(self.unique_id, measure_dict) def is_on(self, output_channel=None): diff --git a/mycodo/outputs/pwm_shell.py b/mycodo/outputs/pwm_shell.py index d94e8962f..e03e346aa 100644 --- a/mycodo/outputs/pwm_shell.py +++ b/mycodo/outputs/pwm_shell.py @@ -226,7 +226,7 @@ def output_switch(self, state, output_type=None, amount=None, output_channel=Non if self.options_channels['pwm_invert_stored_signal'][0]: amount = 100.0 - abs(amount) - measure_dict[0]['value'] = amount + measure_dict[0]['value'] = float(amount) add_measurements_influxdb(self.unique_id, measure_dict) def is_on(self, output_channel=None):