RASCSI/python/ctrlboard/src/main.py

189 lines
6.6 KiB
Python
Raw Normal View History

"""Module is the entry point for the RaSCSI Control Board UI"""
import argparse
import sys
import logging
from config import CtrlboardConfig
from ctrlboard_hw.ctrlboard_hw import CtrlBoardHardware
from ctrlboard_hw.ctrlboard_hw_constants import CtrlBoardHardwareConstants
from ctrlboard_event_handler.ctrlboard_menu_update_event_handler \
import CtrlBoardMenuUpdateEventHandler
from ctrlboard_menu_builder import CtrlBoardMenuBuilder
from menu.menu_renderer_config import MenuRendererConfig
from menu.menu_renderer_luma_oled import MenuRendererLumaOled
from rascsi.exceptions import (EmptySocketChunkException,
InvalidProtobufResponse,
FailedSocketConnectionException)
from rascsi.ractl_cmds import RaCtlCmds
from rascsi.socket_cmds import SocketCmds
from rascsi_menu_controller import RascsiMenuController
def parse_config():
"""Parses the command line parameters and configured the RaSCSI Control Board UI accordingly"""
config = CtrlboardConfig()
cmdline_args_parser = argparse.ArgumentParser(description='RaSCSI ctrlboard service')
cmdline_args_parser.add_argument(
"--rotation",
type=int,
choices=[0, 90, 180, 270],
default=180,
action="store",
help="The rotation of the screen buffer in degrees. Default: 180",
)
cmdline_args_parser.add_argument(
"--height",
type=int,
choices=[64],
default=64,
action="store",
help="The pixel height of the screen buffer. Default: 64",
)
cmdline_args_parser.add_argument(
"--rascsi-host",
type=str,
default="localhost",
action="store",
help="RaSCSI host. Default: localhost",
)
cmdline_args_parser.add_argument(
"--rascsi-port",
type=int,
default=6868,
action="store",
help="RaSCSI port. Default: 6868",
)
cmdline_args_parser.add_argument(
"--password",
type=str,
default="",
action="store",
help="Token password string for authenticating with RaSCSI",
)
cmdline_args_parser.add_argument(
"--loglevel",
type=int,
choices=[0, 10, 30, 40, 50],
default=logging.WARN,
action="store",
help="Loglevel. Valid values: 0 (notset), 10 (debug), 30 (warning), "
"40 (error), 50 (critical). Default: Warning",
)
cmdline_args_parser.add_argument(
"--transitions",
type=int,
choices=[0, 1],
default=1,
action="store",
help="Transition animations. Valid values: 0 (disabled), 1 (enabled). Default: 1",
)
args = cmdline_args_parser.parse_args()
config.ROTATION = args.rotation
if args.height == 64:
config.HEIGHT = 64
config.LINES = 8
elif args.height == 32:
config.HEIGHT = 32
config.LINES = 4
config.TOKEN = args.password
config.WIDTH = 128
config.BORDER = 5
config.RASCSI_HOST = args.rascsi_host
config.RASCSI_PORT = args.rascsi_port
config.LOG_LEVEL = args.loglevel
config.TRANSITIONS = bool(args.transitions)
return config
def check_rascsi_connection(ractl_cmd):
"""Checks whether a RaSCSI connection exists by polling the RaSCSI server info.
Returns true if connection works, false if connection fails."""
try:
info = ractl_cmd.get_reserved_ids()
return bool(info["status"] is True)
except FailedSocketConnectionException:
log = logging.getLogger(__name__)
log.error("Could not establish connection. Stopping service")
exit(1)
def main():
"""Main function for the RaSCSI Control Board UI"""
config = parse_config()
log_format = "%(asctime)s:%(name)s:%(levelname)s - %(message)s"
logging.basicConfig(stream=sys.stdout,
format=log_format,
level=config.LOG_LEVEL)
log = logging.getLogger(__name__)
log.debug("RaSCSI ctrlboard service started.")
ctrlboard_hw = CtrlBoardHardware(display_i2c_address=config.DISPLAY_I2C_ADDRESS,
pca9554_i2c_address=config.PCA9554_I2C_ADDRESS)
# for now, we require the complete rascsi ctrlboard hardware.
# Oled only will be supported as well at some later point in time.
if ctrlboard_hw.rascsi_controlboard_detected is False:
log.error("Ctrlboard hardware not detected. Stopping service")
exit(1)
sock_cmd = None
ractl_cmd = None
try:
sock_cmd = SocketCmds(host=config.RASCSI_HOST, port=config.RASCSI_PORT)
ractl_cmd = RaCtlCmds(sock_cmd=sock_cmd, token=config.TOKEN)
except EmptySocketChunkException:
log.error("Retrieved empty data from RaSCSI. Stopping service")
exit(1)
except InvalidProtobufResponse:
log.error("Retrieved unexpected data from RaSCSI. Stopping service")
exit(1)
if check_rascsi_connection(ractl_cmd) is False:
log.error("Communication with RaSCSI failed. Please check if password token must be set "
"and whether is set correctly.")
exit(1)
menu_renderer_config = MenuRendererConfig()
if config.TRANSITIONS is False:
menu_renderer_config.transition = None
menu_renderer_config.i2c_address = CtrlBoardHardwareConstants.DISPLAY_I2C_ADDRESS
menu_renderer_config.rotation = config.ROTATION
menu_builder = CtrlBoardMenuBuilder(ractl_cmd)
menu_controller = RascsiMenuController(config.MENU_REFRESH_INTERVAL, menu_builder=menu_builder,
menu_renderer=MenuRendererLumaOled(menu_renderer_config),
menu_renderer_config=menu_renderer_config)
menu_controller.add(CtrlBoardMenuBuilder.SCSI_ID_MENU)
menu_controller.add(CtrlBoardMenuBuilder.ACTION_MENU)
menu_controller.show_splash_screen(f"resources/splash_start_64.bmp")
menu_update_event_handler = CtrlBoardMenuUpdateEventHandler(menu_controller,
sock_cmd=sock_cmd,
ractl_cmd=ractl_cmd)
ctrlboard_hw.attach(menu_update_event_handler)
menu_controller.set_active_menu(CtrlBoardMenuBuilder.SCSI_ID_MENU)
while True:
# pylint: disable=broad-except
try:
ctrlboard_hw.process_events()
menu_update_event_handler.update_events()
menu_controller.update()
except KeyboardInterrupt:
ctrlboard_hw.cleanup()
break
except Exception as ex:
print(ex)
if __name__ == '__main__':
main()