diff --git a/examples/LTE modem/README.md b/examples/LTE modem/README.md index 0871330f..5055bce1 100644 --- a/examples/LTE modem/README.md +++ b/examples/LTE modem/README.md @@ -1,77 +1,139 @@ -# LTE modem HUAWEI K5161H + Serial Studio Example +# Serial Studio and LTE modem HUAWEI K5161H ## Overview -This project demonstrates how to use Serial Studio and MQTT to visualize data from a **LTE modem HUAWEI K5161H**. +This project demonstrates how to use **Serial Studio** to visualize signal quality data from a **LTE modem HUAWEI K5161H**. -## Using in this example +![Serial Studio](doc/screenshot.png) -- OS **Archlinux** -- **Mosquitto**: MQTT broker -- **Python** -- **paho**: Python client library for MQTT - -## Step-by-Step Guide - -### 1. MQTT broker Mosquitto -To install MQTT Broker **Mosquitto** run in terminal: -`sudo pacman -S mosquitto` - -To run MQTT Broker **Mosquitto** with default settings run in terminal: -`mosquitto --verbose` - -### 2. Parse data from LTE modem API -For simple cases, you can send data frame to MQTT from terminal, e.g.: -`mosquitto_pub -m "100,50,75,89" -t "lte"` - -For complex situations, you can use Python (or another language for your choice) to retrieve and form the data frame. -An example script is contained in the file [lte_mqtt.py](lte_mqtt.py) - -Install **paho** - Python client library for MQTT: -`sudo pacman -S python-paho-mqtt` - -Run in terminal: -`python lte_mqtt.py` - -Data frame will send to MQTT every 5 seconds. +Three methods of sending data are described: +- [Virtual Serial Port](#method_1) +- [MQTT](#method_2) +- [UDP Socket](#method_3) -### 3. Serial Studio Configuration -1. **Download and Install Serial Studio**: +The examples are implemented on OS [Archlinux](https://archlinux.org/), in which **Serial Studio** can be: +- run from [AppImage](https://github.com/serial-studio/serial-studio/releases/latest) +- installed from [Arch User Repository](https://aur.archlinux.org/packages/serial-studio-bin) (AUR) [manually](https://wiki.archlinux.org/title/Arch_User_Repository#Installing_and_upgrading_packages) or by AUR helper, e.g. `yay` + ``` + yay -S serial-studio-bin + ``` +- compiled by [cmake](/#development) - Visit [Serial Studio's official website](https://serial-studio.github.io/) to download and install the software. +Data from HUAWEI K5161H can be get by url API `http://192.168.9.1/api/device/signal` +Python was used to receive, process and generate data frames. -2. **Open Serial Studio and configure MQTT**: +--- - - Set the **Host**: 127.0.0.1 - - Set the **Port**: 1883 - - Set the **Topic**: lte - - Set the **Mode**: Subscriber - - Set the **Keep Alive**: 600 - - Click **Connect** -![Serial Studio Quick Plot](doc/mqtt_setup.png) + +## Method 1 - Virtual Serial Port -3. After get first frame of data Serial-Studio will automatic open dashboard with plots. +### Create Virtual Serial Port +1. Install [socat](http://www.dest-unreach.org/socat/) + ``` + sudo pacman -S socat + ``` +2. Create a linked pair of virtual serial ports, ttyV0 for listening and ttyV1 for sending data + ``` + socat -d -d pty,rawer,echo=0,link=/tmp/ttyV0,b9600 pty,rawer,echo=0,link=/tmp/ttyV1,b9600 + ``` +3. You can check the operation of the virtul serial ports by reading the file `/tmp/ttyV0` + ``` + cat /tmp/ttyV0 + ``` + and writing data to the file `/tmp/ttyV1` + ``` + echo 100 > /tmp/ttyV1 + ``` +5. Install `python-pyserial` + ``` + sudo pacman -S python-pyserial + ``` +6. Run a Python script `lte_serial.py` to process data and send it to the virtual serial port `/tmp/ttyV1` + ``` + python lte_serial.py + ``` -![LTE modem signal](doc/screenshot.png) +### Serial Studio configuration for Virtual Serial Port +- Run **Serial Studio** +- Select **DEVICE SETUP** → I/O Interface: Serial Port +- Select **FRAME PARSING** → Parse via JSON Project File +- Select **Project file** → `lte.json` +- Manually enter **COM Port** → `/tmp/ttyV0` and press Enter +- Select **Baud Rate** → 9600 +- Click **Connect** in upper right corner -4. Use **Project editor** to configure dashboard. +After get first frame of data **Serial Studio** will automatic open dashboard with plots. -![Project Editor](doc/project_editor.png) +![Screenshot Virtual Serial Port](doc/screenshot_serial.png) +--- -## UDP Socket -Solution with UDP Socket looks much simpler than MQTT. + +## Method 2 - MQTT -Run in terminal: -`python lte_udp.py` +### Prepare MQTT broker +1. Install MQTT broker [Mosquitto](https://mosquitto.org/) + ``` + sudo pacman -S mosquitto + ``` +2. Run MQTT broker with default settings + ``` + mosquitto --verbose + ``` +3. You can check MQTT broker by sending data + ``` + mosquitto_pub -m "abcd,100,50,75,89" -t "lte" + ``` +4. Install Python client library for MQTT - **paho** + ``` + sudo pacman -S python-paho-mqtt + ``` +5. Run a Python script `lte_mqtt.py` to process and send data to the MQTT broker + ``` + python lte_mqtt.py + ``` + +### Serial Studio Configuration for MQTT + +- Run **Serial Studio** +- Select **FRAME PARSING** → Parse via JSON Project File +- Select **Project file** → `lte.json` +- Click **MQTT** in the top bar +- Set **Host** → 127.0.0.1 +- Set **Port** → 1883 +- Set **Topic** → lte +- Select **Mode** → Subscriber +- Set **Keep Alive** → 600 +- Click **Connect** + +After get first frame of data **Serial Studio** will automatic open dashboard with plots. + +![Screenshot MQTT](doc/screenshot_mqtt.png) + +--- + + +## Method 3 - UDP Socket +Solution with UDP Socket looks much simpler than other. + +Run a Python script `lte_udp.py` to process data and send it to the UDP Socket +``` +python lte_udp.py +``` ### Serial Studio Configuration for UDP Socket - - Set the **DEVICE SETUP**: I/O Interface: Network Socket - - Set the **Socket type**: UDP - - Set the **Remote address**: 127.0.0.1 - - Set the **Local port**: 5005 - - Set the **Ignore data delimeters**: True - - Click **Connect** -![Serial Studio Quick Plot](doc/udp.png) +- Run **Serial Studio** +- Select **DEVICE SETUP** → I/O Interface: Network Socket +- Select **FRAME PARSING** → Parse via JSON Project File +- Select **Project file** → `lte.json` +- Select **Socket type** → UDP +- Set **Remote address** → 127.0.0.1 +- Set **Local port** → 5005 +- Click **Connect** in upper right corner + +After get first frame of data **Serial Studio** will automatic open dashboard with plots. + +![Screenshot UDP](doc/screenshot_udp.png) + diff --git a/examples/LTE modem/doc/project_editor.png b/examples/LTE modem/doc/project_editor.png deleted file mode 100644 index cec173c4..00000000 Binary files a/examples/LTE modem/doc/project_editor.png and /dev/null differ diff --git a/examples/LTE modem/doc/mqtt_setup.png b/examples/LTE modem/doc/screenshot_mqtt.png similarity index 100% rename from examples/LTE modem/doc/mqtt_setup.png rename to examples/LTE modem/doc/screenshot_mqtt.png diff --git a/examples/LTE modem/doc/screenshot_serial.png b/examples/LTE modem/doc/screenshot_serial.png new file mode 100644 index 00000000..bfc76e56 Binary files /dev/null and b/examples/LTE modem/doc/screenshot_serial.png differ diff --git a/examples/LTE modem/doc/screenshot_udp.png b/examples/LTE modem/doc/screenshot_udp.png new file mode 100644 index 00000000..0163e592 Binary files /dev/null and b/examples/LTE modem/doc/screenshot_udp.png differ diff --git a/examples/LTE modem/doc/udp.png b/examples/LTE modem/doc/udp.png deleted file mode 100644 index 1b822ff3..00000000 Binary files a/examples/LTE modem/doc/udp.png and /dev/null differ diff --git a/examples/LTE modem/lte.json b/examples/LTE modem/lte.json new file mode 100644 index 00000000..3a4aebbf --- /dev/null +++ b/examples/LTE modem/lte.json @@ -0,0 +1,105 @@ +{ + "actions": [ + ], + "decoder": 0, + "frameDetection": 1, + "frameEnd": "*/", + "frameParser": "/**\n * Automatically migrated frame parser function.\n */\nfunction parse(frame) {\n return frame.split(',');\n}", + "frameStart": "/*", + "groups": [ + { + "datasets": [ + { + "alarm": 0, + "fft": false, + "fftSamples": 256, + "fftSamplingRate": 100, + "graph": false, + "index": 1, + "led": false, + "ledHigh": 1, + "log": false, + "max": 0, + "min": 0, + "title": "Cell id", + "units": "", + "value": "--.--", + "widget": "" + }, + { + "alarm": 0, + "fft": false, + "fftSamples": 256, + "fftSamplingRate": 100, + "graph": true, + "index": 2, + "led": false, + "ledHigh": 1, + "log": false, + "max": 0, + "min": -20, + "title": "RSRQ", + "units": "dB", + "value": "--.--", + "widget": "" + }, + { + "alarm": 0, + "fft": false, + "fftSamples": 256, + "fftSamplingRate": 100, + "graph": true, + "index": 3, + "led": false, + "ledHigh": 1, + "log": false, + "max": -70, + "min": -120, + "title": "RSRP", + "units": "dBm", + "value": "--.--", + "widget": "" + }, + { + "alarm": 0, + "fft": false, + "fftSamples": 256, + "fftSamplingRate": 100, + "graph": true, + "index": 4, + "led": false, + "ledHigh": 1, + "log": false, + "max": -50, + "min": -100, + "title": "RSSI", + "units": "dBm", + "value": "--.--", + "widget": "" + }, + { + "alarm": 0, + "fft": false, + "fftSamples": 256, + "fftSamplingRate": 100, + "graph": true, + "index": 5, + "led": false, + "ledHigh": 1, + "log": false, + "max": 30, + "min": -20, + "title": "SINR", + "units": "dB", + "value": "", + "widget": "" + } + ], + "title": "Data Grid", + "widget": "datagrid" + } + ], + "mapTilerApiKey": "", + "thunderforestApiKey": "", + "title": "HUAWEI K5161H" +} diff --git a/examples/LTE modem/lte_mqtt.py b/examples/LTE modem/lte_mqtt.py index d253952a..f44da49e 100644 --- a/examples/LTE modem/lte_mqtt.py +++ b/examples/LTE modem/lte_mqtt.py @@ -45,8 +45,8 @@ while True: dlfrequency = int(get_value('dlfrequency')) print(f'{datetime.datetime.now().strftime("%H-%M-%S")} CELL={cell} RSRQ={rsrq} RSRP={rsrp} RSSI={rssi} SINR={sinr}') - data_frame = f'{rsrq},{rsrp},{rssi},{sinr},{cell}' - # print(frame) + data_frame = f'{cell},{rsrq},{rsrp},{rssi},{sinr}\n' + print(data_frame) mqttc.publish(mqtt_topic, data_frame) time.sleep(cycle_time) diff --git a/examples/LTE modem/lte_serial.py b/examples/LTE modem/lte_serial.py new file mode 100644 index 00000000..fdb3514b --- /dev/null +++ b/examples/LTE modem/lte_serial.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python + +import requests +import time +import datetime +import xml.etree.ElementTree as ET +import re +import serial + +# -------------------------- CONFIGURATION -------------------------------- + +url_api = 'http://192.168.9.1/api/device/signal' # Address modem API +cycle_time = 5 # Pause between data frame +serial_port = '/tmp/ttyV1' # Serial port address +serial_speed = 9600 # Serial port baudrate + +# ------------------------------------------------------------------------- + +def get_value(marker): + string = tree.find(marker).text + value = re.search(r'(\-|)(\d+)(\.?)(\d*)', string).group(0) + # print('string=', string, ' value=', value) + return value + +serialPort = serial.Serial(port=serial_port, baudrate=serial_speed, bytesize=8, timeout=2, stopbits=serial.STOPBITS_ONE) + +while True: + xml_data = requests.get(url_api).text + tree = ET.XML(xml_data) + + cell = str(get_value('cell_id')) + rsrq = int(float(get_value('rsrq'))) + rsrp = int(get_value('rsrp')) + rssi = int(get_value('rssi')) + sinr = int(get_value('sinr')) + + pci = int(get_value('pci')) + mode = int(get_value('mode')) + ulbandwidth = int(get_value('ulbandwidth')) + dlbandwidth = int(get_value('dlbandwidth')) + band = int(get_value('band')) + ulfrequency = int(get_value('ulfrequency')) + dlfrequency = int(get_value('dlfrequency')) + + print(f'{datetime.datetime.now().strftime("%H-%M-%S")} CELL={cell} RSRQ={rsrq} RSRP={rsrp} RSSI={rssi} SINR={sinr}') + data_frame = f'/*{cell} ,{rsrq},{rsrp},{rssi},{sinr}*/\n' + # print(frame) + serialPort.write(data_frame.encode('utf-8')) + + time.sleep(cycle_time) diff --git a/examples/LTE modem/lte_udp.py b/examples/LTE modem/lte_udp.py index cf11ea19..e6bc87ab 100644 --- a/examples/LTE modem/lte_udp.py +++ b/examples/LTE modem/lte_udp.py @@ -43,7 +43,7 @@ while True: dlfrequency = int(get_value('dlfrequency')) print(f'{datetime.datetime.now().strftime("%H-%M-%S")} CELL={cell} RSRQ={rsrq} RSRP={rsrp} RSSI={rssi} SINR={sinr}') - data_frame = f'{rsrq},{rsrp},{rssi},{sinr},{cell}' + data_frame = f'/*{cell} ,{rsrq},{rsrp},{rssi},{sinr}*/\n' # print(frame) sock.sendto(data_frame.encode('utf-8'), (udp_ip, udp_port)) diff --git a/examples/README.md b/examples/README.md index dd958f96..31708874 100644 --- a/examples/README.md +++ b/examples/README.md @@ -15,9 +15,12 @@ Some examples also include Serial Studio project files (`*.json`) to simplify th - **Screenshot**: Example view in Serial Studio. ### 2. LTE modem -- **Description**: This example reads data of signal from LTE modem and transmits it over MQTT or UDP Socket. +- **Description**: This example reads data of signal quality from LTE modem and transmits it over Virtual Serial Port, MQTT or UDP Socket. - **Contents**: - - **lte_mqtt.py**: Python script for parsing data of signal from LTE modem API and send it over MQTT or UDP Socket. + - **lte.json**: Serial Studio project file for visualizing data of signal quality from LTE modem. + - **lte_mqtt.py**: Python script for parsing data and send it over MQTT. + - **lte_serial.py**: Python script for parsing data and send it over Virtual Serial Port. + - **lte_udp.py**: Python script for parsing data and send it over UDP Socket. - **README.md**: Setup and usage instructions. - **Screenshot**: Example view in Serial Studio.