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 LCDController(threading.Thread): """ Class to operate LCD controller """ 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)) def run(self): try: self.running = True self.logger.info("Activated in {:.1f} ms".format( (timeit.default_timer() - self.thread_startup_timer) * 1000)) self.ready.set() while self.running: 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 time.sleep(1) except Exception as except_msg: self.logger.exception("Exception: {err}".format(err=except_msg)) finally: 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, '', '') self.logger.info("Deactivated in {:.1f} ms".format( (timeit.default_timer() - self.thread_shutdown_timer) * 1000)) self.running = False 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'] == 'BLANK': 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': 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': 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': last_measurement = read_last_influxdb( self.lcd_line[display_id][i]['id'], '/.*/', None, 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]['measure'], self.lcd_line[display_id][i]['channel'], 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']: unit_length = len( self.lcd_line[display_id][i]['unit'].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=self.lcd_line[display_id][i]['unit'].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', '16x2_generic', '20x4_generic']: self.lcd_out.lcd_write_lines(line_1, line_2, line_3, line_4) elif self.lcd_type == '128x64_pioled': 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) @staticmethod def output_state(output_id): output = db_retrieve_table_daemon(Output, unique_id=output_id) GPIO.setmode(GPIO.BCM) if GPIO.input(output.pin) == output.on_state: gpio_state = 'On' else: gpio_state = 'Off' return gpio_state 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']: 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']: 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', '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_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.lcd_id) else: self.flash_lcd_on = False self.lcd_backlight(True) return 1, "LCD {} Reset".format(self.lcd_id) def is_running(self): """ returns if the controller is running """ return self.running def stop_controller(self): """ Stops the controller """ self.thread_shutdown_timer = timeit.default_timer() self.running = False
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', '16x4_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))
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, '', '')
class LCDController(threading.Thread): """ Class to operate LCD controller """ 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', '16x4_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)) def run(self): try: self.running = True self.logger.info("Activated in {:.1f} ms".format( (timeit.default_timer() - self.thread_startup_timer) * 1000)) self.ready.set() while self.running: 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 time.sleep(1) except Exception as except_msg: self.logger.exception("Exception: {err}".format(err=except_msg)) finally: 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, '', '') self.logger.info("Deactivated in {:.1f} ms".format( (timeit.default_timer() - self.thread_shutdown_timer) * 1000)) self.running = False 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'] == 'BLANK': 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': 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': 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': last_measurement = read_last_influxdb( self.lcd_line[display_id][i]['id'], '/.*/', None, 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]['measure'], self.lcd_line[display_id][i]['channel'], 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']: unit_length = len(self.lcd_line[display_id][i]['unit'].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=self.lcd_line[display_id][i]['unit'].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', '16x2_generic', '16x4_generic']: self.lcd_out.lcd_write_lines(line_1, line_2, line_3, line_4) elif self.lcd_type == '128x64_pioled': 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) @staticmethod def output_state(output_id): output = db_retrieve_table_daemon(Output, unique_id=output_id) GPIO.setmode(GPIO.BCM) if GPIO.input(output.pin) == output.trigger: gpio_state = 'On' else: gpio_state = 'Off' return gpio_state 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']: 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']: 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', '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_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.lcd_id) else: self.flash_lcd_on = False self.lcd_backlight(True) return 1, "LCD {} Reset".format(self.lcd_id) def is_running(self): """ returns if the controller is running """ return self.running def stop_controller(self): """ Stops the controller """ self.thread_shutdown_timer = timeit.default_timer() self.running = False