def initialize_variables(self): from mycodo.devices.lcd_pioled_circuitpython import LCD_Pioled_Circuitpython try: function_channels = db_retrieve_table_daemon( FunctionChannel).filter( FunctionChannel.function_id == self.unique_id).all() self.options_channels = self.setup_custom_channel_options_json( FUNCTION_INFORMATION['custom_channel_options'], function_channels) for each_set in range(self.number_line_sets): self.line_sets.append([]) for each_line in range(lcd_lines): self.line_sets[each_set].append(each_line) self.logger.debug("Line sets: {}".format(self.line_sets)) lcd_settings_dict = { "unique_id": self.unique_id, "interface": "I2C", "i2c_address": self.i2c_address, "i2c_bus": self.i2c_bus, "x_characters": lcd_x_characters, "lcd_type": "128x64_pioled_circuit_python" } self.device = LCD_Pioled_Circuitpython( lcd_settings_dict=lcd_settings_dict) self.device.lcd_init() self.logger.debug("LCD Function started") except: self.logger.exception("Starting LCD Function")
class CustomModule(AbstractFunction): """ Class to operate custom controller """ def __init__(self, function, testing=False): super(CustomModule, self).__init__(function, testing=testing, name=__name__) self.options_channels = {} self.device = None self.timer_loop = time.time() self.line_sets = [] self.current_line_set = 0 self.line_y_dimensions = [0, 8, 16, 24, 32, 40, 48, 56] self.pad = -2 # Initialize custom options self.period = None self.spi_bus = None self.spi_device = None self.pin_dc = None self.pin_reset = None self.pin_cs = None self.number_line_sets = None self.pin_reset = None # Set custom options custom_function = db_retrieve_table_daemon(CustomController, unique_id=self.unique_id) self.setup_custom_options(FUNCTION_INFORMATION['custom_options'], custom_function) if not testing: self.initialize_variables() def initialize_variables(self): from mycodo.devices.lcd_pioled_circuitpython import LCD_Pioled_Circuitpython try: function_channels = db_retrieve_table_daemon( FunctionChannel).filter( FunctionChannel.function_id == self.unique_id).all() self.options_channels = self.setup_custom_channel_options_json( FUNCTION_INFORMATION['custom_channel_options'], function_channels) for each_set in range(self.number_line_sets): self.line_sets.append([]) for each_line in range(lcd_lines): self.line_sets[each_set].append(each_line) self.logger.debug("Line sets: {}".format(self.line_sets)) lcd_settings_dict = { "unique_id": self.unique_id, "interface": "SPI", "spi_bus": self.spi_bus, "spi_device": self.spi_device, "pin_dc": self.pin_dc, "pin_reset": self.pin_reset, "pin_cs": self.pin_cs, "x_characters": lcd_x_characters, "lcd_type": "128x64_pioled_circuit_python" } self.device = LCD_Pioled_Circuitpython( lcd_settings_dict=lcd_settings_dict) self.device.lcd_init() self.logger.debug("LCD Function started") except: self.logger.exception("Starting LCD Function") def loop(self): if self.timer_loop > time.time(): return while self.timer_loop < time.time(): self.timer_loop += self.period if not self.device: self.logger.error("LCD not set up") return # Generate lines to display lines_display = {} for line in range(lcd_lines): lines_display[line] = "" for current_line in self.line_sets[self.current_line_set]: current_channel = (self.current_line_set * lcd_lines) + current_line self.logger.debug("Channel: {}, Set: {} Line: {}, ".format( current_channel, self.current_line_set, current_line)) try: # Get measurement value and timestamp if self.options_channels['line_display_type'][ current_channel] in [ 'measurement_value', 'measurement_ts' ]: lines_display[current_line] = "NONE" measure_ts = None measure_value = None last_measurement = self.get_last_measurement( self.options_channels['select_measurement'] [current_channel]['device_id'], self.options_channels['select_measurement'] [current_channel]['measurement_id'], max_age=self.options_channels['measure_max_age'] [current_channel]) if last_measurement: measure_ts = last_measurement[0] measure_value = last_measurement[1] if self.options_channels['line_display_type'][ current_channel] == 'measurement_value': if measure_value: if self.options_channels['measure_decimal'][ current_channel] == 0: val_rounded = int( self.options_channels['measure_decimal'] [current_channel]) else: val_rounded = round( measure_value, self.options_channels['measure_decimal'] [current_channel]) lines_display[ current_line] = format_measurement_line( self.options_channels['select_measurement'] [current_channel]['device_id'], self.options_channels['select_measurement'] [current_channel]['measurement_id'], val_rounded, lcd_x_characters) elif self.options_channels['line_display_type'][ current_channel] == 'measurement_ts': if measure_ts: # Convert UTC timestamp to local timezone utc_dt = datetime.datetime.strptime( measure_ts.split(".")[0], '%Y-%m-%dT%H:%M:%S') utc_timestamp = calendar.timegm(utc_dt.timetuple()) lines_display[current_line] = str( datetime.datetime.fromtimestamp(utc_timestamp)) elif self.options_channels['line_display_type'][ current_channel] == 'current_time': lines_display[current_line] = time.strftime( '%Y-%m-%d %H:%M:%S') elif self.options_channels['line_display_type'][ current_channel] == 'text': lines_display[current_line] = self.options_channels[ 'text'][current_channel] elif self.options_channels['line_display_type'][ current_channel] == 'blank_line': lines_display[current_line] = "" elif self.options_channels['line_display_type'][ current_channel] == 'ip_address': str_ip_cmd = "ip addr | " \ "grep 'state UP' -A2 | " \ "tail -n1 | " \ "awk '{print $2}' | " \ "cut -f1 -d'/'" ip_out, _, _ = cmd_output(str_ip_cmd) lines_display[current_line] = ip_out.rstrip().decode( "utf-8") except Exception as err: # self.logger.exception("Generating line") self.logger.error( "Error generating channel {} line: {}".format( current_channel, err)) lines_display[current_line] = "ERROR" if self.current_line_set == len(self.line_sets) - 1: self.current_line_set = 0 else: self.current_line_set += 1 self.logger.debug("Displaying: {}".format(lines_display)) # Display lines self.device.lcd_init() self.device.lcd_write_lines(lines_display[0], lines_display[1], lines_display[2], lines_display[3]) def stop_function(self): self.device.lcd_write_lines("Mycodo {}".format(MYCODO_VERSION), "Display Deactivated", "", "")
class LCDController(AbstractController, threading.Thread): """ Class to operate LCD controller """ def __init__(self, ready, unique_id): threading.Thread.__init__(self) super(LCDController, self).__init__(ready, unique_id=unique_id, name=__name__) self.unique_id = unique_id self.sample_rate = 1 self.flash_lcd_on = False self.lcd_initialized = False self.lcd_is_on = False self.display_sets = [] self.display_set_count = 0 self.lcd_out = None self.lcd_type = None self.lcd_name = None self.lcd_period = None self.lcd_x_characters = None self.lcd_y_lines = None self.timer = None self.backlight_timer = None self.log_level_debug = None self.list_inputs = None self.dict_units = None self.lcd_string_line = {} self.lcd_line = {} self.lcd_text = {} self.lcd_max_age = {} self.lcd_decimal_places = {} def loop(self): if not self.lcd_initialized: self.stop_controller() elif (self.lcd_is_on and self.lcd_initialized and time.time() > self.timer): try: # Acquire all measurements to be displayed on the LCD display_id = self.display_sets[self.display_set_count] for line in range(1, self.lcd_y_lines + 1): if not self.running: break if self.lcd_line[display_id][line]['id'] and self.lcd_line[display_id][line]['setup']: self.create_lcd_line( self.get_measurement(display_id, line), display_id, line) else: self.lcd_string_line[display_id][line] = 'LCD LINE ERROR' # Output lines to the LCD if self.running: self.output_lcds() except KeyError: self.logger.exception( "KeyError: Unable to output to LCD.") except IOError: self.logger.exception( "IOError: Unable to output to LCD.") except Exception: self.logger.exception( "Exception: Unable to output to LCD.") # Increment display counter to show the next display if len(self.display_sets) > 1: if self.display_set_count < len(self.display_sets) - 1: self.display_set_count += 1 else: self.display_set_count = 0 self.timer = time.time() + self.lcd_period elif not self.lcd_is_on: # Turn backlight off self.lcd_out.lcd_backlight(0) if self.flash_lcd_on: if time.time() > self.backlight_timer: if self.lcd_is_on: self.lcd_backlight(0) seconds = 0.2 else: self.output_lcds() seconds = 1.1 self.backlight_timer = time.time() + seconds def run_finally(self): self.lcd_out.lcd_init() # Blank LCD line_1 = 'Mycodo {}'.format(MYCODO_VERSION) line_2 = 'Stop {}'.format(self.lcd_name) self.lcd_out.lcd_write_lines(line_1, line_2, '', '') def initialize_variables(self): lcd_dev = db_retrieve_table_daemon(LCD, unique_id=self.unique_id) self.lcd_type = lcd_dev.lcd_type self.lcd_name = lcd_dev.name self.lcd_period = lcd_dev.period self.lcd_x_characters = lcd_dev.x_characters self.lcd_y_lines = lcd_dev.y_lines self.timer = time.time() + self.lcd_period self.backlight_timer = time.time() self.log_level_debug = lcd_dev.log_level_debug self.set_log_level_debug(self.log_level_debug) # Add custom measurement and units to list self.list_inputs = add_custom_measurements( db_retrieve_table_daemon(Measurement, entry='all')) self.list_inputs.update( {'input_time': {'unit': None, 'name': 'Time'}}) self.list_inputs.update( {'pid_time': {'unit': None, 'name': 'Time'}}) self.dict_units = add_custom_units( db_retrieve_table_daemon(Unit, entry='all')) lcd_data = db_retrieve_table_daemon( LCDData).filter(LCDData.lcd_id == lcd_dev.unique_id).all() for each_lcd_display in lcd_data: self.display_sets.append(each_lcd_display.unique_id) self.lcd_string_line[each_lcd_display.unique_id] = {} self.lcd_line[each_lcd_display.unique_id] = {} self.lcd_text[each_lcd_display.unique_id] = {} self.lcd_max_age[each_lcd_display.unique_id] = {} self.lcd_decimal_places[each_lcd_display.unique_id] = {} for i in range(1, self.lcd_y_lines + 1): self.lcd_string_line[each_lcd_display.unique_id][i] = '' self.lcd_line[each_lcd_display.unique_id][i] = {} if i == 1: self.lcd_text[each_lcd_display.unique_id][i] = each_lcd_display.line_1_text self.lcd_max_age[each_lcd_display.unique_id][i] = each_lcd_display.line_1_max_age self.lcd_decimal_places[each_lcd_display.unique_id][i] = each_lcd_display.line_1_decimal_places elif i == 2: self.lcd_text[each_lcd_display.unique_id][i] = each_lcd_display.line_2_text self.lcd_max_age[each_lcd_display.unique_id][i] = each_lcd_display.line_2_max_age self.lcd_decimal_places[each_lcd_display.unique_id][i] = each_lcd_display.line_2_decimal_places elif i == 3: self.lcd_text[each_lcd_display.unique_id][i] = each_lcd_display.line_3_text self.lcd_max_age[each_lcd_display.unique_id][i] = each_lcd_display.line_3_max_age self.lcd_decimal_places[each_lcd_display.unique_id][i] = each_lcd_display.line_3_decimal_places elif i == 4: self.lcd_text[each_lcd_display.unique_id][i] = each_lcd_display.line_4_text self.lcd_max_age[each_lcd_display.unique_id][i] = each_lcd_display.line_4_max_age self.lcd_decimal_places[each_lcd_display.unique_id][i] = each_lcd_display.line_4_decimal_places elif i == 5: self.lcd_text[each_lcd_display.unique_id][i] = each_lcd_display.line_5_text self.lcd_max_age[each_lcd_display.unique_id][i] = each_lcd_display.line_5_max_age self.lcd_decimal_places[each_lcd_display.unique_id][i] = each_lcd_display.line_5_decimal_places elif i == 6: self.lcd_text[each_lcd_display.unique_id][i] = each_lcd_display.line_6_text self.lcd_max_age[each_lcd_display.unique_id][i] = each_lcd_display.line_6_max_age self.lcd_decimal_places[each_lcd_display.unique_id][i] = each_lcd_display.line_6_decimal_places elif i == 7: self.lcd_text[each_lcd_display.unique_id][i] = each_lcd_display.line_7_text self.lcd_max_age[each_lcd_display.unique_id][i] = each_lcd_display.line_7_max_age self.lcd_decimal_places[each_lcd_display.unique_id][i] = each_lcd_display.line_7_decimal_places elif i == 8: self.lcd_text[each_lcd_display.unique_id][i] = each_lcd_display.line_8_text self.lcd_max_age[each_lcd_display.unique_id][i] = each_lcd_display.line_8_max_age self.lcd_decimal_places[each_lcd_display.unique_id][i] = each_lcd_display.line_8_decimal_places if self.lcd_y_lines in [2, 4, 8]: self.setup_lcd_line( each_lcd_display.unique_id, 1, each_lcd_display.line_1_id, each_lcd_display.line_1_measurement) self.setup_lcd_line( each_lcd_display.unique_id, 2, each_lcd_display.line_2_id, each_lcd_display.line_2_measurement) if self.lcd_y_lines in [4, 8]: self.setup_lcd_line( each_lcd_display.unique_id, 3, each_lcd_display.line_3_id, each_lcd_display.line_3_measurement) self.setup_lcd_line( each_lcd_display.unique_id, 4, each_lcd_display.line_4_id, each_lcd_display.line_4_measurement) if self.lcd_y_lines == 8: self.setup_lcd_line( each_lcd_display.unique_id, 5, each_lcd_display.line_5_id, each_lcd_display.line_5_measurement) self.setup_lcd_line( each_lcd_display.unique_id, 6, each_lcd_display.line_6_id, each_lcd_display.line_6_measurement) self.setup_lcd_line( each_lcd_display.unique_id, 7, each_lcd_display.line_7_id, each_lcd_display.line_7_measurement) self.setup_lcd_line( each_lcd_display.unique_id, 8, each_lcd_display.line_8_id, each_lcd_display.line_8_measurement) if self.lcd_type in ['16x2_generic', '20x4_generic']: from mycodo.devices.lcd_generic import LCD_Generic self.lcd_out = LCD_Generic(lcd_dev) self.lcd_init() elif self.lcd_type in ['16x2_grove_lcd_rgb']: from mycodo.devices.lcd_grove_lcd_rgb import LCD_Grove_LCD_RGB self.lcd_out = LCD_Grove_LCD_RGB(lcd_dev) self.lcd_init() elif self.lcd_type in ['128x32_pioled', '128x64_pioled']: from mycodo.devices.lcd_pioled import LCD_Pioled self.lcd_out = LCD_Pioled(lcd_dev) self.lcd_init() elif self.lcd_type in ['128x32_pioled_circuit_python', '128x64_pioled_circuit_python']: from mycodo.devices.lcd_pioled_circuitpython import LCD_Pioled_Circuitpython self.lcd_out = LCD_Pioled_Circuitpython(lcd_dev) self.lcd_init() else: self.logger.error("Unknown LCD type: {}".format(self.lcd_type)) if self.lcd_initialized: line_1 = 'Mycodo {}'.format(MYCODO_VERSION) line_2 = 'Start {}'.format(self.lcd_name) self.lcd_out.lcd_write_lines(line_1, line_2, '', '') def lcd_init(self): self.lcd_out.lcd_init() self.lcd_initialized = True self.lcd_is_on = True def get_measurement(self, display_id, i): try: if self.lcd_line[display_id][i]['measure'] == 'TEXT': # Display custom, user-entered text self.lcd_line[display_id][i]['name'] = '' self.lcd_line[display_id][i]['unit'] = '' if len(self.lcd_text[display_id][i]) > self.lcd_x_characters: self.lcd_line[display_id][i]['measure_val'] = self.lcd_text[display_id][i][:self.lcd_x_characters] else: self.lcd_line[display_id][i]['measure_val'] = self.lcd_text[display_id][i] return True elif self.lcd_line[display_id][i]['measure'] == 'BLANK': # Display an empty line self.lcd_line[display_id][i]['name'] = '' self.lcd_line[display_id][i]['unit'] = '' self.lcd_line[display_id][i]['measure_val'] = '' return True elif self.lcd_line[display_id][i]['measure'] == 'IP': # Display the device's IP address str_ip_cmd = "ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/'" ip_out, _, _ = cmd_output(str_ip_cmd) self.lcd_line[display_id][i]['name'] = '' self.lcd_line[display_id][i]['unit'] = '' self.lcd_line[display_id][i]['measure_val'] = ip_out.rstrip().decode("utf-8") return True elif self.lcd_line[display_id][i]['measure'] == 'output_state': # Display the GPIO state # TODO: Currently not a selectable option in the LCD Line dropdown self.lcd_line[display_id][i]['measure_val'] = self.output_state( self.lcd_line[display_id][i]['id']) return True else: if self.lcd_line[display_id][i]['measure'] == 'time': # Display the time of the last measurement last_measurement = read_last_influxdb( self.lcd_line[display_id][i]['id'], '/.*/', None, duration_sec=self.lcd_max_age[display_id][i]) else: last_measurement = read_last_influxdb( self.lcd_line[display_id][i]['id'], self.lcd_line[display_id][i]['unit'], self.lcd_line[display_id][i]['channel'], measure=self.lcd_line[display_id][i]['measure'], duration_sec=self.lcd_max_age[display_id][i]) if last_measurement: self.lcd_line[display_id][i]['time'] = last_measurement[0] if self.lcd_decimal_places[display_id][i] == 0: self.lcd_line[display_id][i]['measure_val'] = int(last_measurement[1]) else: self.lcd_line[display_id][i]['measure_val'] = round( last_measurement[1], self.lcd_decimal_places[display_id][i]) utc_dt = datetime.datetime.strptime( self.lcd_line[display_id][i]['time'].split(".")[0], '%Y-%m-%dT%H:%M:%S') utc_timestamp = calendar.timegm(utc_dt.timetuple()) local_timestamp = str(datetime.datetime.fromtimestamp(utc_timestamp)) self.logger.debug("Latest {}: {} @ {}".format( self.lcd_line[display_id][i]['measure'], self.lcd_line[display_id][i]['measure_val'], local_timestamp)) return True else: self.lcd_line[display_id][i]['time'] = None self.lcd_line[display_id][i]['measure_val'] = None self.logger.debug("No data returned from influxdb") return False except Exception as except_msg: self.logger.debug( "Failed to read measurement from the influxdb database: " "{err}".format(err=except_msg)) return False def create_lcd_line(self, last_measurement_success, display_id, i): try: if last_measurement_success: if self.lcd_line[display_id][i]['unit'] in self.dict_units: unit_display = self.dict_units[self.lcd_line[display_id][i]['unit']]['unit'] else: unit_display = '' if unit_display: unit_length = len(unit_display.replace('°', u'')) else: unit_length = 0 # Produce the line that will be displayed on the LCD if self.lcd_line[display_id][i]['measure'] == 'time': # Convert UTC timestamp to local timezone utc_dt = datetime.datetime.strptime( self.lcd_line[display_id][i]['time'].split(".")[0], '%Y-%m-%dT%H:%M:%S') utc_timestamp = calendar.timegm(utc_dt.timetuple()) self.lcd_string_line[display_id][i] = str( datetime.datetime.fromtimestamp(utc_timestamp)) elif unit_length > 0: value_length = len(str( self.lcd_line[display_id][i]['measure_val'])) name_length = self.lcd_x_characters - value_length - unit_length - 2 name_cropped = self.lcd_line[display_id][i]['name'].ljust(name_length)[:name_length] self.lcd_string_line[display_id][i] = '{name} {value} {unit}'.format( name=name_cropped, value=self.lcd_line[display_id][i]['measure_val'], unit=unit_display.replace('°', u'')) else: value_length = len(str( self.lcd_line[display_id][i]['measure_val'])) name_length = self.lcd_x_characters - value_length - 1 name_cropped = self.lcd_line[display_id][i]['name'][:name_length] if name_cropped != '': line_str = '{name} {value}'.format( name=name_cropped, value=self.lcd_line[display_id][i]['measure_val']) else: line_str = self.lcd_line[display_id][i]['measure_val'] self.lcd_string_line[display_id][i] = line_str else: error = 'NO DATA' name_length = self.lcd_x_characters - len(error) - 1 name_cropped = self.lcd_line[display_id][i]['name'].ljust(name_length)[:name_length] self.lcd_string_line[display_id][i] = '{name} {error}'.format( name=name_cropped, error=error) except Exception as except_msg: self.logger.exception("Error: {err}".format(err=except_msg)) def output_lcds(self): """ Output to all LCDs all at once """ line_1 = '' line_2 = '' line_3 = '' line_4 = '' line_5 = '' line_6 = '' line_7 = '' line_8 = '' self.lcd_out.lcd_init() display_id = self.display_sets[self.display_set_count] if 1 in self.lcd_string_line[display_id] and self.lcd_string_line[display_id][1]: line_1 = self.lcd_string_line[display_id][1] if 2 in self.lcd_string_line[display_id] and self.lcd_string_line[display_id][2]: line_2 = self.lcd_string_line[display_id][2] if 3 in self.lcd_string_line[display_id] and self.lcd_string_line[display_id][3]: line_3 = self.lcd_string_line[display_id][3] if 4 in self.lcd_string_line[display_id] and self.lcd_string_line[display_id][4]: line_4 = self.lcd_string_line[display_id][4] if 5 in self.lcd_string_line[display_id] and self.lcd_string_line[display_id][5]: line_5 = self.lcd_string_line[display_id][5] if 6 in self.lcd_string_line[display_id] and self.lcd_string_line[display_id][6]: line_6 = self.lcd_string_line[display_id][6] if 7 in self.lcd_string_line[display_id] and self.lcd_string_line[display_id][7]: line_7 = self.lcd_string_line[display_id][7] if 8 in self.lcd_string_line[display_id] and self.lcd_string_line[display_id][8]: line_8 = self.lcd_string_line[display_id][8] if self.lcd_type in ['128x32_pioled', '128x32_pioled_circuit_python', '16x2_generic', '20x4_generic', '16x2_grove_lcd_rgb']: self.lcd_out.lcd_write_lines(line_1, line_2, line_3, line_4) elif self.lcd_type in ['128x64_pioled', '128x64_pioled_circuit_python']: self.lcd_out.lcd_write_lines(line_1, line_2, line_3, line_4, message_line_5=line_5, message_line_6=line_6, message_line_7=line_7, message_line_8=line_8) def output_state(self, output_id): output = db_retrieve_table_daemon(Output, unique_id=output_id) try: import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) if GPIO.input(output.pin) == output.on_state: gpio_state = 'On' else: gpio_state = 'Off' return gpio_state except: self.logger.error( "RPi.GPIO and Raspberry Pi required for this action") def setup_lcd_line(self, display_id, line, device_id, measurement_id): if measurement_id == 'output': device_measurement = db_retrieve_table_daemon( Output, unique_id=device_id) elif measurement_id in ['BLANK', 'IP', 'TEXT']: device_measurement = None else: device_measurement = db_retrieve_table_daemon( DeviceMeasurements, unique_id=measurement_id) if device_measurement: conversion = db_retrieve_table_daemon( Conversion, unique_id=device_measurement.conversion_id) channel, unit, measurement = return_measurement_info( device_measurement, conversion) else: channel = None unit = None measurement = None self.lcd_line[display_id][line]['setup'] = False self.lcd_line[display_id][line]['id'] = device_id self.lcd_line[display_id][line]['name'] = None self.lcd_line[display_id][line]['unit'] = unit self.lcd_line[display_id][line]['measure'] = measurement self.lcd_line[display_id][line]['channel'] = channel if 'time' in measurement_id: self.lcd_line[display_id][line]['measure'] = 'time' elif measurement_id in ['BLANK', 'IP', 'TEXT']: self.lcd_line[display_id][line]['measure'] = measurement_id self.lcd_line[display_id][line]['name'] = '' if not device_id: return if unit in self.dict_units: self.lcd_line[display_id][line]['unit'] = unit else: self.lcd_line[display_id][line]['unit'] = '' # Determine the name controllers = [ Output, PID, Input, Math ] for each_controller in controllers: controller_found = db_retrieve_table_daemon(each_controller, unique_id=device_id) if controller_found: self.lcd_line[display_id][line]['name'] = controller_found.name if (self.lcd_line[display_id][line]['measure'] in ['BLANK', 'IP', 'TEXT', 'time'] or None not in [self.lcd_line[display_id][line]['name'], self.lcd_line[display_id][line]['unit']]): self.lcd_line[display_id][line]['setup'] = True def lcd_backlight(self, state): """ Turn the backlight on or off """ if state: self.lcd_out.lcd_backlight(state) self.lcd_is_on = True self.timer = time.time() - 1 # Induce LCD to update after turning backlight on else: self.lcd_is_on = False # Instruct LCD backlight to turn off def lcd_backlight_color(self, color): """ Set backlight color """ self.lcd_out.lcd_backlight_color(color) self.timer = time.time() - 1 # Induce LCD to update after turning backlight on def lcd_flash(self, state): """ Enable the LCD to begin or end flashing """ if state: self.flash_lcd_on = True return 1, "LCD {} Flashing Turned On".format(self.unique_id) else: self.flash_lcd_on = False self.lcd_backlight(True) return 1, "LCD {} Reset".format(self.unique_id)
def initialize_variables(self): lcd_dev = db_retrieve_table_daemon(LCD, unique_id=self.unique_id) self.lcd_type = lcd_dev.lcd_type self.lcd_name = lcd_dev.name self.lcd_period = lcd_dev.period self.lcd_x_characters = lcd_dev.x_characters self.lcd_y_lines = lcd_dev.y_lines self.timer = time.time() + self.lcd_period self.backlight_timer = time.time() self.log_level_debug = lcd_dev.log_level_debug self.set_log_level_debug(self.log_level_debug) # Add custom measurement and units to list self.list_inputs = add_custom_measurements( db_retrieve_table_daemon(Measurement, entry='all')) self.list_inputs.update( {'input_time': {'unit': None, 'name': 'Time'}}) self.list_inputs.update( {'pid_time': {'unit': None, 'name': 'Time'}}) self.dict_units = add_custom_units( db_retrieve_table_daemon(Unit, entry='all')) lcd_data = db_retrieve_table_daemon( LCDData).filter(LCDData.lcd_id == lcd_dev.unique_id).all() for each_lcd_display in lcd_data: self.display_sets.append(each_lcd_display.unique_id) self.lcd_string_line[each_lcd_display.unique_id] = {} self.lcd_line[each_lcd_display.unique_id] = {} self.lcd_text[each_lcd_display.unique_id] = {} self.lcd_max_age[each_lcd_display.unique_id] = {} self.lcd_decimal_places[each_lcd_display.unique_id] = {} for i in range(1, self.lcd_y_lines + 1): self.lcd_string_line[each_lcd_display.unique_id][i] = '' self.lcd_line[each_lcd_display.unique_id][i] = {} if i == 1: self.lcd_text[each_lcd_display.unique_id][i] = each_lcd_display.line_1_text self.lcd_max_age[each_lcd_display.unique_id][i] = each_lcd_display.line_1_max_age self.lcd_decimal_places[each_lcd_display.unique_id][i] = each_lcd_display.line_1_decimal_places elif i == 2: self.lcd_text[each_lcd_display.unique_id][i] = each_lcd_display.line_2_text self.lcd_max_age[each_lcd_display.unique_id][i] = each_lcd_display.line_2_max_age self.lcd_decimal_places[each_lcd_display.unique_id][i] = each_lcd_display.line_2_decimal_places elif i == 3: self.lcd_text[each_lcd_display.unique_id][i] = each_lcd_display.line_3_text self.lcd_max_age[each_lcd_display.unique_id][i] = each_lcd_display.line_3_max_age self.lcd_decimal_places[each_lcd_display.unique_id][i] = each_lcd_display.line_3_decimal_places elif i == 4: self.lcd_text[each_lcd_display.unique_id][i] = each_lcd_display.line_4_text self.lcd_max_age[each_lcd_display.unique_id][i] = each_lcd_display.line_4_max_age self.lcd_decimal_places[each_lcd_display.unique_id][i] = each_lcd_display.line_4_decimal_places elif i == 5: self.lcd_text[each_lcd_display.unique_id][i] = each_lcd_display.line_5_text self.lcd_max_age[each_lcd_display.unique_id][i] = each_lcd_display.line_5_max_age self.lcd_decimal_places[each_lcd_display.unique_id][i] = each_lcd_display.line_5_decimal_places elif i == 6: self.lcd_text[each_lcd_display.unique_id][i] = each_lcd_display.line_6_text self.lcd_max_age[each_lcd_display.unique_id][i] = each_lcd_display.line_6_max_age self.lcd_decimal_places[each_lcd_display.unique_id][i] = each_lcd_display.line_6_decimal_places elif i == 7: self.lcd_text[each_lcd_display.unique_id][i] = each_lcd_display.line_7_text self.lcd_max_age[each_lcd_display.unique_id][i] = each_lcd_display.line_7_max_age self.lcd_decimal_places[each_lcd_display.unique_id][i] = each_lcd_display.line_7_decimal_places elif i == 8: self.lcd_text[each_lcd_display.unique_id][i] = each_lcd_display.line_8_text self.lcd_max_age[each_lcd_display.unique_id][i] = each_lcd_display.line_8_max_age self.lcd_decimal_places[each_lcd_display.unique_id][i] = each_lcd_display.line_8_decimal_places if self.lcd_y_lines in [2, 4, 8]: self.setup_lcd_line( each_lcd_display.unique_id, 1, each_lcd_display.line_1_id, each_lcd_display.line_1_measurement) self.setup_lcd_line( each_lcd_display.unique_id, 2, each_lcd_display.line_2_id, each_lcd_display.line_2_measurement) if self.lcd_y_lines in [4, 8]: self.setup_lcd_line( each_lcd_display.unique_id, 3, each_lcd_display.line_3_id, each_lcd_display.line_3_measurement) self.setup_lcd_line( each_lcd_display.unique_id, 4, each_lcd_display.line_4_id, each_lcd_display.line_4_measurement) if self.lcd_y_lines == 8: self.setup_lcd_line( each_lcd_display.unique_id, 5, each_lcd_display.line_5_id, each_lcd_display.line_5_measurement) self.setup_lcd_line( each_lcd_display.unique_id, 6, each_lcd_display.line_6_id, each_lcd_display.line_6_measurement) self.setup_lcd_line( each_lcd_display.unique_id, 7, each_lcd_display.line_7_id, each_lcd_display.line_7_measurement) self.setup_lcd_line( each_lcd_display.unique_id, 8, each_lcd_display.line_8_id, each_lcd_display.line_8_measurement) if self.lcd_type in ['16x2_generic', '20x4_generic']: from mycodo.devices.lcd_generic import LCD_Generic self.lcd_out = LCD_Generic(lcd_dev) self.lcd_init() elif self.lcd_type in ['16x2_grove_lcd_rgb']: from mycodo.devices.lcd_grove_lcd_rgb import LCD_Grove_LCD_RGB self.lcd_out = LCD_Grove_LCD_RGB(lcd_dev) self.lcd_init() elif self.lcd_type in ['128x32_pioled', '128x64_pioled']: from mycodo.devices.lcd_pioled import LCD_Pioled self.lcd_out = LCD_Pioled(lcd_dev) self.lcd_init() elif self.lcd_type in ['128x32_pioled_circuit_python', '128x64_pioled_circuit_python']: from mycodo.devices.lcd_pioled_circuitpython import LCD_Pioled_Circuitpython self.lcd_out = LCD_Pioled_Circuitpython(lcd_dev) self.lcd_init() else: self.logger.error("Unknown LCD type: {}".format(self.lcd_type)) if self.lcd_initialized: line_1 = 'Mycodo {}'.format(MYCODO_VERSION) line_2 = 'Start {}'.format(self.lcd_name) self.lcd_out.lcd_write_lines(line_1, line_2, '', '')