From 97da47dc2c84e63324bc851b73b237d3a2f79935 Mon Sep 17 00:00:00 2001 From: "Justin D. Harris" Date: Sun, 7 Jun 2020 18:29:27 -0400 Subject: [PATCH] server: Add ability to customize controller type and port with args. (#18) Bump to version 0.3.0 Server * Add port, controller type, and log level args. * Allow log level to easily be changed. * Install joycontrol. Client * Add link to hosted client. --- README.md | 4 ++-- server/README.md | 19 ++++++++++++--- server/setup.py | 4 ++-- server/switchremoteplay/controller.py | 11 +++++---- server/switchremoteplay/server.py | 33 +++++++++++++++++---------- website-client/package.json | 2 +- 6 files changed, 48 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 2e98500..1573bda 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,8 @@ This is very much a work in progress right now but you can indeed play your Swit # Requirements The host (person setting this up) needs: * A Nintendo Switch -* **Linux** machine to host the service and connect via Bluetooth to the Switch (tested with a Raspberry Pi 4B) (a Linux machine is required by the code that actually connects to the Switch via Bluetooth: [joycontrol][joycontrol]) -* (optional) video capture card to see the video (or just have bad quality and lag by pointing your camera at your Switch and use a video chat app) +* A **Linux** machine to host the service and connect via Bluetooth to the Switch (tested with a Raspberry Pi 4B) (a Linux machine is required by the code that actually connects to the Switch via Bluetooth: [joycontrol][joycontrol]) +* (optional) A video capture card to see the video (or just have bad quality and lag by pointing your camera at your Switch and use a video chat app) The client (your friend) needs: * A web browser to open the client and send commands diff --git a/server/README.md b/server/README.md index 8c18a35..e0767a5 100644 --- a/server/README.md +++ b/server/README.md @@ -1,7 +1,13 @@ # Server # Setup -Follow the setup instructions for [joycontrol][joycontrol]. +This code relies a lot on [joycontrol][joycontrol] for sending commands via Bluetooth to your Switch. +For information and troubleshooting on pairing controllers: see [joycontrol][joycontrol]. + +Install dependencies required by [joycontrol][joycontrol]: +```bash +sudo apt install python3-dbus libhidapi-hidraw0 +``` For this code, in this server folder: @@ -13,9 +19,16 @@ sudo pip3 install -e . # Start ```bash -# Append '-r ' to reconnect to an already paired Switch. -SECRET_KEY='something random-ish' PYTHONPATH=".:${PYTHONPATH}" sudo python3 switchremoteplay/server.py +sudo SECRET_KEY='something random-ish' python3 switchremoteplay/server.py ``` +Append `-r ` to reconnect to an already paired Switch. For example `-r 6E:A3:63:B9:CE:92`. + +To see more configuration options, run: +```bash +sudo python3 switchremoteplay/server.py --help +``` + +You can change the controller type, the port used by the socket service, and the log level. # API The service uses a socket to connect to the client. diff --git a/server/setup.py b/server/setup.py index 6374022..8761b96 100644 --- a/server/setup.py +++ b/server/setup.py @@ -4,7 +4,7 @@ install_requires = [ 'eventlet', - # 'joycontrol @ git+ssh://git@github.com/juharris/joycontrol.git@e90499393be4d829015785f7949566d6dc1561ba', + 'joycontrol @ git+https://git@github.com/mart1nro/joycontrol.git@721646a7ec10231490bcf788b3bdde10d8c2007f', 'flask-socketio', ] @@ -14,7 +14,7 @@ setup( name='switch-remoteplay-server', - version='0.2.0', + version='0.3.0', packages=find_packages(), url='https://github.com/juharris/switch-remoteplay', license='MIT', diff --git a/server/switchremoteplay/controller.py b/server/switchremoteplay/controller.py index c4c94e7..95bafc5 100644 --- a/server/switchremoteplay/controller.py +++ b/server/switchremoteplay/controller.py @@ -10,19 +10,19 @@ class SwitchController(): - configured_log = False - def __init__(self, logger: Logger, controller_state: ControllerState): self._controller_state: ControllerState = controller_state self._logger = logger + @staticmethod + def configure_log(level): + log.configure(level, level) + @staticmethod async def get_controller(logger: Logger, switch_mac_address=None, spi_flash=None, controller='PRO_CONTROLLER', capture_file=None, device_id=None): - if not SwitchController.configured_log: - log.configure(logger.level, logger.level) - SwitchController.configured_log = True + logger.info("Simulating a %s controller.", controller) if spi_flash: with open(spi_flash, 'rb') as spi_flash_file: spi_flash = FlashMemory(spi_flash_file.read()) @@ -52,6 +52,7 @@ async def get_controller(logger: Logger, switch_mac_address=None, spi_flash=None "Will try again in %ds.", wait_s) await asyncio.sleep(wait_s) + logger.info("Simulated %s paired.", controller.name) return SwitchController(logger, controller_state) def __del__(self): diff --git a/server/switchremoteplay/server.py b/server/switchremoteplay/server.py index db8a6e7..b721a66 100644 --- a/server/switchremoteplay/server.py +++ b/server/switchremoteplay/server.py @@ -52,35 +52,45 @@ def handle_press(command): async def _main(): - logger.info("Starting") parser = argparse.ArgumentParser() parser.add_argument('-r', '--switch_mac_address', type=str, default=None, help="The Switch console's MAC address. Specify this if you've already paired a Switch console to your server device.") + parser.add_argument('-c', '--controller_type', type=str, default="PRO_CONTROLLER", + help="The type of controller to simulate. Either PRO_CONTROLLER, JOYCON_L, or JOYCON_R. Default: PRO_CONTROLLER.") + parser.add_argument('--service_port', type=int, default=5000, + help="The port that the socket service should use for connections.\n Default: 5000.") + + parser.add_argument('--log_level', type=str, default=logging.INFO, + help="The log level. Options are Python log level names. Default: INFO.") args = parser.parse_args() + + logger.setLevel(args.log_level) + SwitchController.configure_log(logger.level) + + logger.info("Starting") switch_mac_address = args.switch_mac_address + controller_type = args.controller_type + port = args.service_port global controller try: - start_server() - controller = await SwitchController.get_controller(logger, switch_mac_address) + start_server(port) # Keep the server running and attempt to reconnect the controller. # There must be a better way to do this but this seems to work fine for now. while True: - if not controller.is_connected(): - logger.info("Attempting to reconnect the controller.") - controller = await SwitchController.get_controller(logger, switch_mac_address) + if controller is None or not controller.is_connected(): + logger.info("Attempting to connect the controller.") + controller = await SwitchController.get_controller(logger, switch_mac_address, + controller=controller_type) await asyncio.sleep(10) finally: logger.info('Stopping the service...') -def start_server(): +def start_server(port): host = '0.0.0.0' - # 5000 is the default port. - port = 5000 - # port = 48668 - logger.info("Socket service running at {}:{}".format(host, port)) + logger.info("Socket service running at %s:%d", host, port) l = asyncio.get_running_loop() @@ -92,7 +102,6 @@ def _start(): if __name__ == '__main__': - logger.setLevel(logging.INFO) loop = asyncio.get_event_loop() loop.run_until_complete( _main() diff --git a/website-client/package.json b/website-client/package.json index 78492a8..74dbdfc 100644 --- a/website-client/package.json +++ b/website-client/package.json @@ -1,6 +1,6 @@ { "name": "switch-rp-client", - "version": "0.1.0", + "version": "0.3.0", "private": true, "dependencies": { "@material-ui/core": "^4.10.0",