Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
614 changes: 614 additions & 0 deletions New dashboard-1745359029061.json

Large diffs are not rendered by default.

Binary file added root/assets/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added root/assets/Pasted image 20250422233745.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added root/assets/Pasted image 20250422234213.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added root/assets/Pasted image 20250422234913.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added root/assets/Pasted image 20250422235459.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added root/assets/Pasted image 20250422235812.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added root/assets/Pasted image 20250423002833.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added root/assets/Pasted image 20250423002855.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added root/assets/Pasted image 20250423003238.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added root/assets/Pasted image 20250423003426.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added root/assets/Pasted image 20250423003701.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added root/assets/Pasted image 20250423003828.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added root/assets/Pasted image 20250423004001.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added root/assets/Pasted image 20250423005726.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
61 changes: 61 additions & 0 deletions root/report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
## Генерация данных
### 1 - Sensor.py
Начинаем разработку с создания ООП файла `sensor.py` с 4-мя типами датчиков. Создаем родительский класс датчика - Sensor.

![[1.png]]

На его основе создаем 4 подкласса: температура, давление, ток и влажность.

![[Pasted image 20250422233745.png]]

### 2 - Main.py

Создаем основной файл-клиент, который будет обеспечивать соединение с mqtt-брокером на второй машине.

![[Pasted image 20250423002855.png]]

### 3 - Сборка и запуск проекта

В Dockerfile пошагово описываем сборку образа и создаем первый образ с помощью команды `docker build`

![[Pasted image 20250422234913.png]]

## 2 - MQTT брокер

Для настройки протокола создаем файл `mosquitto.conf`. И описываем поднятие контейнера в compose-файле.
![[Pasted image 20250422235459.png]]

Связь между контейнерами будет обеспечена благодаря внешней сети mqtt-net.

Предварительно создаем ее с помощью команды: `docker network create mqtt-net --subnet=192.168.21.0/24 --gateway=192.168.21.1`

и проверяем перед запуском основных контейнеров.

![[Pasted image 20250422235812.png]]

Создаем образ нашего брокера и запускаем его. После запускаем клиента и наблюдаем, что подключение прошло успешно.
![[Pasted image 20250423002833.png]]

## 3 - Визуализация данных

Создаем место, где будут храниться данные полученные от клиента. В конфигурационном файле _influxdb-init.iql_ прописываем:
![[Pasted image 20250423003238.png]]

После чего настраиваем получение данных с помощью telegraf.
![[Pasted image 20250423003426.png]]

Для отображения данных будем использовать grafana.
Разворачиваем все три контейнера с помощью docker-compose файла.
![[Pasted image 20250423003701.png]]

Запуск прошел успешно.
![[Pasted image 20250423003828.png]]

Займемся настройкой графического интерфейса перейдя по localhost:3000
Видно, что данные генерируются, значит все контейнеры настроены корректно.

![[Pasted image 20250423004001.png]]

Смоделируем удобный дашборд для всех датчиков.

![[Pasted image 20250423005726.png]]
6 changes: 6 additions & 0 deletions root/vms/client/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM python:alpine3.20
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "main.py"]
48 changes: 48 additions & 0 deletions root/vms/client/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
services:
temp_sensor:
image: tremenbez/data
environment:
- SIM_HOST=192.168.21.10
- SIM_NAME=TEMP1
- SIM_PERIOD=5
- SIM_TYPE=temperature
networks:
mqtt-net:
ipv4_address: 192.168.21.11

pressure_sensor:
image: tremenbez/data
environment:
- SIM_HOST=192.168.21.10
- SIM_NAME=PRES1
- SIM_PERIOD=10
- SIM_TYPE=pressure
networks:
mqtt-net:
ipv4_address: 192.168.21.12

current_sensor:
image: tremenbez/data
environment:
- SIM_HOST=192.168.21.10
- SIM_NAME=CUR1
- SIM_PERIOD=3
- SIM_TYPE=current
networks:
mqtt-net:
ipv4_address: 192.168.21.13

humidity_sensor:
image: tremenbez/data
environment:
- SIM_HOST=192.168.21.10
- SIM_NAME=HUM1
- SIM_PERIOD=7
- SIM_TYPE=humidity
networks:
mqtt-net:
ipv4_address: 192.168.21.14

networks:
mqtt-net:
external: true
Empty file.
78 changes: 78 additions & 0 deletions root/vms/client/files/sensor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import random
import math
import time


class Sensor:
value: float
name: str
type: str

def __init__(self, name, interval):
self.name = name
self.interval = interval
self.value = None

def generate_new_value(self):
pass

def get_data(self):
return self.value

def run(self):
"""Запускает цикл генерации данных с заданным интервалом."""
while True:
self.generate_new_value()
print(f"Sensor {self.name} ({self.type}): {self.value}")
time.sleep(self.interval)


class Temperature(Sensor):
step = 10

def __init__(self, name, interval):
super().__init__(name, interval)
self.type = "temperature"

