Skip to content

Commit

Permalink
server: Add ability to customize controller type and port with args. (#…
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
juharris authored Jun 7, 2020
1 parent 5c163bb commit 97da47d
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 25 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 16 additions & 3 deletions server/README.md
Original file line number Diff line number Diff line change
@@ -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:

Expand All @@ -13,9 +19,16 @@ sudo pip3 install -e .

# Start
```bash
# Append '-r <Switch MAC address>' 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 <Switch MAC address>` 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.
Expand Down
4 changes: 2 additions & 2 deletions server/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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',
]

Expand All @@ -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',
Expand Down
11 changes: 6 additions & 5 deletions server/switchremoteplay/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down Expand Up @@ -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):
Expand Down
33 changes: 21 additions & 12 deletions server/switchremoteplay/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand All @@ -92,7 +102,6 @@ def _start():


if __name__ == '__main__':
logger.setLevel(logging.INFO)
loop = asyncio.get_event_loop()
loop.run_until_complete(
_main()
Expand Down
2 changes: 1 addition & 1 deletion website-client/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down

0 comments on commit 97da47d

Please sign in to comment.