diff --git a/arduino/arduino_nRF52840/arduino_nRF52840.ino b/arduino/arduino_nRF52840/arduino_nRF52840.ino index c056a9d..14df390 100644 --- a/arduino/arduino_nRF52840/arduino_nRF52840.ino +++ b/arduino/arduino_nRF52840/arduino_nRF52840.ino @@ -859,26 +859,64 @@ void removeBleDevice(char *myLine) void switchBleConnection(char *myLine) { char buff[256]; + char tempBleDevName[32] = {0}; + + BLEConnection *connection = NULL; + connection = Bluefruit.Connection(target_ble_conn); at_response("at+switchconn\n"); - if (!Bluefruit.connected()) - { - switchBleConnStartIndex = 1; - //Serial.println("Current Dev Index: " + String(switchBleConnStartIndex)); - switchBleConnCurrIndex = 1; - flag_bleSwapConnProsStarted = 1; - swapConnProsStartTicks = millis(); - - snprintf(buff, sizeof(buff), "Trying to connect with - %s\n", bleDeviceNameList[switchBleConnCurrIndex - 1]); - at_response(buff); + if (!Bluefruit.connected()) { + at_response("ERROR: No device connected now\n"); + return; + } + + if (bleDeviceNameListIndex < 2) { + at_response("ERROR: No other device present in list\n"); + return; } - else - { - BLEConnection *connection = NULL; - char tempBleDevName[32] = {0}; - connection = Bluefruit.Connection(target_ble_conn); + Serial.print("Received line: "); // temp + Serial.println(myLine); // temp + + char * start_dev_p = strstr(myLine, "=\""); // search device argument + if (start_dev_p != NULL) { + // if device argument present, switch to next device + char * end_dev_p = strrchr(myLine, '\"'); + if(end_dev_p != NULL && end_dev_p != (start_dev_p+1)) { + start_dev_p += 2; // move pointer to start of device name + + if((end_dev_p-start_dev_p) <= 31) { + strncpy(tempBleDevName, start_dev_p, (end_dev_p-start_dev_p)); + } + } + + if(strlen(tempBleDevName) != 0) { + Serial.print("Device argument: "); // temp + Serial.println(tempBleDevName); // temp + + for (int i = 0; i < bleDeviceNameListIndex; i++) { + if (!strcmp((char *)tempBleDevName, (char *)bleDeviceNameList[i])) { + switchBleConnCurrIndex = i+1; + flag_bleSwapConnProsStarted = 1; + swapConnProsStartTicks = millis(); + + snprintf(buff, sizeof(buff), "Trying to connect with - %s\n", bleDeviceNameList[switchBleConnCurrIndex - 1]); + at_response(buff); + + connection->disconnect(); + + return; + } + } + at_response("ERROR: Device not found in list\n"); + return; + } else { + at_response("ERROR: Syntax\n"); + return; + } + } else { + // if no device argument, switch to next device connection->getPeerName(tempBleDevName, sizeof(tempBleDevName)); //Serial.println("Current Dev Name: " + String(tempBleDevName)); @@ -889,12 +927,6 @@ void switchBleConnection(char *myLine) { switchBleConnStartIndex = i + 1; //Serial.println("Current Dev Index: " + String(switchBleConnStartIndex)); - - if (bleDeviceNameListIndex == 1) - { - at_response("ERROR: No other device present in list\n"); - break; - } if (switchBleConnStartIndex >= bleDeviceNameListIndex) { @@ -917,6 +949,7 @@ void switchBleConnection(char *myLine) } } } + } void printBleDevList(char *myLine) @@ -1069,11 +1102,11 @@ void loop() if(!ble_mode) { if(Serial.available() > 0) { receive_char(0, Serial.read()); - } + } } - if(digitalRead(USER_SW) == false) { - if(detect_click() == 1){ + if(digitalRead(USER_SW) == false) { + if(detect_click() == 1){ addNewBleDevice(""); } else { change_mode(""); diff --git a/blehid.py b/blehid.py index afa0fb2..7a4f0c1 100644 --- a/blehid.py +++ b/blehid.py @@ -289,7 +289,9 @@ async def blehid_send_switch_command(ser, devicecommand): if devicecommand == 'switch': await _write_atcmd(ser, "AT+SWITCHCONN") await _read_response(ser) - + elif devicecommand.startswith("switch="): + await _write_atcmd(ser, "AT+SWITCHCONN=\"{}\"".format(devicecommand.split("=")[1])) + await _read_response(ser) async def blehid_send_get_device_name(ser, devicecommand): logging.debug('device command:'+str(devicecommand)) diff --git a/build.py b/build.py index 14e3725..1927cc7 100644 --- a/build.py +++ b/build.py @@ -43,6 +43,7 @@ def moveTree(sourceRoot, destRoot): ('relaykeysd.py', 'relaykeysd', True), ('relaykeysd-service.py', 'relaykeysd-service', True), ('relaykeysd-service-stop.py', 'relaykeysd-service-stop', True), + ('poll_devname.py', 'poll_devname', True), ('relaykeys-cli.py', 'relaykeys-cli', True), ('relaykeys-cli.py', 'relaykeys-cli-win', False), ('relaykeys-qt.py', 'relaykeys-qt', False)]: @@ -59,7 +60,7 @@ def moveTree(sourceRoot, destRoot): #os.system("md ./dist") # Do a pyinstaller on these files -for spec in ['relaykeysd.spec', 'relaykeys-cli.spec', 'relaykeys-cli-win.spec', 'relaykeys-qt.spec']: +for spec in ['relaykeysd.spec', 'relaykeys-cli.spec', 'poll_devname.spec', 'relaykeys-cli-win.spec', 'relaykeys-qt.spec']: subprocess.run(["pyinstaller", '-y', spec]) # remaining files that dont fit the standard spec @@ -80,7 +81,7 @@ def moveTree(sourceRoot, destRoot): # Merge all directories if os.name == 'nt': - for item in [r"dist\relaykeysd-service", r"dist\relaykeysd-service-stop", r"dist\relaykeys-cli", r"dist\relaykeys-cli-win", r"dist\relaykeys-qt"]: + for item in [r"dist\relaykeysd-service", r"dist\relaykeysd-service-stop", r"dist\relaykeys-cli", r"dist\poll_devname", r"dist\relaykeys-cli-win", r"dist\relaykeys-qt"]: moveTree(item, r'dist\relaykeysd') if os.name == 'posix': for item in [r"dist/relaykeys-cli", r"dist/relaykeys-cli-win", r"dist/relaykeys-qt"]: diff --git a/poll_devname.py b/poll_devname.py new file mode 100644 index 0000000..4506663 --- /dev/null +++ b/poll_devname.py @@ -0,0 +1,33 @@ +from time import sleep, time +from pathlib import Path +from notifypy import Notify + +from relaykeysclient import RelayKeysClient + +client = RelayKeysClient(url="http://127.0.0.1:5383/") + +def send_devname_notification(device_name): + notification = Notify() + notification.application_name = "Relaykeys" + notification.title = "" + notification.icon = str(Path(__file__).resolve().parent / "resources" / "logo.png") + notification.message = "Connected to {}.".format(device_name) + + notification.send() + +polling_start_timestamp = time() +timeout_sec = 40 + +while True: + if time() - polling_start_timestamp > timeout_sec: + break # timeout + + ret = client.ble_cmd("devname") + if 'result' in ret: + devname = ret["result"] + if devname != 'NONE': + send_devname_notification(devname) + break + + sleep(2) + diff --git a/relaykeys-cli.py b/relaykeys-cli.py index 26f3c61..e51cceb 100644 --- a/relaykeys-cli.py +++ b/relaykeys-cli.py @@ -5,6 +5,7 @@ import sys from pathlib import Path import json +import subprocess # util modules import logging @@ -82,6 +83,8 @@ def send_notification(command_type, command, result): notification.message = "Device list is cleared." elif command == "switch": notification.message = "Switching to next device." + elif command.startswith("switch="): + notification.message = "Trying to switch to \"{}\"".format(command.split("=")[1]) elif "devremove" in command: removed_device = command.split("=")[1] notification.message = "{} was removed from device list.".format(removed_device) @@ -195,6 +198,15 @@ def do_devicecommand(client, devcommand, notify=False,copyresults=False): logging.info("devicecommand ({}) response : {}".format(devcommand, ret["result"])) if notify: send_notification("device command", devcommand, ret["result"]) + if devcommand.startswith("switch"): + exe_path = Path(__file__).resolve().parent / "poll_devname.exe" + if exe_path.exists(): + # run exe if builded + subprocess.Popen([str(exe_path)]) + else: + # run script if no exe + script_path = Path(__file__).resolve().parent / "poll_devname.py" + subprocess.Popen(["python", str(script_path)]) if copyresults: copy_return("daemon command", devcommand, ret["result"]) diff --git a/relaykeysd.py b/relaykeysd.py index 2e5989e..d4a467a 100755 --- a/relaykeysd.py +++ b/relaykeysd.py @@ -567,7 +567,7 @@ async def process_action(ser, keys, cmd): elif cmd[0] == 'ble_cmd': - if cmd[1] == "switch": + if cmd[1] == "switch" or cmd[1].startswith("switch="): await blehid_send_switch_command(ser, cmd[1]) elif cmd[1] == "devname":