Hi,
I’ve been trying to set up my own little hydroponic pepper garden. The offline part is going pretty decent…
a picot from the inside of my tent! the first habanero is almost ready for tasting and I’m very excited!
Since the vacation is coming soon I also gotten around to the hardware part of automating everything. I’ve been soldering, attaching and a lot of reading from the tutorial. With some help of Kyle I got Mycodo running on a pi. PH/EC CO2 Humidity and temperatures are all working as expected and here’s what it looks like now:
Since I’m a total noob in programming and coding this last part is where I get stuck! I have a Sparkfun I2C quad solid state relay board nicely boxed in the powerbox. I’m also trying to edit the grove multichannel relay to work with this one… there is quiet a nice api from the Sparkfun I’m trying to integrate… however when I install the dependency it isn’t to be found afterwards…
my code:
coding=utf-8
example_dummy_output.py - Example Output module
from flask_babel import lazy_gettext
from mycodo.outputs.base_output import AbstractOutput
from mycodo.utils.constraints_pass import constraints_pass_positive_value
from mycodo.databases.models import OutputChannel
from mycodo.utils.database import db_retrieve_table_daemonMeasurements
measurements_dict = {
0: {
‘measurement’: ‘duration_time’,
‘unit’: ‘s’,
},
1: {
‘measurement’: ‘duty_cycle’,
‘unit’: ‘percent’
},
2: {
‘measurement’: ‘duration_time’,
‘unit’: ‘s’,
},
3: {
‘measurement’: ‘duty_cycle’,
‘unit’: ‘percent’
},
4: {
‘measurement’: ‘duration_time’,
‘unit’: ‘s’,
},
5: {
‘measurement’: ‘duty_cycle’,
‘unit’: ‘percent’
},
6: {
‘measurement’: ‘duration_time’,
‘unit’: ‘s’,
},
7: {
‘measurement’: ‘duty_cycle’,
‘unit’: ‘percent’
}
}channels_dict = {
1: {
‘name’: ‘Relay 1’,
‘types’: [‘on_off’,‘pwm’],
‘measurements’: [0,1]
},
2: {
‘name’: ‘Relay 2’,
‘types’: [‘on_off’,‘pwm’],
‘measurements’: [2,3]
},
3: {
‘name’: ‘Relay 3’,
‘types’: [‘on_off’,‘pwm’],
‘measurements’: [4,5]
},
4: {
‘name’: ‘Relay 4’,
‘types’: [‘on_off’,‘pwm’],
‘measurements’: [6,7]
}
}Output information
OUTPUT_INFORMATION = {
# A unique output name used to distinguish it from others
‘output_name_unique’: ‘Sparkfun Qwiic Quad Solid state relay’,# A friendly/common name for the output to display to the user 'output_name': 'Sparkfun Quad Solid State Relay', 'output_manufacturer': 'Sparkfun', # Optional library name (for outputs that are named the same but use different libraries) # The dictionary of measurements for this output. Don't edit this. 'measurements_dict': measurements_dict, 'channels_dict': channels_dict, # Type of output. Options: "on_off", "pwm", "volume" 'output_types': ['on_off','pwm'], 'url_manufacturer': 'https://www.sparkfun.com/products/16833', 'url_datasheet': 'https://cdn.sparkfun.com/assets/learn_tutorials/1/1/8/6/SparkFun_Qwiic_Quad_Solid_State_Relay-Schematic.pdf', 'url_product_purchase': 'https://www.sparkfun.com/products/16833', # A message to display at the top of the output options 'message': 'Controls the 2 or 4 channel Sparkfun solid state relay board.', # Form input options that are enabled or disabled 'options_enabled': [ 'button_on', # Shows a button to turn the output on 'button_send_duty_cycle', 'I2C location' ], 'options_disabled': [ 'interface' # Show the interface (as a disabled input) ], # Any dependencies required by the output module 'dependencies_module': [ ('pip-pypi', 'sparkfun-qwiic-relay','sparkfun-qwiic-relay') ], # The interface or interfaces that can be used with this module # A custom interface can be used. # Options: SHELL, PYTHON, GPIO, I2C, FTDI, UART 'interfaces': ['I2C'], 'i2c_location': ['0x08'], 'i2c_address_editable': True, 'i2c_address_default': '0x08', 'custom_channel_options': [ { 'id': 'name', 'type': 'text', 'default_value': '', 'required': False, }, { 'id': 'state_startup', 'type': 'select', 'default_value': 0, 'options_select': [ (0, 'Off'), (1, 'On') ], 'name': lazy_gettext('Startup State'), 'phrase': 'Set the state of the relay when Mycodo starts' }, { 'id': 'state_shutdown', 'type': 'select', 'default_value': 0, 'options_select': [ (0, 'Off'), (1, 'On') ], 'name': lazy_gettext('Shutdown State'), 'phrase': 'Set the state of the relay when Mycodo shuts down' }, { 'id': 'on_state', 'type': 'select', 'default_value': 1, 'options_select': [ (1, 'HIGH'), (0, 'LOW') ], 'name': lazy_gettext('On State'), 'phrase': 'The state of the relay that corresponds to an On state' }, { 'id': 'trigger_functions_startup', 'type': 'bool', 'default_value': False, 'name': lazy_gettext('Trigger Functions at Startup'), 'phrase': 'Whether to trigger functions when the output switches at startup' }, { 'id': 'amps', 'type': 'float', 'default_value': 0.0, 'required': True, 'name': '{} ({})'.format(lazy_gettext('Current'), lazy_gettext('Amps')), 'phrase': 'The current draw of the device being controlled' } ]
}
class OutputModule(AbstractOutput):
“”" An output support class that operates an output “”"
def init(self, output, testing=False):
super(OutputModule, self).init(output, testing=testing, name=name)self.myRelays = None output_channels = db_retrieve_table_daemon(OutputChannel).filter(OutputChannel.output_id == output.unique_id).all() self.options_channels = self.setup_custom_channel_options_json( OUTPUT_INFORMATION['custom_channel_options'], output_channels) def setup_output(self): import qwiic_relay self.setup_output_variables(OUTPUT_INFORMATION) try: self.logger.debug("I2C: Address: {}".format(self.output.i2c_location)) if self.output.i2c_location: ## Dit veranderen self.myRelays = qwiic_relay.QwiicRelay(i2c_location) ## klopt deze var verwijzing of moet dit ook self.output. zijn? self.output_setup = True except: self.logger.exception("Could not set up output") return def output_switch(self, state, output_type=None, amount=None, duty_cycle=None, output_channel=None): if output_channel is None: msg = "Output channel needs to be specified" self.logger.error(msg) return msg if not self.is_setup(): msg = "Output not set up" self.logger.error(msg) return msg try: dict_states = {} for channel in channels_dict: if output_channel == channel: if state == 'On': dict_states[channel] = bool(self.options_channels['on_state'][channel]) self.myRelays.set_relay_on(channel); elif state == 'Off': dict_states[channel] = bool(not self.options_channels['on_state'][channel]) self.myRelays.set_relay_off(channel); else: dict_states[channel] = self.output_states[channel] self.logger.debug("List sent to device: {}".format(self.dict_to_list_states(dict_states))) # Dit veranderen self.output_states[output_channel] = dict_states[output_channel] msg = "success" except Exception as e: msg = "CH{} state change error: {}".format(output_channel, e) self.logger.error(msg) return msg def is_on(self, output_channel=None): if self.is_setup(): if output_channel is not None and output_channel in self.output_states: return self.output_states[output_channel] == self.options_channels['on_state'][output_channel] def is_setup(self): return self.output_setup @staticmethod def dict_to_list_states(dict_states): list_states = [] for i, _ in enumerate(dict_states): list_states.append(dict_states[i]) return list_states def stop_output(self): """ Called when Output is stopped """ dict_states = {} if self.is_setup(): for channel in channels_dict: if self.options_channels['state_shutdown'][channel] == 1: dict_states[channel] = bool(self.options_channels['on_state'][channel]) elif self.options_channels['state_shutdown'][channel] == 0: dict_states[channel] = bool(not self.options_channels['on_state'][channel]) self.logger.debug("List sent to device: {}".format(self.dict_to_list_states(dict_states))) self.myRelays.set_relay_off(self) self.running = False
the install log:
[2021-07-17 10:48:52] Dependency installation beginning. Installing: sparkfun-qwiic-relay
[2021-07-17 10:48:52]
[2021-07-17 10:48:52] #### Installing/updating sparkfun-qwiic-relay (pip-pypi)
[2021-07-17 10:48:53] Requirement already satisfied: sparkfun-qwiic-relay in ./env/lib/python3.7/site-packages (0.0.2)
[2021-07-17 10:48:53] Requirement already satisfied: sparkfun-qwiic-i2c in ./env/lib/python3.7/site-packages (from sparkfun-qwiic-relay) (0.9.11)
[2021-07-17 10:48:53] Requirement already satisfied: smbus2 in ./env/lib/python3.7/site-packages (from sparkfun-qwiic-i2c->sparkfun-qwiic-relay) (0.4.1)
[2021-07-17 10:48:55] End install of sparkfun-qwiic-relay
[2021-07-17 10:48:55]
[2021-07-17 10:48:55] #### Setting permissions
[2021-07-17 10:48:56] #### Dependency install finished
now there is probably a ton of other errors and there is still a lot to do (adding PWM) but I can’t test without trial and error