コード例 #1
0
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")
コード例 #2
0
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)
コード例 #3
0
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)
コード例 #4
0
ファイル: status_monitor.py プロジェクト: Mezgrman/LCD-FIA
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)
コード例 #5
0
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)
コード例 #6
0
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)
コード例 #7
0
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')
コード例 #8
0
ファイル: log_env.py プロジェクト: Mezgrman/LCD-FIA
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")
コード例 #9
0
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()
コード例 #10
0
ファイル: db_platform_list.py プロジェクト: Mezgrman/LCD-FIA
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)
コード例 #11
0
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)
コード例 #12
0
ファイル: temperature_log.py プロジェクト: Mezgrman/LCD-FIA
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)