Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(microservices): add LiDAR, Weight, Peripheral Analytics, and Grafana integration #655

Merged
merged 46 commits into from
Feb 19, 2025

Conversation

naman-ranka
Copy link
Contributor

@naman-ranka naman-ranka commented Jan 28, 2025

Introduces a single common-service for managing both LiDAR and Weight sensors, configurable through environment variables for MQTT, Kafka, and HTTP publishing. Integrates Grafana (with a pre-loaded dashboard and data source) for real-time visualization over MQTT.
Closes #537

PR Checklist

  • Added label to the Pull Request for easier discoverability and search
  • Commit Message meets guidelines as indicated in the URL https://github.com/intel-retail/automated-self-checkout/blob/main/CONTRIBUTING.md
  • Every commit is a single defect fix and does not mix feature addition or changes
  • Unit Tests have been added for new changes
  • Updated Documentation as relevant to the changes
  • All commented code has been removed
  • If you've added a dependency, you've ensured license is compatible with repository license and clearly outlined the added dependency.
  • PR change contains code related to security
  • PR introduces changes that breaks compatibility with other modules (If YES, please provide details below)

What are you changing?

This PR introduces the following features:

1. Overview

  1. Common-Service
  • LiDAR & Weight Sensors handled within one container (common-service).

  • Each sensor has its own configuration (e.g., sensor ID, port, mock mode).

  • Publishes data to one or more protocols:

    • MQTT (e.g., broker host, port, topic)

    • Kafka (e.g., bootstrap server, topic)

    • HTTP (e.g., URL endpoint)

  • Uses a shared framework (publisher.py & config.py) plus two apps (lidar_app.py, weight_app.py).

  1. Environment Variables & Configuration
  • Fully controlled via Fully controlled via docker-compose.yml .

  • Example snippet for LiDAR (2 sensors) & Weight (2 sensors):

environment:
  # LiDAR environment variables
  LIDAR_COUNT: 2
  LIDAR_SENSOR_ID_1: lidar-001
  LIDAR_SENSOR_ID_2: lidar-002
  LIDAR_MOCK_1: "true"
  LIDAR_MOCK_2: "true"
  LIDAR_PORT_1: /dev/ttyUSB0
  LIDAR_PORT_2: /dev/ttyUSB1
  LIDAR_MQTT_ENABLE: "true"
  LIDAR_MQTT_BROKER_HOST: mqtt-broker_1
  LIDAR_MQTT_BROKER_PORT: 1883
  LIDAR_KAFKA_ENABLE: "true"
  KAFKA_BOOTSTRAP_SERVERS: kafka:9093
  LIDAR_KAFKA_TOPIC: "lidar-data"
  LIDAR_MQTT_TOPIC: "lidar/data"
  LIDAR_HTTP_ENABLE: "true"
  LIDAR_HTTP_URL: "http://localhost:5000/api/lidar_data"
  LIDAR_PUBLISH_INTERVAL: 1.0
  LIDAR_LOG_LEVEL: INFO

  # Weight environment variables
  WEIGHT_COUNT: 2
  WEIGHT_SENSOR_ID_1: weight-001
  WEIGHT_SENSOR_ID_2: weight-002
  WEIGHT_MOCK_1: "true"
  WEIGHT_MOCK_2: "true"
  WEIGHT_PORT_1: /dev/ttyUSB2
  WEIGHT_PORT_2: /dev/ttyUSB3
  WEIGHT_MQTT_ENABLE: "true"
  WEIGHT_MQTT_BROKER_HOST: mqtt-broker_1
  WEIGHT_MQTT_BROKER_PORT: 1883
  WEIGHT_KAFKA_ENABLE: "false"
  WEIGHT_MQTT_TOPIC: "weight/data"
  WEIGHT_HTTP_ENABLE: "false"
  WEIGHT_PUBLISH_INTERVAL: 1.0
  WEIGHT_LOG_LEVEL: INFO
  • Change true/false to enable or disable each protocol.

  • Adjust intervals, logging levels, or sensor counts as needed.

  1. Kafka & Zookeeper
  • Included in the docker-compose.yml file.

  • By default, Kafka listens on PLAINTEXT://:9093.

  1. MQTT Broker
  • An Eclipse Mosquitto container, usually accessible at mqtt-broker_1:1883.
  1. Grafana Integration
  • A Grafana container is provided with:
    • Preloaded Dashboard : Sensor-Analytics.

    • Datasource Provisioning : An MQTT data source is set up (may require manual URI update in Grafana’s Data Sources if the hostname differs).


Issue this PR will close

close: #537
(Build a microservice to get sensor details from a Lidar sensor).

Test Instructions :

Run the Demo

  • Start all services using the following command:
    make run-demo
    

