diff --git a/serial_to_mqtt_bridge/Dockerfile b/serial_to_mqtt_bridge/Dockerfile deleted file mode 100644 index aeac7ca8034293c1113a2804a0c60f28d4f0af97..0000000000000000000000000000000000000000 --- a/serial_to_mqtt_bridge/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM python:3.9 -# Or any preferred Python version. -WORKDIR /src -COPY . . -RUN pip install -r requirements.txt -CMD ["python3", "-u", "./serial_to_mqtt.py"] -# Or enter the name of your unique directory and parameter set. \ No newline at end of file diff --git a/serial_to_mqtt_bridge/create_exe.bat b/serial_to_mqtt_bridge/create_exe.bat new file mode 100644 index 0000000000000000000000000000000000000000..8325f9ce8b788acd06373fae703433e700745186 --- /dev/null +++ b/serial_to_mqtt_bridge/create_exe.bat @@ -0,0 +1,48 @@ +@echo off +setlocal + +:: Make sure the dist directory exists +if not exist dist mkdir dist + +:: Check if Python is installed +python --version >nul 2>&1 +if errorlevel 1 ( + echo Python is not installed. Please install Python from https://www.python.org/downloads/ + pause + exit /b 1 +) + +:: Check if PyInstaller is installed +pip show pyinstaller >nul 2>&1 +if errorlevel 1 ( + echo Installing PyInstaller... + pip install pyinstaller +) + +:: Check if required packages are installed +pip show paho-mqtt >nul 2>&1 +if errorlevel 1 ( + echo Installing required packages... + pip install -r requirements.txt +) + +:: Generate spec file +echo Generating spec file... +python -m PyInstaller --onefile --name serial_to_mqtt serial_to_mqtt.py + +:: Compile program +echo Compiling program... +python -m PyInstaller serial_to_mqtt.spec + +:: Move exe file to main directory +echo Moving exe file to main directory... +move /Y dist\serial_to_mqtt.exe .\serial_to_mqtt.exe + +:: Clean temporary folders +echo Cleaning temporary folders... +rmdir /S /Q build +rmdir /S /Q dist +del /F /Q serial_to_mqtt.spec + +echo Binary created successfully in .\serial_to_mqtt.exe +pause \ No newline at end of file diff --git a/serial_to_mqtt_bridge/serial_to_mqtt.exe b/serial_to_mqtt_bridge/serial_to_mqtt.exe index e74c34afbb6655d95c658ef79d36c820d83ef917..c55ed39921c2990ac26366e78bdd56cb7500d2b8 100644 Binary files a/serial_to_mqtt_bridge/serial_to_mqtt.exe and b/serial_to_mqtt_bridge/serial_to_mqtt.exe differ diff --git a/serial_to_mqtt_bridge/serial_to_mqtt.py b/serial_to_mqtt_bridge/serial_to_mqtt.py index 456d548daca19418b959926958b552def92bb2bc..30e83e4827f0d3a6b755d3eaf6bd550a6e147b3b 100755 --- a/serial_to_mqtt_bridge/serial_to_mqtt.py +++ b/serial_to_mqtt_bridge/serial_to_mqtt.py @@ -4,10 +4,79 @@ import paho.mqtt.client as mqtt import time import argparse import yaml +import os +import serial.tools.list_ports + +def list_serial_ports(): + """ + Lists all available serial ports and returns a list of ports + """ + ports = serial.tools.list_ports.comports() + + if not ports: + print("No serial ports found") + return None + + print("\nAvailable serial ports:") + print("-" * 50) + + port_list = [] + for i, port in enumerate(ports, 1): + print(f"{i}. Port: {port.device}") + print(f" Description: {port.description}") + print(f" Manufacturer: {port.manufacturer}") + print(f" Hardware ID: {port.hwid}") + print("-" * 50) + port_list.append(port.device) + + return port_list + +def select_serial_port(): + """ + Allows user to select a serial port from the list. + If there is only one port, it is selected automatically. + """ + port_list = list_serial_ports() + if not port_list: + return None + + # If there is only one port, select it automatically + if len(port_list) == 1: + print(f"\nOnly one port found: {port_list[0]}") + print("Selected automatically.") + return port_list[0] + + while True: + try: + choice = input("\nSelect port number (or type 'q' to quit): ") + if choice.lower() == 'q': + return None + + choice = int(choice) + if 1 <= choice <= len(port_list): + return port_list[choice - 1] + else: + print("Invalid port number. Please try again.") + except ValueError: + print("Please enter a valid number.") + # Load default configuration from YAML file def load_config(file_path="config.yaml"): - with open(file_path, 'r') as file: - return yaml.safe_load(file) + """ + Load configuration from YAML file. + If file doesn't exist or there's an error, return empty dict. + Default values are handled in argument parser. + """ + if not os.path.exists(file_path): + print(f"Warning: Configuration file '{file_path}' not found. Using default values from command line arguments.") + return {} + + try: + with open(file_path, 'r') as file: + return yaml.safe_load(file) or {} + except Exception as e: + print(f"Warning: Error reading configuration file '{file_path}': {str(e)}. Using default values from command line arguments.") + return {} # MQTT connection initialization client = mqtt.Client() @@ -36,11 +105,9 @@ def main(serial_port=None, baud_rate=115200, file_path="sim_data.txt", mqtt_brok if ser.in_waiting > 0: line = ser.readline().decode('utf-8').strip() print(f"Received from serial port: {line}") - + print(f"Sent to MQTT broker={mqtt_broker} in topic={mqtt_topic} msg={line}") # Send data to MQTT - client.publish(mqtt_topic, line.split(",",1)[1]) - print(f"Sent to MQTT: {line}") - + client.publish(mqtt_topic, line) time.sleep(0.1) # Short delay except KeyboardInterrupt: @@ -51,7 +118,7 @@ def main(serial_port=None, baud_rate=115200, file_path="sim_data.txt", mqtt_brok client.loop_stop() client.disconnect() else: - # If simulation mode is selected, send lines from the file cyclically + # If simulation mode is selected, send lines from the file cyclically file_reader = cyclic_file_reader(file_path) cnt=0 try: @@ -70,23 +137,28 @@ def main(serial_port=None, baud_rate=115200, file_path="sim_data.txt", mqtt_brok client.loop_stop() client.disconnect() - - if __name__ == "__main__": # Load configuration from YAML config = load_config() # Argument parser for serial port, baud rate, and file path parser = argparse.ArgumentParser(description="Read data from serial port and publish to MQTT.") - parser.add_argument("serial_port", type=str, help="Serial port to connect to (e.g., /dev/ttyUSB0) or 'sim' for simulation mode") - parser.add_argument("--baud_rate", type=int, default=config['serial'].get('baud_rate', 115200), help="Baud rate for serial communication") - parser.add_argument("--file_path", type=str, default=config['sim'].get('file_path'), help="Path to the file with data for MQTT") - parser.add_argument("--mqtt_broker", type=str, default=config['mqtt'].get('broker', "localhost"), help="MQTT broker address") - parser.add_argument("--mqtt_port", type=int, default=config['mqtt'].get('port', 1883), help="MQTT port") - parser.add_argument("--mqtt_topic", type=str, default=config['mqtt'].get('topic', "serial2MQTT"), help="MQTT topic to publish data") - parser.add_argument("--sim_interval", type=int, default=config['sim'].get('interval', 1), help="Interval in seconds for sending data from file") + parser.add_argument("--serial_port", type=str, help="Serial port to connect to (e.g., COM3) or 'sim' for simulation mode") + parser.add_argument("--baud_rate", type=int, default=config.get('serial', {}).get('baud_rate', 115200), help="Baud rate for serial communication") + parser.add_argument("--file_path", type=str, default=config.get('sim', {}).get('file_path', "sim_data.txt"), help="Path to the file with data for MQTT") + parser.add_argument("--mqtt_broker", type=str, default=config.get('mqtt', {}).get('broker', "localhost"), help="MQTT broker address") + parser.add_argument("--mqtt_port", type=int, default=config.get('mqtt', {}).get('port', 1883), help="MQTT port") + parser.add_argument("--mqtt_topic", type=str, default=config.get('mqtt', {}).get('topic', "serial2MQTT"), help="MQTT topic to publish data") + parser.add_argument("--sim_interval", type=int, default=config.get('sim', {}).get('interval', 1), help="Interval in seconds for sending data from file") args = parser.parse_args() + # If port is not provided as argument, let user select it + if not args.serial_port: + args.serial_port = select_serial_port() + if not args.serial_port: + print("No port selected. Program will terminate.") + exit(1) + # Run main with configuration from YAML and/or command line arguments main( serial_port=args.serial_port, diff --git a/serial_to_mqtt_bridge/sim_data.txt b/serial_to_mqtt_bridge/sim_data.txt index f38c7d206f5435c85938945d598687688e927d38..a6f5b225a854641ef9c73f69c2b72f31d0a3164b 100644 --- a/serial_to_mqtt_bridge/sim_data.txt +++ b/serial_to_mqtt_bridge/sim_data.txt @@ -1,100 +1,100 @@ -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=88,char=22,channel=38,tx_power=8,temp=3901,pH=2086,pHRaw=260,battery=2705,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=81,char=17,channel=37,tx_power=8,temp=3083,pH=2207,pHRaw=275,battery=684,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=71,char=21,channel=38,tx_power=8,temp=714,pH=1292,pHRaw=161,battery=2860,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=63,char=16,channel=37,tx_power=8,temp=61,pH=2737,pHRaw=342,battery=3735,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=47,char=38,channel=38,tx_power=8,temp=610,pH=423,pHRaw=52,battery=3663,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=64,char=38,channel=39,tx_power=8,temp=695,pH=4003,pHRaw=500,battery=2037,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=76,char=13,channel=37,tx_power=8,temp=510,pH=2869,pHRaw=358,battery=610,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=78,char=15,channel=39,tx_power=8,temp=1150,pH=289,pHRaw=36,battery=1598,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=68,char=20,channel=38,tx_power=8,temp=3964,pH=434,pHRaw=54,battery=1758,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=77,char=24,channel=39,tx_power=8,temp=789,pH=547,pHRaw=68,battery=1952,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=88,char=14,channel=39,tx_power=8,temp=834,pH=2084,pHRaw=260,battery=1367,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=74,char=24,channel=37,tx_power=8,temp=3405,pH=418,pHRaw=52,battery=3098,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=89,char=24,channel=37,tx_power=8,temp=2917,pH=2346,pHRaw=293,battery=90,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=72,char=18,channel=37,tx_power=8,temp=1812,pH=810,pHRaw=101,battery=182,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=45,char=19,channel=37,tx_power=8,temp=1021,pH=3112,pHRaw=389,battery=1122,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=71,char=13,channel=38,tx_power=8,temp=3759,pH=3384,pHRaw=423,battery=1046,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=52,char=17,channel=39,tx_power=8,temp=1490,pH=293,pHRaw=36,battery=2931,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=50,char=14,channel=38,tx_power=8,temp=2712,pH=3843,pHRaw=480,battery=3880,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=46,char=18,channel=39,tx_power=8,temp=61,pH=1878,pHRaw=234,battery=2490,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=66,char=21,channel=38,tx_power=8,temp=3020,pH=687,pHRaw=85,battery=439,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=62,char=15,channel=39,tx_power=8,temp=434,pH=2156,pHRaw=269,battery=1653,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=58,char=23,channel=38,tx_power=8,temp=3933,pH=582,pHRaw=72,battery=2409,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=71,char=21,channel=39,tx_power=8,temp=1242,pH=3835,pHRaw=479,battery=3377,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=78,char=23,channel=38,tx_power=8,temp=3186,pH=3799,pHRaw=474,battery=1032,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=54,char=24,channel=39,tx_power=8,temp=1465,pH=2598,pHRaw=324,battery=1145,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=77,char=18,channel=37,tx_power=8,temp=3294,pH=2294,pHRaw=286,battery=3995,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=59,char=18,channel=38,tx_power=8,temp=3097,pH=1957,pHRaw=244,battery=1372,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=65,char=19,channel=39,tx_power=8,temp=1944,pH=1166,pHRaw=145,battery=1963,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=81,char=23,channel=39,tx_power=8,temp=3192,pH=1025,pHRaw=128,battery=3403,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=62,char=24,channel=37,tx_power=8,temp=86,pH=1420,pHRaw=177,battery=2173,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=73,char=16,channel=38,tx_power=8,temp=2024,pH=1351,pHRaw=168,battery=293,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=50,char=37,channel=39,tx_power=8,temp=1362,pH=1007,pHRaw=125,battery=2843,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=89,char=15,channel=39,tx_power=8,temp=1031,pH=190,pHRaw=23,battery=3980,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=45,char=38,channel=38,tx_power=8,temp=1874,pH=2610,pHRaw=326,battery=691,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=86,char=21,channel=37,tx_power=8,temp=3544,pH=3073,pHRaw=384,battery=590,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=51,char=20,channel=37,tx_power=8,temp=341,pH=601,pHRaw=75,battery=289,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=72,char=20,channel=39,tx_power=8,temp=598,pH=4040,pHRaw=505,battery=1967,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=79,char=21,channel=37,tx_power=8,temp=3420,pH=3193,pHRaw=399,battery=385,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=78,char=19,channel=37,tx_power=8,temp=3928,pH=1276,pHRaw=159,battery=3097,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=79,char=22,channel=38,tx_power=8,temp=1140,pH=2853,pHRaw=356,battery=4042,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=56,char=18,channel=38,tx_power=8,temp=943,pH=2014,pHRaw=251,battery=1054,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=47,char=13,channel=37,tx_power=8,temp=1019,pH=3915,pHRaw=489,battery=2563,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=67,char=23,channel=38,tx_power=8,temp=2941,pH=411,pHRaw=51,battery=429,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=66,char=21,channel=38,tx_power=8,temp=2586,pH=2697,pHRaw=337,battery=3850,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=51,char=16,channel=39,tx_power=8,temp=3521,pH=3614,pHRaw=451,battery=1824,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=81,char=13,channel=38,tx_power=8,temp=1143,pH=707,pHRaw=88,battery=1633,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=46,char=22,channel=37,tx_power=8,temp=3836,pH=2517,pHRaw=314,battery=2445,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=59,char=19,channel=37,tx_power=8,temp=3573,pH=3040,pHRaw=380,battery=1950,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=81,char=37,channel=37,tx_power=8,temp=3354,pH=3958,pHRaw=494,battery=3053,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=48,char=15,channel=38,tx_power=8,temp=1922,pH=1646,pHRaw=205,battery=2364,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=57,char=22,channel=37,tx_power=8,temp=2533,pH=2947,pHRaw=368,battery=890,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=76,char=14,channel=37,tx_power=8,temp=753,pH=3213,pHRaw=401,battery=2100,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=89,char=19,channel=38,tx_power=8,temp=1592,pH=696,pHRaw=87,battery=2075,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=58,char=21,channel=38,tx_power=8,temp=1358,pH=343,pHRaw=42,battery=1764,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=76,char=15,channel=39,tx_power=8,temp=2896,pH=2154,pHRaw=269,battery=842,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=90,char=22,channel=39,tx_power=8,temp=1111,pH=2495,pHRaw=311,battery=671,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=47,char=15,channel=39,tx_power=8,temp=1306,pH=4080,pHRaw=510,battery=2497,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=82,char=15,channel=37,tx_power=8,temp=2815,pH=2215,pHRaw=276,battery=3145,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=80,char=37,channel=39,tx_power=8,temp=1740,pH=997,pHRaw=124,battery=598,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=86,char=20,channel=39,tx_power=8,temp=2423,pH=3654,pHRaw=456,battery=3386,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=68,char=21,channel=39,tx_power=8,temp=3077,pH=1668,pHRaw=208,battery=3426,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=69,char=38,channel=37,tx_power=8,temp=3996,pH=1739,pHRaw=217,battery=360,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=50,char=15,channel=37,tx_power=8,temp=2116,pH=2417,pHRaw=302,battery=158,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=67,char=17,channel=38,tx_power=8,temp=3202,pH=1947,pHRaw=243,battery=3810,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=89,char=18,channel=38,tx_power=8,temp=3616,pH=2598,pHRaw=324,battery=665,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=80,char=38,channel=37,tx_power=8,temp=1135,pH=2649,pHRaw=331,battery=1595,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=59,char=17,channel=37,tx_power=8,temp=2497,pH=319,pHRaw=39,battery=163,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=89,char=15,channel=37,tx_power=8,temp=3603,pH=2958,pHRaw=369,battery=170,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=84,char=22,channel=39,tx_power=8,temp=3019,pH=399,pHRaw=49,battery=1643,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=48,char=14,channel=39,tx_power=8,temp=2853,pH=3798,pHRaw=474,battery=384,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=71,char=24,channel=39,tx_power=8,temp=989,pH=4022,pHRaw=502,battery=1269,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=89,char=23,channel=37,tx_power=8,temp=378,pH=3316,pHRaw=414,battery=3170,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=58,char=38,channel=38,tx_power=8,temp=1737,pH=4037,pHRaw=504,battery=2836,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=74,char=20,channel=38,tx_power=8,temp=74,pH=3558,pHRaw=444,battery=1550,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=50,char=14,channel=38,tx_power=8,temp=3439,pH=1289,pHRaw=161,battery=2482,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=67,char=15,channel=37,tx_power=8,temp=2390,pH=524,pHRaw=65,battery=2981,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=89,char=17,channel=39,tx_power=8,temp=2166,pH=3086,pHRaw=385,battery=1833,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=64,char=15,channel=38,tx_power=8,temp=1113,pH=3702,pHRaw=462,battery=3844,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=60,char=20,channel=37,tx_power=8,temp=2881,pH=3718,pHRaw=464,battery=3238,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=87,char=37,channel=38,tx_power=8,temp=2806,pH=2729,pHRaw=341,battery=3726,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=55,char=38,channel=37,tx_power=8,temp=2806,pH=2384,pHRaw=298,battery=798,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=47,char=24,channel=39,tx_power=8,temp=3246,pH=276,pHRaw=34,battery=3670,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=59,char=20,channel=39,tx_power=8,temp=178,pH=3943,pHRaw=492,battery=3070,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=50,char=13,channel=39,tx_power=8,temp=1088,pH=2433,pHRaw=304,battery=3080,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=75,char=23,channel=38,tx_power=8,temp=2849,pH=3824,pHRaw=478,battery=2326,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=67,char=14,channel=38,tx_power=8,temp=306,pH=967,pHRaw=120,battery=4,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=46,char=16,channel=38,tx_power=8,temp=2002,pH=503,pHRaw=62,battery=1295,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=91,char=18,channel=39,tx_power=8,temp=1951,pH=2623,pHRaw=327,battery=3824,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=72,char=15,channel=39,tx_power=8,temp=2796,pH=179,pHRaw=22,battery=3228,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=90,char=16,channel=39,tx_power=8,temp=556,pH=739,pHRaw=92,battery=3655,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=89,char=38,channel=38,tx_power=8,temp=1691,pH=1058,pHRaw=132,battery=2974,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=63,char=15,channel=38,tx_power=8,temp=144,pH=951,pHRaw=118,battery=2738,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=82,char=38,channel=39,tx_power=8,temp=1314,pH=1867,pHRaw=233,battery=1180,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=64,char=16,channel=39,tx_power=8,temp=3909,pH=779,pHRaw=97,battery=2148,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=87,char=15,channel=37,tx_power=8,temp=905,pH=2907,pHRaw=363,battery=418,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=60,char=38,channel=38,tx_power=8,temp=213,pH=441,pHRaw=55,battery=2914,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=83,char=15,channel=38,tx_power=8,temp=3916,pH=487,pHRaw=60,battery=3312,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=72,char=21,channel=38,tx_power=8,temp=761,pH=3942,pHRaw=492,battery=1901,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=51,char=22,channel=39,tx_power=8,temp=3744,pH=2668,pHRaw=333,battery=2264,timestamp= -dongle_t=c000d0009,beacon_t=c000beac0004 rssi=84,char=20,channel=39,tx_power=8,temp=1398,pH=3934,pHRaw=491,battery=1787,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=49,char=22,channel=37,tx_power=8,temp=928,pH=372,pHRaw=46,battery=3002,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=46,char=22,channel=39,tx_power=8,temp=3914,pH=3391,pHRaw=423,battery=2158,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=60,char=38,channel=37,tx_power=8,temp=1645,pH=600,pHRaw=75,battery=512,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=69,char=21,channel=39,tx_power=8,temp=833,pH=1331,pHRaw=166,battery=259,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=51,char=20,channel=37,tx_power=8,temp=1574,pH=2811,pHRaw=351,battery=405,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=85,char=24,channel=39,tx_power=8,temp=1390,pH=914,pHRaw=114,battery=523,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=50,char=22,channel=39,tx_power=8,temp=667,pH=2074,pHRaw=259,battery=2569,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=48,char=24,channel=37,tx_power=8,temp=4090,pH=1586,pHRaw=198,battery=3991,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=46,char=20,channel=39,tx_power=8,temp=2689,pH=1329,pHRaw=166,battery=479,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=76,char=22,channel=38,tx_power=8,temp=2734,pH=3961,pHRaw=495,battery=3025,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=59,char=19,channel=37,tx_power=8,temp=3540,pH=2953,pHRaw=369,battery=3837,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=49,char=21,channel=37,tx_power=8,temp=2475,pH=1358,pHRaw=169,battery=1569,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=49,char=23,channel=39,tx_power=8,temp=3819,pH=2866,pHRaw=358,battery=83,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=49,char=17,channel=37,tx_power=8,temp=3164,pH=3505,pHRaw=438,battery=3272,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=81,char=15,channel=37,tx_power=8,temp=790,pH=844,pHRaw=105,battery=1119,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=80,char=18,channel=39,tx_power=8,temp=1773,pH=289,pHRaw=36,battery=2078,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=58,char=21,channel=38,tx_power=8,temp=2554,pH=2843,pHRaw=355,battery=3302,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=71,char=18,channel=38,tx_power=8,temp=1946,pH=3705,pHRaw=463,battery=3119,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=75,char=18,channel=39,tx_power=8,temp=1228,pH=3488,pHRaw=436,battery=3501,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=52,char=13,channel=38,tx_power=8,temp=1369,pH=2050,pHRaw=256,battery=2631,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=46,char=16,channel=38,tx_power=8,temp=2097,pH=3264,pHRaw=408,battery=2329,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=61,char=21,channel=38,tx_power=8,temp=319,pH=502,pHRaw=62,battery=1709,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=46,char=38,channel=39,tx_power=8,temp=1496,pH=3825,pHRaw=478,battery=812,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=78,char=20,channel=37,tx_power=8,temp=3088,pH=2535,pHRaw=316,battery=1207,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=90,char=38,channel=39,tx_power=8,temp=4002,pH=1516,pHRaw=189,battery=3825,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=63,char=17,channel=38,tx_power=8,temp=3651,pH=1598,pHRaw=199,battery=1484,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=83,char=37,channel=37,tx_power=8,temp=3386,pH=20,pHRaw=2,battery=1953,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=83,char=38,channel=39,tx_power=8,temp=2936,pH=2680,pHRaw=335,battery=3670,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=75,char=17,channel=39,tx_power=8,temp=1335,pH=3755,pHRaw=469,battery=171,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=51,char=24,channel=37,tx_power=8,temp=3547,pH=1182,pHRaw=147,battery=779,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=65,char=22,channel=37,tx_power=8,temp=766,pH=138,pHRaw=17,battery=1395,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=57,char=13,channel=37,tx_power=8,temp=389,pH=399,pHRaw=49,battery=654,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=82,char=37,channel=38,tx_power=8,temp=3583,pH=1572,pHRaw=196,battery=3908,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=52,char=23,channel=37,tx_power=8,temp=4090,pH=3453,pHRaw=431,battery=323,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=46,char=23,channel=37,tx_power=8,temp=3480,pH=358,pHRaw=44,battery=3276,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=45,char=23,channel=39,tx_power=8,temp=2486,pH=2919,pHRaw=364,battery=3548,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=47,char=16,channel=37,tx_power=8,temp=385,pH=7,pHRaw=0,battery=934,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=53,char=13,channel=37,tx_power=8,temp=769,pH=203,pHRaw=25,battery=2131,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=49,char=15,channel=39,tx_power=8,temp=2290,pH=871,pHRaw=108,battery=3019,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=70,char=20,channel=37,tx_power=8,temp=2155,pH=1038,pHRaw=129,battery=2113,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=77,char=13,channel=37,tx_power=8,temp=3610,pH=3091,pHRaw=386,battery=4047,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=45,char=38,channel=38,tx_power=8,temp=1490,pH=644,pHRaw=80,battery=338,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=88,char=13,channel=37,tx_power=8,temp=3218,pH=2409,pHRaw=301,battery=2912,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=61,char=17,channel=39,tx_power=8,temp=698,pH=326,pHRaw=40,battery=412,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=79,char=24,channel=39,tx_power=8,temp=3739,pH=1524,pHRaw=190,battery=935,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=74,char=20,channel=38,tx_power=8,temp=1685,pH=1415,pHRaw=176,battery=1610,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=62,char=23,channel=38,tx_power=8,temp=1129,pH=2250,pHRaw=281,battery=1672,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=88,char=24,channel=39,tx_power=8,temp=135,pH=3377,pHRaw=422,battery=3346,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=89,char=14,channel=38,tx_power=8,temp=2029,pH=3376,pHRaw=422,battery=3041,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=55,char=38,channel=37,tx_power=8,temp=3739,pH=2169,pHRaw=271,battery=2054,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=58,char=37,channel=38,tx_power=8,temp=2523,pH=259,pHRaw=32,battery=3961,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=85,char=21,channel=39,tx_power=8,temp=2897,pH=1754,pHRaw=219,battery=1830,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=74,char=13,channel=37,tx_power=8,temp=23,pH=3586,pHRaw=448,battery=4070,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=57,char=38,channel=38,tx_power=8,temp=1898,pH=3710,pHRaw=463,battery=324,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=56,char=23,channel=39,tx_power=8,temp=2080,pH=239,pHRaw=29,battery=534,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=68,char=15,channel=39,tx_power=8,temp=2052,pH=3445,pHRaw=430,battery=1350,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=58,char=15,channel=37,tx_power=8,temp=3947,pH=462,pHRaw=57,battery=2162,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=90,char=24,channel=38,tx_power=8,temp=1937,pH=132,pHRaw=16,battery=1334,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=65,char=20,channel=38,tx_power=8,temp=929,pH=3238,pHRaw=404,battery=2798,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=86,char=38,channel=37,tx_power=8,temp=2861,pH=2509,pHRaw=313,battery=1644,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=88,char=22,channel=38,tx_power=8,temp=2580,pH=356,pHRaw=44,battery=2207,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=64,char=21,channel=38,tx_power=8,temp=3965,pH=3976,pHRaw=497,battery=2044,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=51,char=19,channel=39,tx_power=8,temp=3138,pH=3088,pHRaw=386,battery=2179,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=89,char=37,channel=37,tx_power=8,temp=3796,pH=3752,pHRaw=469,battery=1335,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=84,char=13,channel=37,tx_power=8,temp=2879,pH=464,pHRaw=58,battery=2531,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=86,char=15,channel=38,tx_power=8,temp=1510,pH=4081,pHRaw=510,battery=1834,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=59,char=14,channel=39,tx_power=8,temp=1337,pH=3595,pHRaw=449,battery=417,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=90,char=17,channel=37,tx_power=8,temp=1962,pH=2854,pHRaw=356,battery=2833,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=79,char=18,channel=38,tx_power=8,temp=829,pH=843,pHRaw=105,battery=2936,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=55,char=38,channel=37,tx_power=8,temp=3878,pH=2916,pHRaw=364,battery=987,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=70,char=23,channel=37,tx_power=8,temp=779,pH=4048,pHRaw=506,battery=1853,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=52,char=14,channel=39,tx_power=8,temp=2102,pH=3702,pHRaw=462,battery=2060,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=67,char=14,channel=38,tx_power=8,temp=2796,pH=1946,pHRaw=243,battery=569,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=58,char=23,channel=39,tx_power=8,temp=2249,pH=2161,pHRaw=270,battery=3769,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=45,char=20,channel=39,tx_power=8,temp=2571,pH=791,pHRaw=98,battery=395,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=67,char=21,channel=39,tx_power=8,temp=3110,pH=4029,pHRaw=503,battery=3970,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=63,char=23,channel=39,tx_power=8,temp=1250,pH=3791,pHRaw=473,battery=1081,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=72,char=21,channel=37,tx_power=8,temp=75,pH=3175,pHRaw=396,battery=3363,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=54,char=37,channel=37,tx_power=8,temp=3928,pH=1700,pHRaw=212,battery=1721,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=58,char=38,channel=38,tx_power=8,temp=1051,pH=3004,pHRaw=375,battery=2207,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=67,char=15,channel=39,tx_power=8,temp=1601,pH=2707,pHRaw=338,battery=721,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=48,char=19,channel=37,tx_power=8,temp=1163,pH=1358,pHRaw=169,battery=2922,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=84,char=37,channel=38,tx_power=8,temp=1134,pH=1417,pHRaw=177,battery=272,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=76,char=24,channel=37,tx_power=8,temp=1315,pH=2065,pHRaw=258,battery=243,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=81,char=17,channel=39,tx_power=8,temp=3284,pH=151,pHRaw=18,battery=73,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=55,char=21,channel=39,tx_power=8,temp=3657,pH=1804,pHRaw=225,battery=781,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=72,char=24,channel=37,tx_power=8,temp=226,pH=1687,pHRaw=210,battery=2594,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=62,char=16,channel=37,tx_power=8,temp=2353,pH=3854,pHRaw=481,battery=1259,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=73,char=37,channel=39,tx_power=8,temp=1901,pH=2863,pHRaw=357,battery=930,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=80,char=24,channel=39,tx_power=8,temp=1897,pH=4030,pHRaw=503,battery=3164,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=86,char=17,channel=39,tx_power=8,temp=644,pH=63,pHRaw=7,battery=863,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=66,char=15,channel=37,tx_power=8,temp=2839,pH=2441,pHRaw=305,battery=1483,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=67,char=16,channel=39,tx_power=8,temp=2228,pH=2152,pHRaw=269,battery=1369,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=67,char=37,channel=39,tx_power=8,temp=1476,pH=418,pHRaw=52,battery=1849,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=74,char=16,channel=38,tx_power=8,temp=3769,pH=3603,pHRaw=450,battery=1895,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=85,char=20,channel=39,tx_power=8,temp=704,pH=349,pHRaw=43,battery=2170,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=63,char=18,channel=38,tx_power=8,temp=1497,pH=3031,pHRaw=378,battery=3990,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=87,char=18,channel=37,tx_power=8,temp=3730,pH=355,pHRaw=44,battery=567,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=68,char=22,channel=39,tx_power=8,temp=970,pH=1998,pHRaw=249,battery=2206,timestamp= +dongle_t=c000d0009,beacon_t=c000beac0004 rssi=77,char=14,channel=38,tx_power=8,temp=2887,pH=1097,pHRaw=137,battery=2398,timestamp=