Last active
July 19, 2026 07:03
-
-
Save sleventyeleven/4f6fe63451b179e21aed64628c2c8628 to your computer and use it in GitHub Desktop.
simple pyserial script to send commands encoded as weather data over LoRa
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import serial | |
| import time | |
| # Configure the serial port. | |
| # Replace '/dev/ttyUSB0' with your actual port: | |
| # Windows: 'COM3', 'COM4', etc. | |
| # Mac/Linux: '/dev/ttyUSB0', '/dev/ttyAMA0', etc. | |
| SERIAL_PORT = '/dev/ttyS4' | |
| BAUD_RATE = 115200 | |
| target_addr = 10 | |
| local_addr = 12 | |
| network_id = 18 | |
| network_band = 915000000 | |
| try: | |
| ser = serial.Serial( | |
| port=SERIAL_PORT, | |
| baudrate=BAUD_RATE, | |
| bytesize=serial.EIGHTBITS, | |
| parity=serial.PARITY_NONE, | |
| stopbits=serial.STOPBITS_ONE, | |
| timeout=1.0 | |
| ) | |
| except Exception as e: | |
| print(f"Error opening serial port: {e}") | |
| exit() | |
| # Simple mapping dictionary to encode hex characters into plausible weather metrics. | |
| # We will use the decimals of different weather readings to encode our payload data. | |
| HEX_MAP = { | |
| '0': (15.1, 45.1), '1': (15.2, 45.2), '2': (15.3, 45.3), '3': (15.4, 45.4), | |
| '4': (15.5, 45.5), '5': (15.6, 45.6), '6': (15.7, 45.7), '7': (15.8, 45.8), | |
| '8': (16.1, 46.1), '9': (16.2, 46.2), 'a': (16.3, 46.3), 'b': (16.4, 46.4), | |
| 'c': (16.5, 46.5), 'd': (16.6, 46.6), 'e': (16.7, 46.7), 'f': (16.8, 46.8) | |
| } | |
| # Reverse mapping for decoding | |
| REV_MAP_TEMP = {v[0]: k for k, v in HEX_MAP.items()} | |
| REV_MAP_HUMID = {v[1]: k for k, v in HEX_MAP.items()} | |
| def encode_to_weather(hex_payload): | |
| """ | |
| Encodes a hexadecimal payload string into a series of mock weather telemetry packets. | |
| For demonstration, each hex character pair is mapped to simulated Temp (T) and Humidity (H) decimals. | |
| """ | |
| encoded_packets = [] | |
| # Ensure lowercase hex | |
| clean_hex = hex_payload.lower().strip() | |
| # Process the hex string in pairs | |
| for i in range(0, len(clean_hex), 2): | |
| char1 = clean_hex[i] | |
| char2 = clean_hex[i + 1] if i + 1 < len(clean_hex) else '0' | |
| t_val = HEX_MAP.get(char1, (15.0, 45.0))[0] | |
| h_val = HEX_MAP.get(char2, (15.0, 45.0))[1] | |
| # Format the fake weather string | |
| fake_packet = f"ID:WS915;T:{t_val}C;H:{h_val}%;P:1013.2hPa;W:2.4m/s" | |
| encoded_packets.append(fake_packet) | |
| return encoded_packets | |
| def send_command(command_str): | |
| """Formats and sends an AT command to the module.""" | |
| full_command = f"{command_str}\r\n" | |
| ser.write(full_command.encode('utf-8')) | |
| print(f"[Sent]: {command_str}") | |
| # Basic initialization sequence | |
| time.sleep(1) | |
| send_command("AT") # Test if the module responds with "+OK" | |
| time.sleep(2) | |
| send_command(f"AT+ADDRESS={local_addr}") # Set Address | |
| time.sleep(2) | |
| send_command(f"AT+NETWORKID={network_id}") # Set Network | |
| time.sleep(2) | |
| send_command(f"AT+BAND={network_band}") # Set Band | |
| time.sleep(2) | |
| # Example Usage | |
| if __name__ == "__main__": | |
| # Simulated command to send: "CMD: RUN WHOAMI" converted to hex | |
| original_data = "CMD: WHOAMI" | |
| hex_data = original_data.encode('utf-8').hex() | |
| print(f"Original String: {original_data}") | |
| print(f"Hex Representation: {hex_data}\n") | |
| # Encode payload as benign weather data | |
| weather_packets = encode_to_weather(hex_data) | |
| print("--- Transmitted Weather Packets ---") | |
| time.sleep(1) | |
| start_msg = f"START:{len(weather_packets)}" | |
| len_start_msg = len(start_msg) | |
| send_command(f"AT+SEND={target_addr},{len_start_msg},{start_msg}") | |
| time.sleep(1) | |
| for pkt in weather_packets: | |
| length = len(pkt) | |
| send_command(f"AT+SEND={target_addr},{length},{pkt}") | |
| time.sleep(1) | |
| send_command(f"AT+SEND={target_addr},3,END") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment