RASCSI/python/ctrlboard/src/main.py

198 lines
6.3 KiB
Python
Raw Normal View History

"""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()