A. MQTT (via Grafana)

  1. Access Grafana
  1. Preloaded Dashboard :
  • Look for Sensor-Analytics in the Dashboards list.

  • Panels should be configured for:

    • lidar/data

    • weight/data

  • If you see no data:

    • Go to Configuration > Data Sources and confirm the MQTT data source URI is set to tcp://mqtt-broker_1:1883 or tcp://mqtt-broker:1883 (depending on your Docker network name).

    • Click Test to ensure it connects.

  1. Real-Time Visualization :
  • You should see sensor data updating in each panel.

  • Adjust the refresh interval (top-right in Grafana) if needed.


B. Kafka Publishing

  1. Enable Kafka
  • In your docker-compose.yml, set:
LIDAR_KAFKA_ENABLE: "true"
WEIGHT_KAFKA_ENABLE: "true"
  1. Test from inside the common-service container:
docker exec asc_common_service python kafka_publisher_test.py --topic lidar-data
  • This script subscribes to the lidar-data topic.

  • Verify it prints incoming LiDAR messages published to Kafka.

  1. (Optional) Use other Kafka clients to confirm message flow.

C. HTTP Publishing

This feature can be verified in two ways :

  1. Local HTTP Test (Inside Docker)

    1. In your docker-compose.yml, set:
    LIDAR_HTTP_ENABLE: "true"
    LIDAR_HTTP_URL: "http://localhost:5000/api/lidar_data"
    1. Start the containers:
    make run-demo
    1. Run the test script inside the common-service container:
    docker exec asc_common_service python http_publisher_test.py
    1. The Flask server within common-service will print the received LiDAR data, confirming that HTTP publishing is working.
  2. Webhook.site for External Validation

    1. Go to Webhook.site and generate a unique URL.

    2. Set LIDAR_HTTP_URL in docker-compose.yml to that URL, for example:

    LIDAR_HTTP_ENABLE: "true"
    LIDAR_HTTP_URL: "https://webhook.site/abcdef12-3456-7890-..."
    1. Restart the containers:
    make run-demo
    1. Observe the Recent Requests section on Webhook.site to see incoming LiDAR data in real time.

4. Additional Notes

  • Mock Mode : If you set LIDAR_MOCK_1 or WEIGHT_MOCK_1 to "true", the service publishes randomized demo data instead of reading from hardware.

  • Multi-Sensor Support : LIDAR_COUNT and WEIGHT_COUNT define how many sensors to handle. Each has its own environment variables (e.g., LIDAR_SENSOR_ID_1, LIDAR_PORT_1, etc.).

  • Topic & Interval Config : The publish interval can be tuned (e.g., LIDAR_PUBLISH_INTERVAL, WEIGHT_PUBLISH_INTERVAL), and each sensor’s MQTT/Kafka topic is customizable.

…Kafka/HTTP publishing

- Implement Python microservice to ingest real or mock Lidar data
- Publish sensor data to MQTT, Kafka, or HTTP (controlled by environment vars)
- Add logging, retry logic, and graceful shutdown handling
- Integrate with existing Makefile and Docker Compose

Signed-off-by: Naman Yeshwanth Kumar <[email protected]>
…DAR and weight data

- Subscribes to LiDAR and weight sensor MQTT topics
- Performs analytics to calculate item density (weight per LiDAR point)
- Publishes analytics results to a dedicated MQTT topic ()
- Includes robust logging and error handling

Signed-off-by: Naman Yeshwanth Kumar <[email protected]>
- Introduced Grafana container configuration in docker-compose.yml
- Configured Grafana to depend on mqtt-broker_1

Signed-off-by: Naman Yeshwanth Kumar <[email protected]>
@ejlee3
Copy link
Contributor

ejlee3 commented Jan 28, 2025

Can you please update the title of your PR with a conventional commit style message?

