def initialize_variables(self): from mycodo.devices.lcd_generic import LCD_Generic 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, "i2c_address": self.i2c_address, "i2c_bus": self.i2c_bus, "x_characters": lcd_x_characters, "y_lines": lcd_lines } self.lcd = LCD_Generic(lcd_settings_dict=lcd_settings_dict) self.lcd.lcd_init() self.logger.debug("LCD Function started") except: self.logger.exception("Starting LCD Function")
def __init__(self, ready, lcd_id): threading.Thread.__init__(self) self.logger = logging.getLogger( "mycodo.lcd_{id}".format(id=lcd_id.split('-')[0])) self.running = False self.thread_startup_timer = timeit.default_timer() self.thread_shutdown_timer = 0 self.ready = ready self.flash_lcd_on = False self.lcd_initialized = False self.lcd_is_on = False self.lcd_id = lcd_id self.display_sets = [] self.display_set_count = 0 try: lcd_dev = db_retrieve_table_daemon(LCD, unique_id=self.lcd_id) self.lcd_type = lcd_dev.lcd_type self.lcd_name = lcd_dev.name self.lcd_i2c_address = int(lcd_dev.location, 16) self.lcd_i2c_bus = lcd_dev.i2c_bus 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.list_pids = ['setpoint', 'pid_time'] self.list_outputs = [ 'duration_time', 'output_time', 'output_state' ] # 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() self.lcd_string_line = {} self.lcd_line = {} self.lcd_max_age = {} self.lcd_decimal_places = {} 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_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_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_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_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_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_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_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_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_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 ['128x32_pioled', '128x64_pioled']: from mycodo.devices.lcd_pioled import LCD_Pioled self.lcd_out = LCD_Pioled(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, '', '') except Exception as except_msg: self.logger.exception("Error: {err}".format(err=except_msg))
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.lcd = None self.timer_loop = time.time() self.line_sets = [] self.current_line_set = 0 self.line_y_dimensions = [0, 8] self.pad = -2 # Initialize custom options self.period = None self.i2c_address = None self.i2c_bus = None self.number_line_sets = 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_generic import LCD_Generic 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, "i2c_address": self.i2c_address, "i2c_bus": self.i2c_bus, "x_characters": lcd_x_characters, "y_lines": lcd_lines } self.lcd = LCD_Generic(lcd_settings_dict=lcd_settings_dict) self.lcd.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.lcd: 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.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.lcd.lcd_init() self.lcd.lcd_write_lines( lines_display[0], lines_display[1], "", "") def stop_function(self): self.lcd.lcd_init() self.lcd.lcd_write_lines( "Mycodo {}".format(MYCODO_VERSION), "LCD Deactivated", "", "")
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, '', '')