From e3393a15767be2b306cc1d0a845a2df14d7b616c Mon Sep 17 00:00:00 2001 From: "Fabio A. Castiblanco" Date: Tue, 9 Nov 2021 14:40:30 -0500 Subject: [PATCH 1/7] Added cell_nats service --- .github/workflows/build-and-push-services.yml | 1 + services/cell_nats/Dockerfile | 38 +++++++++ services/cell_nats/cell_nats.py | 83 +++++++++++++++++++ services/cell_nats/docker-compose-example.yml | 10 +++ services/cell_nats/requirements.txt | 2 + 5 files changed, 134 insertions(+) create mode 100644 services/cell_nats/Dockerfile create mode 100755 services/cell_nats/cell_nats.py create mode 100644 services/cell_nats/docker-compose-example.yml create mode 100644 services/cell_nats/requirements.txt diff --git a/.github/workflows/build-and-push-services.yml b/.github/workflows/build-and-push-services.yml index b556f869..6db55b2b 100644 --- a/.github/workflows/build-and-push-services.yml +++ b/.github/workflows/build-and-push-services.yml @@ -19,6 +19,7 @@ jobs: - cand - j1939d - gps-exporter + - cell_nats runs-on: ubuntu-latest diff --git a/services/cell_nats/Dockerfile b/services/cell_nats/Dockerfile new file mode 100644 index 00000000..f97f3d8e --- /dev/null +++ b/services/cell_nats/Dockerfile @@ -0,0 +1,38 @@ +# BUILDER +FROM python:3 as builder + +WORKDIR /usr/src/app + +# Download latest listing of available packages +RUN apt-get -y update + +# Needed for building dbus-python +RUN apt-get install -y --no-install-recommends python3-pip pkg-config libdbus-1-dev python3-dbus + +# Activate virtualenv +RUN python -m venv /opt/venv + +# Make sure we use the virtualenv +ENV PATH="/opt/venv/bin:$PATH" + +# Copy requirements and build with pip +COPY requirements.txt ./ +RUN pip3 install -r requirements.txt + +# RUNTIME +FROM python:3 as runtime + +WORKDIR /usr/src/app + +# Install runtime deps +RUN apt-get -y update && apt-get install -y --no-install-recommends python3-dbus + +# Copy compiled venv from builder +COPY --from=builder /opt/venv /opt/venv + +# Make sure we use the virtualenv +ENV PATH="/opt/venv/bin:$PATH" + +# Copy script over and run +COPY cell_logger.py . +CMD [ "./cell_nats.py" ] diff --git a/services/cell_nats/cell_nats.py b/services/cell_nats/cell_nats.py new file mode 100755 index 00000000..379d64ec --- /dev/null +++ b/services/cell_nats/cell_nats.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 + +import dbus +import datetime +import time +from pynats2 import NATSClient + +def get_signal_stats(): + + modem_signal_iface = 'org.freedesktop.ModemManager1.Modem.Signal' + + modem_manager_object = bus.get_object('org.freedesktop.ModemManager1', + '/org/freedesktop/ModemManager1') + modem_manager_iface = dbus.Interface(modem_manager_object, + 'org.freedesktop.DBus.ObjectManager') + + modem_data = modem_manager_iface.GetManagedObjects() + +#Extract modem path from the DBus data dictionary + + modem_path = list(modem_data.keys())[0] + +#Check if the 'Lte' dictionary has signal values assigned. If no values are +#found, assume the modem is connected to a 'Umts' network. + + if(list(modem_data[modem_path][modem_signal_iface]['Lte'].keys())): + + cell_tech = 'Lte' + + else: + + cell_tech = 'Umts' + +#Get signal info from the dictionary. If there is no data, assume the modem +#ID has changed and needs to have the signal info update rate reset. + + try: + + signal_dict = dict(modem_data[modem_path][modem_signal_iface][cell_tech]) + + signal = {} + + for item in signal_dict: + # Truncate all floats to 1 decimal point + signal[str(item)] = float(f'{signal_dict[item]:.1f}') + + signal["tech"] = cell_tech.lower() + + except(KeyError): + + set_update_rate(modem_path) + + return '' + + return signal + +bus = dbus.SystemBus() + + +def set_update_rate(modem_path): + + modem_object = bus.get_object('org.freedesktop.ModemManager1', modem_path) + modem_iface = dbus.Interface(modem_object, + 'org.freedesktop.ModemManager1.Modem.Signal') + modem_iface.Setup(dbus.UInt32(1)) + +print("Starting cell_nats") + + +if __name__ == '__main__': + + while(True): + + timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + data = get_signal_stats() + with NATSClient() as client: + for item in data: + client.publish(f'cell.{item}', + payload=bytes(str({'value' : data[item], + 'time' : timestamp}), + 'utf-8')) + + time.sleep(1) diff --git a/services/cell_nats/docker-compose-example.yml b/services/cell_nats/docker-compose-example.yml new file mode 100644 index 00000000..c51306f2 --- /dev/null +++ b/services/cell_nats/docker-compose-example.yml @@ -0,0 +1,10 @@ +version: '3.9' +services: + cell_nats: + build: + context: ../cell_nats + restart: unless-stopped + depends_on: + - nats + volumes: + - /var/run/dbus:/var/run/dbus:rw diff --git a/services/cell_nats/requirements.txt b/services/cell_nats/requirements.txt new file mode 100644 index 00000000..3f7edfec --- /dev/null +++ b/services/cell_nats/requirements.txt @@ -0,0 +1,2 @@ +dbus-python +pynats2 From 31e86197bf97ab9b5b2072aa64c5a8a8250642b7 Mon Sep 17 00:00:00 2001 From: "Fabio A. Castiblanco" Date: Tue, 9 Nov 2021 15:08:49 -0500 Subject: [PATCH 2/7] Fixed copy/paste typo in Dockerfile --- services/cell_nats/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/cell_nats/Dockerfile b/services/cell_nats/Dockerfile index f97f3d8e..80f4365f 100644 --- a/services/cell_nats/Dockerfile +++ b/services/cell_nats/Dockerfile @@ -34,5 +34,5 @@ COPY --from=builder /opt/venv /opt/venv ENV PATH="/opt/venv/bin:$PATH" # Copy script over and run -COPY cell_logger.py . +COPY cell_nats.py . CMD [ "./cell_nats.py" ] From 4e606b49deae614bcab4071e82569c00e9c76fab Mon Sep 17 00:00:00 2001 From: "Fabio A. Castiblanco" Date: Sun, 25 Sep 2022 20:04:40 -0400 Subject: [PATCH 3/7] changed data payload to cell.signal NATS topic --- services/cell_nats/Dockerfile | 2 +- services/cell_nats/cell_nats.py | 41 +++++++++++++++------------------ 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/services/cell_nats/Dockerfile b/services/cell_nats/Dockerfile index 80f4365f..44fbee2d 100644 --- a/services/cell_nats/Dockerfile +++ b/services/cell_nats/Dockerfile @@ -7,7 +7,7 @@ WORKDIR /usr/src/app RUN apt-get -y update # Needed for building dbus-python -RUN apt-get install -y --no-install-recommends python3-pip pkg-config libdbus-1-dev python3-dbus +RUN apt-get install -y --no-install-recommends python3-pip pkg-config libdbus-1-3 libdbus-1-dev python3-dbus dbus # Activate virtualenv RUN python -m venv /opt/venv diff --git a/services/cell_nats/cell_nats.py b/services/cell_nats/cell_nats.py index 379d64ec..641a8ae7 100755 --- a/services/cell_nats/cell_nats.py +++ b/services/cell_nats/cell_nats.py @@ -3,28 +3,29 @@ import dbus import datetime import time +import os from pynats2 import NATSClient def get_signal_stats(): modem_signal_iface = 'org.freedesktop.ModemManager1.Modem.Signal' - modem_manager_object = bus.get_object('org.freedesktop.ModemManager1', + modem_manager_object = bus.get_object('org.freedesktop.ModemManager1', '/org/freedesktop/ModemManager1') - modem_manager_iface = dbus.Interface(modem_manager_object, + modem_manager_iface = dbus.Interface(modem_manager_object, 'org.freedesktop.DBus.ObjectManager') modem_data = modem_manager_iface.GetManagedObjects() #Extract modem path from the DBus data dictionary - modem_path = list(modem_data.keys())[0] + modem_path = list(modem_data.keys())[0] #Check if the 'Lte' dictionary has signal values assigned. If no values are #found, assume the modem is connected to a 'Umts' network. if(list(modem_data[modem_path][modem_signal_iface]['Lte'].keys())): - + cell_tech = 'Lte' else: @@ -37,7 +38,6 @@ def get_signal_stats(): try: signal_dict = dict(modem_data[modem_path][modem_signal_iface][cell_tech]) - signal = {} for item in signal_dict: @@ -47,15 +47,12 @@ def get_signal_stats(): signal["tech"] = cell_tech.lower() except(KeyError): - + set_update_rate(modem_path) - - return '' - - return signal -bus = dbus.SystemBus() + return '' + return signal def set_update_rate(modem_path): @@ -64,20 +61,18 @@ def set_update_rate(modem_path): 'org.freedesktop.ModemManager1.Modem.Signal') modem_iface.Setup(dbus.UInt32(1)) -print("Starting cell_nats") - if __name__ == '__main__': - while(True): - - timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + print("Starting cell_nats") + bus = dbus.SystemBus() + + while(True): + data = get_signal_stats() + data['time'] = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ") + subject = os.getenv('AVENA_PREFIX') + ".cell.signal" with NATSClient() as client: - for item in data: - client.publish(f'cell.{item}', - payload=bytes(str({'value' : data[item], - 'time' : timestamp}), - 'utf-8')) - - time.sleep(1) + client.publish(subject, payload=bytes(str(data), 'utf-8')) + + time.sleep(1) From 1167137cbc2c421df70332dee9d3c0ae606d2398 Mon Sep 17 00:00:00 2001 From: "Fabio A. Castiblanco" Date: Wed, 28 Sep 2022 16:48:33 -0400 Subject: [PATCH 4/7] added proper JSON formatting to payload Signed-off-by: Fabio A. Castiblanco --- services/cell_nats/cell_nats.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/cell_nats/cell_nats.py b/services/cell_nats/cell_nats.py index 641a8ae7..be1d8704 100755 --- a/services/cell_nats/cell_nats.py +++ b/services/cell_nats/cell_nats.py @@ -4,6 +4,7 @@ import datetime import time import os +import json from pynats2 import NATSClient def get_signal_stats(): @@ -73,6 +74,6 @@ def set_update_rate(modem_path): data['time'] = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ") subject = os.getenv('AVENA_PREFIX') + ".cell.signal" with NATSClient() as client: - client.publish(subject, payload=bytes(str(data), 'utf-8')) + client.publish(subject, payload=bytes(json.dumps(data)), 'utf-8')) time.sleep(1) From 00310d31052d4a74d902cfadd441e9981ae94c05 Mon Sep 17 00:00:00 2001 From: "Fabio A. Castiblanco" Date: Mon, 3 Oct 2022 18:53:21 -0400 Subject: [PATCH 5/7] temporarily removed other services from build flow Signed-off-by: Fabio A. Castiblanco --- .github/workflows/build-and-push-services.yml | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build-and-push-services.yml b/.github/workflows/build-and-push-services.yml index 6db55b2b..2835f597 100644 --- a/.github/workflows/build-and-push-services.yml +++ b/.github/workflows/build-and-push-services.yml @@ -9,16 +9,16 @@ jobs: strategy: matrix: service: - - gps2tsdb - - gps_nats - - oada_upload - - cell_logger - - can_watchdog - - can_logger - - socketcand - - cand - - j1939d - - gps-exporter + # - gps2tsdb + # - gps_nats + # - oada_upload + # - cell_logger + # - can_watchdog + # - can_logger + # - socketcand + # - cand + # - j1939d + # - gps-exporter - cell_nats runs-on: ubuntu-latest From 8002de4f86a10fa7b499e32f5de41ab639d43734 Mon Sep 17 00:00:00 2001 From: "Fabio A. Castiblanco" Date: Mon, 3 Oct 2022 19:05:02 -0400 Subject: [PATCH 6/7] added cmake to arm build deps Signed-off-by: Fabio A. Castiblanco --- services/cell_nats/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/cell_nats/Dockerfile b/services/cell_nats/Dockerfile index 44fbee2d..9d61c1d3 100644 --- a/services/cell_nats/Dockerfile +++ b/services/cell_nats/Dockerfile @@ -7,7 +7,7 @@ WORKDIR /usr/src/app RUN apt-get -y update # Needed for building dbus-python -RUN apt-get install -y --no-install-recommends python3-pip pkg-config libdbus-1-3 libdbus-1-dev python3-dbus dbus +RUN apt-get install -y --no-install-recommends python3-pip pkg-config libdbus-1-3 libdbus-1-dev python3-dbus dbus cmake # Activate virtualenv RUN python -m venv /opt/venv From b0c8795f62223bec43d833616341800151cb05de Mon Sep 17 00:00:00 2001 From: "Fabio A. Castiblanco" Date: Tue, 4 Oct 2022 09:12:31 -0400 Subject: [PATCH 7/7] fixed typo in cell_nats.py Signed-off-by: Fabio A. Castiblanco --- services/cell_nats/cell_nats.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/cell_nats/cell_nats.py b/services/cell_nats/cell_nats.py index be1d8704..28ac3d24 100755 --- a/services/cell_nats/cell_nats.py +++ b/services/cell_nats/cell_nats.py @@ -74,6 +74,6 @@ def set_update_rate(modem_path): data['time'] = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ") subject = os.getenv('AVENA_PREFIX') + ".cell.signal" with NATSClient() as client: - client.publish(subject, payload=bytes(json.dumps(data)), 'utf-8')) + client.publish(subject, payload=bytes(str(json.dumps(data)), 'utf-8')) time.sleep(1)