@naman-ranka naman-ranka changed the title I 537 Add microservices for LiDAR, Weight, Peripheral Analytics, and Grafana integration (#537) Jan 28, 2025
@NeethuES-intel
Copy link
Contributor

@naman-ranka can you fix the security issues flagged by github-advanced-security bot. Also please follow the git conventional commit format for the PR title -
https://github.com/intel-retail/automated-self-checkout/blob/main/CONTRIBUTING.md

<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>

type here should be feat.

@naman-ranka naman-ranka changed the title Add microservices for LiDAR, Weight, Peripheral Analytics, and Grafana integration (#537) feat(microservices): add LiDAR, Weight, Peripheral Analytics, and Grafana integration Introduced microservices for LiDAR and Weight sensors with configurable data publishing. Added Peripheral Analytics service to process and publish computed metrics. Integrated Grafana for real-time data visualization via MQTT. Closes #537 Jan 30, 2025
@naman-ranka naman-ranka changed the title feat(microservices): add LiDAR, Weight, Peripheral Analytics, and Grafana integration Introduced microservices for LiDAR and Weight sensors with configurable data publishing. Added Peripheral Analytics service to process and publish computed metrics. Integrated Grafana for real-time data visualization via MQTT. Closes #537 feat(microservices): add LiDAR, Weight, Peripheral Analytics, and Grafana integration Jan 30, 2025
- Added required copyright header to newly created Python files.
- Ensures compliance with repository licensing guidelines.

Signed-off-by: Naman Yeshwanth Kumar <[email protected]>
@naman-ranka

This comment was marked as off-topic.

@naman-ranka naman-ranka deleted the I-537 branch January 30, 2025 18:31
@naman-ranka naman-ranka restored the I-537 branch January 30, 2025 18:32
@naman-ranka

This comment was marked as off-topic.

Copy link
Contributor

@NeethuES-intel NeethuES-intel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@naman-ranka From the Design, app.py, Dockerfile and requirements.txt look the same for all 3 services. What is the difference between app.py in each of these services ? Can you consolidate all into one service then ? Looks like only sensor data type is changing here. Are you adding any business logic to any of them to make them unique ? Why duplicate ?

Copy link
Contributor

@antoniomtz antoniomtz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@naman-ranka I was able to run your app, but I had to make so many changes in the docker-compose specifically mqtt and all the networks so the services can communicate with each other. Also, you can create a dashboard template to show the data for demo purposes.
Screenshot from 2025-01-30 18-36-03

…blisher logic

- Consolidated sensor-specific directories into a single common-sources directory
- Implemented a common publisher.py to streamline all types of publishing (MQTT, Kafka, HTTP) across sensor types
- Added support for multiple sensors of the same type to improve scalability
- Introduced a custom MQTT Docker configuration to resolve previous network configuration issues
- Removed redundant directories to simplify the codebase

Signed-off-by: Naman Yeshwanth Kumar <[email protected]>
naman-ranka and others added 20 commits February 14, 2025 00:49
- Introduced Grafana container configuration in docker-compose.yml
- Configured Grafana to depend on mqtt-broker_1

Signed-off-by: Naman Yeshwanth Kumar <[email protected]>
- Added required copyright header to newly created Python files.
- Ensures compliance with repository licensing guidelines.

Signed-off-by: Naman Yeshwanth Kumar <[email protected]>
…blisher logic

- Consolidated sensor-specific directories into a single common-sources directory
- Implemented a common publisher.py to streamline all types of publishing (MQTT, Kafka, HTTP) across sensor types
- Added support for multiple sensors of the same type to improve scalability
- Introduced a custom MQTT Docker configuration to resolve previous network configuration issues
- Removed redundant directories to simplify the codebase

Signed-off-by: Naman Yeshwanth Kumar <[email protected]>
- Integrated a Grafana dashboard to visualize and analyze data from LiDAR and weight sensors.
- Configured dashboard panels to display time series, sensor counts, and analytics metrics.
- Dashboard pulls data from our existing MQTT data source for real-time insights.

Signed-off-by: Naman Yeshwanth Kumar <[email protected]>
- Implemented Grafana datasource provisioning via YAML to auto-load the MQTT datasource.
- Updated dashboard.json to improve data visualization and remove manual refresh requirement.
- Note: Datasource URL still needs to be manually set due to Grafana's provisioning limitations.

Signed-off-by: Naman Yeshwanth Kumar <[email protected]>
- Added  to test HTTP publishing inside .
- Updated  to expose port 5000 for internal HTTP testing.
- Verified HTTP publishing via Webhook.site without modifying .

Signed-off-by: Naman Yeshwanth Kumar <[email protected]>
…tion

- Updated Kafka Docker configuration for improved stability and compatibility.
- Added  to verify message consumption from any user-defined topic.
- Supports command-line arguments for dynamic topic selection and timeout configuration.
- Ensures Kafka messages are received correctly and provides meaningful test results.

Signed-off-by: Naman Yeshwanth Kumar <[email protected]>
- Added a README file inside the common-service directory.
- Includes details on setup, environment variables, and testing procedures.

Signed-off-by: Naman Yeshwanth Kumar <[email protected]>
Signed-off-by: Naman Yeshwanth Kumar <[email protected]>
Replaced COPY commands with volumes in docker-compose.yml
Allows dynamic updates to dashboards and datasources without rebuilding the image

Signed-off-by: Naman Yeshwanth Kumar <[email protected]>
… image

Replaced custom-built Mosquitto image with the official eclipse-mosquitto:2.0.18.
Mounted mosquitto.conf as a volume to allow dynamic updates without rebuilding.

Signed-off-by: Naman Yeshwanth Kumar <[email protected]>
Signed-off-by: Naman Yeshwanth Kumar <[email protected]>
Signed-off-by: Naman Yeshwanth Kumar <[email protected]>
Copy link
Contributor

@NeethuES-intel NeethuES-intel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job getting the PR comments closed.

Copy link
Contributor

@ejlee3 ejlee3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - Nice work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request Intermediate
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Build a microservice to get sensor details from a Lidar sensor
6 participants