def generate_new_value(self):
"""Генерирует новое значение температуры."""
self.value = random.random() + self.step + 222 * 6


class Pressure(Sensor):
step = 15

def __init__(self, name, interval):
super().__init__(name, interval)
self.type = "pressure"

def generate_new_value(self):
"""Генерирует новое значение давления."""
self.value = random.random() + self.step


class Current(Sensor):
step = 20

def __init__(self, name, interval):
super().__init__(name, interval)
self.type = "current"

def generate_new_value(self):
"""Генерирует новое значение тока."""
import math
self.value = math.sin(self.step)
self.step += 1


class Humidity(Sensor):
step = 25

def __init__(self, name, interval):
super().__init__(name, interval)
self.type = "humidity"

def generate_new_value(self):
"""Генерирует новое значение влажности."""
self.value = random.uniform(self.step, self.step + 20)

51 changes: 51 additions & 0 deletions root/vms/client/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import paho.mqtt.client as paho
import time
import logging
from os import environ
from files.sensor import *

# Настройка логирования
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")

# Настройка переменных среды
broker = environ.get("SIM_HOST", "localhost")
port = int(environ.get("SIM_PORT", 1883))
name = environ.get("SIM_NAME", "sensor")
period = int(environ.get("SIM_PERIOD", 1)) # SIM_PERIOD используется как interval
type_sim = environ.get("SIM_TYPE", "temperature")

# Проверка допустимых типов датчиков
sensors = {
"temperature": Temperature,
"pressure": Pressure,
"current": Current,
"humidity": Humidity
}
if type_sim not in sensors:
raise ValueError(f"Unknown sensor type: {type_sim}. Allowed types: {list(sensors.keys())}")

# Создание экземпляра датчика
sensor = sensors[type_sim](name=name, interval=period)

# Callback для публикации
def on_publish(client, userdata, result):
print(f"Data published successfully: {userdata}")

# Подключение к брокеру
client = paho.Client(sensor.name)
client.on_publish = on_publish
try:
client.connect(broker, port)
except Exception as e:
logging.error(f"Failed to connect to broker: {e}")
exit(1)

# Публикация данных
while True:
try:
sensor.generate_new_value()
topic = f"sensors/{sensor.type}/{sensor.name}"
ret = client.publish("sensors/" + sensor.type + "/" + sensor.name, sensor.get_data())
except Exception as e:
logging.error(f"Error during publishing: {e}")
time.sleep(period)
2 changes: 2 additions & 0 deletions root/vms/client/mosquitto/mosquitto.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
listener 1883
allow_anonymous true
1 change: 1 addition & 0 deletions root/vms/client/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
paho_mqtt==1.6.1
15 changes: 15 additions & 0 deletions root/vms/gw/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
services:
broker:
image: eclipse-mosquitto
container_name: broker
volumes:
- ./mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf
ports:
- "1883:1883"
networks:
mqtt-net:
ipv4_address: 192.168.21.10

networks:
mqtt-net:
external: true
2 changes: 2 additions & 0 deletions root/vms/gw/mosquitto/mosquitto.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
listener 1883
allow_anonymous true
44 changes: 44 additions & 0 deletions root/vms/server/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
services:
influxdb:
image: influxdb:1.8
container_name: influxdb
volumes:
- ./influxdb/scripts:/docker-entrypoint-initdb.d
- influx_data:/var/lib/influxdb
networks:
mqtt-net:
ipv4_address: 192.168.21.20

telegraf:
image: telegraf
container_name: telegraf
volumes:
- ./telegraf/telegraf.conf:/etc/telegraf/telegraf.conf:ro
networks:
mqtt-net:
ipv4_address: 192.168.21.21

grafana:
image: grafana/grafana
container_name: grafana
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/datasources.yaml:/etc/grafana/provisioning/datasources/datasources.yaml
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
restart: unless-stopped
ports:
- "3000:3000"
networks:
mqtt-net:
ipv4_address: 192.168.21.22

volumes:
influx_data: {}
grafana_data: {}

networks:
mqtt-net:
external: true
13 changes: 13 additions & 0 deletions root/vms/server/grafana/datasources.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: 1

datasources:
- name: InfluxDB_v1
type: influxdb
access: proxy
database: sensors
user: telegraf
url: http://influxdb:8086
jsonData:
httpMode: GET
secureJsonData:
password: telegraf
2 changes: 2 additions & 0 deletions root/vms/server/influxdb/scripts/influxdb-init.iql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CREATE DATABASE sensors;
CREATE USER telegraf WITH PASSWORD 'telegraf' WITH ALL PRIVILEGES;
14 changes: 14 additions & 0 deletions root/vms/server/telegraf/telegraf.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[[inputs.mqtt_consumer]]
servers = ["tcp://broker:1883"] # Имя сервиса брокера
topics = [
"sensors/#"
]
data_format = "value"
data_type = "float"

[[outputs.influxdb]]
urls = ["http://influxdb:8086"] # Имя сервиса InfluxDB
database = "sensors"
skip_database_creation = true
username = "telegraf"
password = "telegraf"