def main(): fia = FIA("/dev/ttyAMA1", (3, 0), width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT) renderer = LayoutRenderer("fonts") with open("layouts/departures_5x2_single.json", 'r', encoding='utf-8') as f: layout = json.load(f) with open("wr_test_extra.json", 'r') as f: wr_data = json.load(f) for train_number, train_data in wr_data['train'].items(): data = train_data['wagenreihung'] order_sections, order_coaches = get_coach_order_strings(data) data = { 'placeholders': { 'order_sections': "\x25\x26\x27\x28\x29\x2a" if order_sections else None, 'order_coaches': order_coaches, } } img = renderer.render(layout, data) fia.send_image(img) print("Train: {}".format(train_number)) input("Enter for next train")
def main(): parser = argparse.ArgumentParser() parser.add_argument("-d", "--delete", action='store_true', required=False, help="Delete entity in Home Assistant") args = parser.parse_args() fia = FIA("/dev/ttyAMA1", (3, 0), width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT) while True: try: client = mqtt.Client(client_id="funkwerk-fia") client.on_log = on_log client.on_message = lambda *args, **kwargs: on_message( fia, *args, **kwargs) client.username_pw_set(username=MQTT_USER, password=MQTT_PASSWORD) client.connect(MQTT_BROKER, 1883, 60) client.publish(STATE_TOPIC, "ON" if fia.get_backlight_state() else "OFF") client.subscribe(COMMAND_TOPIC) client.loop_start() except KeyboardInterrupt: return except: try: client.loop_stop() except: traceback.print_exc() traceback.print_exc() time.sleep(5) else: break if args.delete: print("Deleting entity") client.publish(DISCOVERY_TOPIC, "") return while True: try: loop(client) except KeyboardInterrupt: return except: traceback.print_exc() time.sleep(5) client.connect(MQTT_BROKER, 1883, 60)
def main(): parser = argparse.ArgumentParser(add_help=False) parser.add_argument('--output', '-o', required=False, type=str) parser.add_argument('--layout', '-l', required=True, type=str) parser.add_argument('--font-dir', '-fd', required=True, type=str) parser.add_argument('--data', '-d', action='append', nargs=2, metavar=("key", "value")) parser.add_argument('--emulate', '-e', action='store_true', help="Run in emulation mode") parser.add_argument('--render-boxes', '-rb', action='store_true', help="Render the bounding boxes of the windows") parser.add_argument('--dont-render-content', '-drc', action='store_true', help="Don't render the content of the windows") args = parser.parse_args() with open(args.layout, 'r', encoding='utf-8') as f: layout = json.load(f) data = {'placeholders': dict(args.data) if args.data is not None else {}} if args.output: renderer = LayoutRenderer(args.font_dir) img = renderer.render(layout, data, render_boxes=args.render_boxes, render_content=not args.dont_render_content) img.save(args.output) else: if args.emulate: fia = FIAEmulator(width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT) else: fia = FIA("/dev/ttyAMA1", (3, 0), width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT) renderer = LayoutRenderer(args.font_dir, fia) renderer.display(layout, data, render_boxes=args.render_boxes, render_content=not args.dont_render_content)
def main(): fia = FIA("/dev/ttyAMA1", (3, 0), width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT) renderer = LayoutRenderer("fonts") with open("layouts/temp_monitor_5x2.json", 'r', encoding='utf-8') as f: layout = json.load(f) while True: try: temps = fia.get_temperatures() humidity = fia.get_humidity() backlight_state = fia.get_backlight_state() bl_base_brightness_a, bl_base_brightness_b = fia.get_backlight_base_brightness( ) bl_cur_brightness_a, bl_cur_brightness_b = fia.get_backlight_brightness( ) env_brightness_a, env_brightness_b = fia.get_env_brightness() door_states = fia.get_door_states() heaters_state = fia.get_heaters_state() circ_fans_state = fia.get_circulation_fans_state() heat_exc_fan_state = fia.get_heat_exchanger_fan_state() bl_ballast_fans_state = fia.get_backlight_ballast_fans_state() data = { 'placeholders': { 'temp_ballasts': "{:.1f}".format(temps[0]), 'temp_airflow': "{:.1f}".format(temps[1]), 'temp_board': "{:.1f}".format(temps[2]), 'temp_mcu': "{:.1f}".format(temps[3]), 'humidity': "{:.1f}".format(humidity), 'backlight_state': POWER_STATES[backlight_state], 'backlight_base_brt_a': str(bl_base_brightness_a), 'backlight_base_brt_b': str(bl_base_brightness_b), 'backlight_cur_brt_a': str(bl_cur_brightness_a), 'backlight_cur_brt_b': str(bl_cur_brightness_b), 'env_brt_a': str(env_brightness_a), 'env_brt_b': str(env_brightness_b), 'door_state_a': DOOR_STATES[door_states & 1 != 0], 'door_state_b': DOOR_STATES[door_states & 2 != 0], 'heaters_state': MULTI_POWER_STATES[heaters_state], 'circ_fans_state': MULTI_POWER_STATES[circ_fans_state], 'heat_exc_fan_state': POWER_STATES[heat_exc_fan_state], 'bl_ballast_fans_state': POWER_STATES[bl_ballast_fans_state], } } img = renderer.render(layout, data) fia.send_image(img) time.sleep(1) except KeyboardInterrupt: break except: traceback.print_exc() time.sleep(1)
def main(): parser = argparse.ArgumentParser(add_help=False) parser.add_argument('--layout-single', '-ls', required=False, type=str) parser.add_argument('--layout-double', '-ld', required=False, type=str) parser.add_argument('--layout-list', '-ll', required=False, type=str) parser.add_argument('--font-dir', '-fd', required=True, type=str) parser.add_argument('--station', '-s', required=True, type=str) parser.add_argument('--train-types', '-tt', required=False, type=str) parser.add_argument('--platform', '-p', required=False, type=str, default="all") parser.add_argument('--replacement-map', '-rm', required=False, type=str) parser.add_argument('--emulate', '-e', action='store_true', help="Run in emulation mode") parser.add_argument('--dbi-host', required=False, type=str, default="dbf.finalrewind.org") parser.add_argument('--mode', '-t', choices=('detail', 'list'), default='list', type=str) args = parser.parse_args() if args.emulate: fia = FIAEmulator(width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT) else: fia = FIA("/dev/ttyAMA1", (3, 0), width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT) if BL_AUX_IN_1_ENABLED: time.sleep(3) gpio.setmode(gpio.BCM) gpio.setup(FIA.PIN_CTRL_AUX1_OUT, gpio.IN) gpio.add_event_detect( FIA.PIN_CTRL_AUX1_OUT, gpio.RISING, callback=lambda pin: on_bl_button_pressed(pin, fia)) fia.set_backlight_state(0) renderer = LayoutRenderer(args.font_dir, fia=fia) dbi = DBInfoscreen(args.dbi_host) ds100 = DS100() if args.train_types: train_types = args.train_types.split(",") else: train_types = [] if args.replacement_map: with open(args.replacement_map, 'r') as f: replacement_map = json.load(f) else: replacement_map = None if args.mode == 'detail': if args.layout_single: with open(args.layout_single, 'r', encoding='utf-8') as f: layout_single = json.load(f) else: print("Missing --layout-single. Aborting.") return if args.layout_double: with open(args.layout_double, 'r', encoding='utf-8') as f: layout_double = json.load(f) else: layout_double = layout_single config = { 'mode': 'detail', 'station': args.station, 'train_types': args.train_types, 'platform': args.platform, 'layout_single': layout_single, 'layout_double': layout_double, 'layout_list': None, 'replacement_map': replacement_map, 'duration': 30 } elif args.mode == 'list': if args.layout_list: with open(args.layout_list, 'r', encoding='utf-8') as f: layout_list = json.load(f) else: print("Missing --layout-list. Aborting.") return config = { 'mode': 'list', 'station': args.station, 'train_types': args.train_types, 'platform': args.platform, 'layout_single': None, 'layout_double': None, 'layout_list': layout_list, 'replacement_map': replacement_map, 'duration': 30 } while True: try: show_departures(dbi, ds100, fia, renderer, config) except KeyboardInterrupt: renderer.free_scroll_buffers() fia.exit() break except: traceback.print_exc() time.sleep(10)
def main(): parser = argparse.ArgumentParser() parser.add_argument('-i', '--image', type=str, required=True, help="The image to convert") parser.add_argument( '-o', '--output', type=str, required=False, help="The name of the output file. Default: same as image filename") parser.add_argument( '-n', '--name', type=str, required=False, help= "The name of the image buffer in the generated C file. Default: <image_filename> with only ASCII characters" ) args = parser.parse_args() input_basename = os.path.splitext(os.path.basename(args.image))[0] if args.output: output_name = args.output else: output_name = input_basename header_name = output_name + ".h" source_name = output_name + ".c" allowed_characters = list(map(chr, range(ord('0'), ord('9') + 1))) allowed_characters += list(map(chr, range(ord('a'), ord('z') + 1))) allowed_characters += list(map(chr, range(ord('A'), ord('Z') + 1))) allowed_characters += ["_"] if args.name: buffer_name = ''.join( [i if i in allowed_characters else '_' for i in args.name]) else: buffer_name = ''.join( [i if i in allowed_characters else '_' for i in input_basename]) fia = FIA("/dev/ttyAMA1", (3, 0), width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT) img = Image.open(args.image).convert('L') array, width, height = fia.img_to_array(img) buffer_size = len(array) buffer_data = "" num_cols = math.ceil(height / 8) for i in range(0, buffer_size, num_cols): buffer_data += " " buffer_data += ", ".join( [f"0x{byte:02x}" for byte in array[i:i + num_cols]]) if i + num_cols < buffer_size: buffer_data += ",\n" buffer_size_def_name = buffer_name.upper() + "_SIZE" header_template = f"""#pragma once\n\n#include <stdint.h>\n\n#define {buffer_size_def_name} {buffer_size}\nconst uint8_t {buffer_name}[{buffer_size_def_name}];\n""" source_template = f"""#include "{header_name}"\n\nconst uint8_t {buffer_name}[{buffer_size_def_name}] = {{\n{buffer_data}\n}};\n""" with open(header_name, 'w') as f: f.write(header_template) with open(source_name, 'w') as f: f.write(source_template)
import time from PIL import Image from fia_control import FIA from local_settings import * fia = FIA("/dev/ttyAMA1", (3, 0), width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT) white = Image.new('L', (DISPLAY_WIDTH, DISPLAY_HEIGHT), 'white') black = Image.new('L', (DISPLAY_WIDTH, DISPLAY_HEIGHT), 'black')
import time from fia_control import FIA from local_settings import * fia = FIA("/dev/ttyAMA1", (3, 0), width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT) env_brt_a, env_brt_b = fia.get_env_brightness() bl_brt_a, bl_brt_b = fia.get_backlight_brightness() bl_base_brt_a, bl_base_brt_b = fia.get_backlight_base_brightness() bl_state = fia.get_backlight_state() bl_temp, air_temp, board_temp, mcu_temp = fia.get_temperatures() hum = fia.get_humidity() bl_fan = fia.get_backlight_ballast_fans_state() circ_fan = fia.get_circulation_fans_state() exch_fan = fia.get_heat_exchanger_fan_state() heaters = fia.get_heaters_state() doors = fia.get_door_states() contrast_a, contrast_b = fia.get_lcd_contrast() values = ",".join( map(str, (env_brt_a, env_brt_b, bl_brt_a, bl_brt_b, bl_base_brt_a, bl_base_brt_b, bl_state, bl_temp, air_temp, board_temp, mcu_temp, hum, bl_fan, circ_fan, exch_fan, heaters, doors, contrast_a, contrast_b))) with open("env_log.csv", 'a') as f: f.write(f"{time.time():.0f},{values}\n")
def main(): parser = argparse.ArgumentParser( description= "This script can show an image or animation on the display.", add_help=False) parser.add_argument('--file', '-f', required=True, type=str, help="Input file to display (static image or GIF)") parser.add_argument('--width', '-w', required=False, default=None, type=pos_nonzero_int, help="Width to crop input to") parser.add_argument('--height', '-h', required=False, default=None, type=pos_nonzero_int, help="Height to crop input to") parser.add_argument( '--interval', '-i', required=False, default=None, type=pos_nonzero_int, help= "Interval between frames in ms (defaults to GIF's setting or one second)" ) parser.add_argument( '--countdown', '-c', action='store_true', help= "If set, do an interactive countdown before starting to help with manually syncing video and audio" ) parser.add_argument( '--loop-count', '-lc', required=False, default=1, type=pos_nonzero_int_or_neg1, help= "Number of loops to run. Defaults to 1. Positive integer or -1 for infinite loop." ) parser.add_argument('--emulate', '-e', action='store_true', help="Run in emulation mode") parser.add_argument('--help', action='help', help="Display this help message") args = parser.parse_args() if args.emulate: fia = FIAEmulator(width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT) else: fia = FIA("/dev/ttyAMA1", (3, 0), width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT) try: display_image(fia, args.file, width=args.width, height=args.height, interval=args.interval, countdown=args.countdown, loop_count=args.loop_count, output=True) except KeyboardInterrupt: print("") fia.exit()
def main(): parser = argparse.ArgumentParser(add_help=False) parser.add_argument('--font-dir', '-fd', required=True, type=str) parser.add_argument('--station', '-s', required=True, type=str) parser.add_argument('--platforms', '-p', required=True, type=str, help="Example string: 1a,1-24,101-104") args = parser.parse_args() platforms = [] raw_platform_list_parts = args.platforms.split(",") for part in raw_platform_list_parts: if "-" in part: p_min, p_max = map(int, part.split("-")) platforms += map(str, range(p_min, p_max + 1)) else: platforms.append(part) fia = FIA("/dev/ttyAMA1", (3, 0), width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT) renderer = LayoutRenderer(args.font_dir) dbi = DBInfoscreen("dbf.finalrewind.org") platform_layout = [{ 'name': "platform_0", 'type': 'text', 'x': 1, 'y': 0, 'width': 19, 'height': 9, 'pad_left': 0, 'pad_top': 0, 'inverted': False, 'font': "7_DBLCD", 'size': 0, 'align': 'right', 'spacing': 1 }, { 'name': "departure_0", 'type': 'text', 'x': 25, 'y': 0, 'width': 30, 'height': 9, 'pad_left': 0, 'pad_top': 0, 'inverted': False, 'font': "7_DBLCD", 'size': 0, 'align': 'left', 'spacing': 1 }, { 'name': "train_0", 'type': 'text', 'x': 59, 'y': 0, 'width': 43, 'height': 9, 'pad_left': 0, 'pad_top': 0, 'inverted': False, 'font': "7_DBLCD", 'size': 0, 'align': 'left', 'spacing': 1 }, { 'name': "destination_0", 'type': 'text', 'x': 106, 'y': 0, 'width': 132, 'height': 9, 'pad_left': 0, 'pad_top': 0, 'inverted': False, 'font': "7_DBLCD", 'size': 0, 'align': 'left', 'spacing': 1 }] layout = { 'width': 480, 'height': 128, 'placeholders': [{ 'name': "divider_1", 'type': 'line', 'x': 22, 'y': 0, 'x2': 22, 'y2': 127, 'inverted': False, 'line_width': 1 }, { 'name': "divider_2", 'type': 'line', 'x': 56, 'y': 0, 'x2': 56, 'y2': 127, 'inverted': False, 'line_width': 1 }, { 'name': "divider_3", 'type': 'line', 'x': 239, 'y': 0, 'x2': 239, 'y2': 127, 'inverted': False, 'line_width': 2 }, { 'name': "divider_4", 'type': 'line', 'x': 263, 'y': 0, 'x2': 263, 'y2': 127, 'inverted': False, 'line_width': 1 }, { 'name': "divider_5", 'type': 'line', 'x': 297, 'y': 0, 'x2': 297, 'y2': 127, 'inverted': False, 'line_width': 1 }] } data = {'placeholders': {}} while True: try: station_code = args.station trains = dbi.calc_real_times(dbi.get_trains(args.station)) trains = filter(lambda t: t['actualDeparture'] is not None, trains) trains = filter(lambda t: not t['train'].startswith("Bus SEV"), trains) trains = list(trains) trains = sorted(trains, key=dbi.time_sort) x, y = 0, 0 for i, platform in enumerate(platforms): placeholders = [p.copy() for p in platform_layout] placeholders[0]['name'] = "platform_" + platform placeholders[1]['name'] = "departure_" + platform placeholders[2]['name'] = "train_" + platform placeholders[3]['name'] = "destination_" + platform placeholders[0]['y'] = placeholders[1]['y'] = placeholders[2][ 'y'] = placeholders[3]['y'] = y placeholders[0]['x'] += x placeholders[1]['x'] += x placeholders[2]['x'] += x placeholders[3]['x'] += x layout['placeholders'] += placeholders data['placeholders']['platform_' + platform] = platform p_trains = list( filter(lambda t: t['platform'] == platform, trains)) if p_trains: t = p_trains[0] data['placeholders']['departure_' + platform] = t['actualDeparture'] data['placeholders']['train_' + platform] = get_train_number( t['train']).replace(" ", "") data['placeholders']['destination_' + platform] = get_destination_name( t['destination']) y += 9 if 56 < y < 64: y = 64 if y > 120: y = 0 x += 241 img = renderer.render(layout, data) fia.send_image(img) time.sleep(30) except KeyboardInterrupt: break except: traceback.print_exc() time.sleep(10)
def main(): parser = argparse.ArgumentParser(add_help=False) parser.add_argument('--config', '-c', required=True, type=str) parser.add_argument('--font-dir', '-fd', required=True, type=str) parser.add_argument('-e', '--emulate', action='store_true', help="Run in emulation mode") args = parser.parse_args() if args.emulate: fia = FIAEmulator(width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT) else: fia = FIA("/dev/ttyAMA1", (3, 0), width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT) renderer = LayoutRenderer(args.font_dir, fia=fia) socket.setdefaulttimeout(10.0) auth = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET) auth.set_access_token(TWITTER_ACCESS_TOKEN, TWITTER_ACCESS_TOKEN_SECRET) twitter_api = tweepy.API(auth) mastodon = Mastodon(api_base_url=MASTODON_API_BASE_URL, client_id=MASTODON_CLIENT_ID, client_secret=MASTODON_CLIENT_SECRET, access_token=MASTODON_ACCESS_TOKEN) dbi = DBInfoscreen("dbf.finalrewind.org") ds100 = DS100() with open(args.config, 'r') as f: config = json.load(f) apps = config.get('apps', []) print("Starting") while True: for app in apps: try: app_type = app.get('type') app_config = app.get('config', {}) if app_type == 'static': static_app(fia, renderer, app_config) elif app_type == 'webserver': webserver_app(fia, renderer, app_config) elif app_type == 'twitter': twitter_app(twitter_api, fia, renderer, app_config) elif app_type == 'telegram': telegram_app(fia, renderer, app_config) elif app_type == 'mastodon': mastodon_app(mastodon, fia, renderer, app_config) elif app_type == 'weather': weather_app(fia, renderer, app_config) elif app_type == 'db_departures': show_departures(dbi, ds100, fia, renderer, app_config, auto_clear_scroll_buf=True) except KeyboardInterrupt: return except: traceback.print_exc() print("Continuing") time.sleep(1)
def main(): fia = FIA("/dev/ttyAMA1", (3, 0), width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT) fia.set_backlight_state(1) fia.set_heaters_state(0) fia.set_circulation_fans_state(2) fia.set_heat_exchanger_fan_state(1) fia.set_backlight_ballast_fans_state(1) fia.set_backlight_base_brightness(2048, 2048) fia.send_image(Image.new('L', (480, 128), 'white')) with open("temperatures.csv", 'a') as f: while True: temps = list(fia.get_temperatures()) humidity = fia.get_humidity() data = [time.time()] + temps + [humidity] print(data) f.write(",".join(map(str, data)) + "\n") time.sleep(5)