/ RNode_Firmware_CE_G2 / configure_wifi.py
configure_wifi.py
 1  #!/usr/bin/env python3
 2  """
 3  Configure WiFi on RNode devices with HAS_WIFI (e.g. Station G2).
 4  Sends KISS commands to set SSID, password, and enable STA mode.
 5  Usage: python3 configure_wifi.py /dev/ttyACM0 "MySSID" "MyPassword"
 6  """
 7  
 8  import sys
 9  import time
10  import serial
11  
12  FEND = 0xC0
13  FESC = 0xDB
14  TFEND = 0xDC
15  TFESC = 0xDD
16  
17  CMD_WIFI_MODE = 0x6A
18  CMD_WIFI_SSID = 0x6B
19  CMD_WIFI_PSK = 0x6C
20  
21  WR_WIFI_OFF = 0x00
22  WR_WIFI_STA = 0x01  # Connect to existing network
23  WR_WIFI_AP = 0x02   # Create hotspot
24  
25  
26  def escape(data: bytes) -> bytes:
27      data = data.replace(bytes([FESC]), bytes([FESC, TFESC]))
28      data = data.replace(bytes([FEND]), bytes([FESC, TFEND]))
29      return data
30  
31  
32  def send_kiss_wifi(ser: serial.Serial, cmd: int, data: bytes) -> None:
33      """Send a KISS WiFi command. Data is null-terminated for SSID/PSK."""
34      frame = bytes([FEND, cmd]) + escape(data) + bytes([FEND])
35      ser.write(frame)
36      time.sleep(0.05)
37  
38  
39  def configure_wifi(port: str, ssid: str, password: str, mode: int = WR_WIFI_STA) -> bool:
40      if len(ssid) > 32:
41          print("SSID must be 32 characters or fewer")
42          return False
43      if len(password) > 32:
44          print("Password must be 32 characters or fewer")
45          return False
46  
47      try:
48          ser = serial.Serial(port, 115200, timeout=2)
49      except serial.SerialException as e:
50          print(f"Failed to open {port}: {e}")
51          return False
52  
53      print("Configuring WiFi...")
54      time.sleep(0.5)
55  
56      # 1. Set SSID (null-terminated; firmware pads to 32 bytes)
57      ssid_data = ssid.encode("utf-8") + b"\x00"
58      send_kiss_wifi(ser, CMD_WIFI_SSID, ssid_data)
59      print(f"  SSID set: {ssid}")
60  
61      # 2. Set password (null-terminated; firmware pads to 32 bytes)
62      psk_data = password.encode("utf-8") + b"\x00"
63      send_kiss_wifi(ser, CMD_WIFI_PSK, psk_data)
64      print("  Password set")
65  
66      # 3. Enable STA mode (connect to network)
67      send_kiss_wifi(ser, CMD_WIFI_MODE, bytes([mode]))
68      mode_name = "STA (connect to network)" if mode == WR_WIFI_STA else "AP (hotspot)" if mode == WR_WIFI_AP else "off"
69      print(f"  WiFi mode: {mode_name}")
70  
71      ser.close()
72      print("\nDone. The RNode will connect to your network.")
73      print("Check the display for the assigned IP, or use rnodeconf -i after reconnecting.")
74      return True
75  
76  
77  def main():
78      if len(sys.argv) < 4:
79          print(__doc__)
80          print("Arguments: PORT SSID PASSWORD")
81          print('Example:   python3 configure_wifi.py /dev/ttyACM0 "MyNetwork" "MySecretPass"')
82          sys.exit(1)
83  
84      port = sys.argv[1]
85      ssid = sys.argv[2]
86      password = sys.argv[3]
87  
88      if not configure_wifi(port, ssid, password):
89          sys.exit(1)
90  
91  
92  if __name__ == "__main__":
93      main()