RASCSI/python/ctrlboard/src/main.py

198 lines
6.3 KiB
Python

"""Module is the entry point for the PiSCSI 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 piscsi.exceptions import (
EmptySocketChunkException,
InvalidProtobufResponse,
FailedSocketConnectionException,
)
from piscsi.piscsi_cmds import PiscsiCmds
from piscsi.socket_cmds import SocketCmds
from piscsi_menu_controller import PiscsiMenuController
def parse_config():
"""Parses the command line parameters and configured the PiSCSI Control Board UI accordingly"""
config = CtrlboardConfig()
cmdline_args_parser = argparse.ArgumentParser(description="PiSCSI 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(
"--piscsi-host",
type=str,
default="localhost",
action="store",
help="PiSCSI host. Default: localhost",
)
cmdline_args_parser.add_argument(
"--piscsi-port",
type=int,
default=6868,
action="store",
help="PiSCSI port. Default: 6868",
)
cmdline_args_parser.add_argument(
"--password",
type=str,
default="",
action="store",
help="Token password string for authenticating with PiSCSI",
)
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.PISCSI_HOST = args.piscsi_host
config.PISCSI_PORT = args.piscsi_port
config.LOG_LEVEL = args.loglevel
config.TRANSITIONS = bool(args.transitions)
return config
def check_piscsi_connection(piscsi_cmd):
"""Checks whether a PiSCSI connection exists by polling the PiSCSI server info.
Returns true if connection works, false if connection fails."""
try:
info = piscsi_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 PiSCSI 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("PiSCSI 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 piscsi ctrlboard hardware.
# Oled only will be supported as well at some later point in time.
if ctrlboard_hw.piscsi_controlboard_detected is False:
log.error("Ctrlboard hardware not detected. Stopping service")
exit(1)
sock_cmd = None
piscsi_cmd = None
try:
sock_cmd = SocketCmds(host=config.PISCSI_HOST, port=config.PISCSI_PORT)
piscsi_cmd = PiscsiCmds(sock_cmd=sock_cmd, token=config.TOKEN)
except EmptySocketChunkException:
log.error("Retrieved empty data from PiSCSI. Stopping service")
exit(1)
except InvalidProtobufResponse:
log.error("Retrieved unexpected data from PiSCSI. Stopping service")
exit(1)
if check_piscsi_connection(piscsi_cmd) is False:
log.error(
"Communication with PiSCSI 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(piscsi_cmd)
menu_controller = PiscsiMenuController(
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("resources/splash_start_64.bmp")
menu_update_event_handler = CtrlBoardMenuUpdateEventHandler(
menu_controller, sock_cmd=sock_cmd, piscsi_cmd=piscsi_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()