Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
72a4c31
Добавлен дочерний класс для четвертого датчика.
14Po Apr 3, 2024
7d3b223
Добавлен четвертый тип датчика - СО.
14Po Apr 3, 2024
ea1a7a2
Указана версия библиотеки paho_mqtt.
14Po Apr 3, 2024
67ac867
Настройка контейнеров для разных типов датчиков.
14Po Apr 3, 2024
24d2ce4
Обновление настройки контейнеров.
14Po Apr 3, 2024
3ba5fa3
Добавлен bash-скрипт для vmA.
14Po Apr 4, 2024
4268bc3
Изменен IP в конфигурации контейнеров.
14Po Apr 4, 2024
d89101f
Добавлена переменная окружения с IP-адресом на Linux B.
14Po Apr 4, 2024
d8102e1
Скрипт для Linux C.
14Po Apr 4, 2024
035e1fd
Настроен конфигурационный файл для брокера.
14Po Apr 4, 2024
e61a6b1
Настроен файрвол.
14Po Apr 5, 2024
7341f1e
Добавлен скрипт для Linux C. Внесены изменения в скрипт Linux A.
14Po Apr 6, 2024
bb99a5c
Изменена используемая версия Python в симуляторе -> Python:alpine 3.19
14Po Apr 11, 2024
bc6363e
Изменен IP-адресс на адресс локальной машины
14Po Apr 11, 2024
10f0442
Обновлен IP-адресс MQTT-брокера
14Po Apr 11, 2024
4d9c783
JSON-файл дашборда Grafana
14Po Apr 11, 2024
93cdaef
Добавлен конфигурационный файл для запуска брокера
14Po Apr 12, 2024
d1c556e
Внесены изменения отображения данных в JSON-файл.
14Po Apr 12, 2024
e9a3647
Добалвен отчет.
14Po Apr 12, 2024
e82a0b9
Удалены ненужные скрины
14Po Apr 12, 2024
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
334 changes: 334 additions & 0 deletions REPORT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,334 @@
# Шаг 1: Разработка Simulator для генерации данных

В файле `sensor.py` создаем четвертый тип датчиков *CO*, прназначение которого измерять концентарцию угарного газа.

```python
class CO(Sensor):
step = 0

def __init__(self,name):
super().__init__(name)
self.type = "carbon oxid"

def generate_new_value(self):
self.value = self.step * 1e6
self.step = self.step + 0.001
```

Далее в файле `main.py` реализовуем клиента, который подключается к mqtt брокеру и публикует сообщения.


```python
import paho.mqtt.client as paho
from os import environ
import time

from entity.sensor import *

broker = "localhost" if "SIM_HOST" not in environ.keys() else environ["SIM_HOST"]
port = 1883 if "SIM_PORT" not in environ.keys() else environ["SIM_PORT"]
name = "sensor" if "SIM_NAME" not in environ.keys() else environ["SIM_NAME"]
period = 1 if "SIM_PERIOD" not in environ.keys() else int(environ["SIM_PERIOD"])
type_sim = "temperature" if "SIM_TYPE" not in environ.keys() else environ["SIM_TYPE"]

sensors = {"temperature": Temperature, "pressure": Pressure, "current": Current, "carbon_oxid": CO}


def on_publish(client, userdata, result): # create function for callback
print(f"data published {userdata}")
pass


sensor = sensors[type_sim](name=name)
client1 = paho.Client(sensor.name) # create client object
client1.on_publish = on_publish # assign function to callback
client1.connect(broker, port) # establish connection
while True:
sensor.generate_new_value()
ret = client1.publish("sensors/" + sensor.type + "/" + sensor.name, sensor.get_data()) # publish
time.sleep(period)
```


В `Dockerfile`, необходимом для того, что создать образ, указываем следуюещие инструкции:

``` Dockerfile
FROM python:alpine3.19
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "main.py"]
```

Инструкция `FROM` инициализирует новый этап сборки и устанавливает базовый образ для последующих инструкций. `WORKDIR` создает рабочий каталог для последующих инструкций `Dockerfile`. Инструкция `COPY` копирует файл *requirements.txt* из источника в указанное место внутри образа.
Инструкция `RUN`задает команды, которые следует выполнить и поместить в новый образ контейнера. `RUN` описывает команду с аргументами, которую нужно выполнить когда контейнер будет запущен.

Содержимое файла *requirements.txt* приведено ниже:
`paho_mqtt==1.6.1`

*paho_mqtt* предоставляет клиентский класс, который позволяет приложениям подключаться к MQTT-брокеру для публикации сообщений.

После проделанных выше опреаций можно создать образ командой:

`docker build -t polinazhirakova/data-simulator . `

Таким образом мы создали образ, из которого можно развернуть контейнер.

<p align="center">
<img width=100% src = "assets\images\image-data-simulator.png">
</p>

Собтвенно запустив контейнер через

`docker run -e SIM_HOST=192.168.0.101 -e SIM_TYPE=temperature --name test -d polinazhirakova/data-simulator`

Получим ошибку, т.к. брокер еще не настроен.

<p align="center">
<img width=100% src = "assets\images\example_run_with_error.png">
</p>


# Шаг 2: Запуск Mosquitto брокера

Для настройки протокола MQTT необходимо создать конфигурационный файл *mosquitto.conf* со следующим содержимымы:

```c
listener 1883
allow_anonymous true
```
Для более удобного запуска брокера создадим файл *docker-compose.yml* со следующим содержимым:

```yml
version: "3"
services:
broker:
image: eclipse-mosquitto
container_name: broker
volumes:
- ./mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf
ports:
- "1883:1883"
```

Теперь создав контейнер (из Шага 1), получим следующее:

<p align="center">
<img width=100% src = "assets\images\example_run.png">
</p>

Логи контейнера:

<p align="center">
<img width=100% src = "assets\images\example_run_logs.png">
</p>

Брокер же отображает присоединившегося клиента.

<p align="center">
<img width=100% src = "assets\images\MQTT-docker_run.png">
</p>

Теперь можно запустить несколько датчиков. Но перед этим необходимо прописать *docker-compose.yml*:

```yml
version: "3"

services:
temp_sensor:
image: polinazhirakova/data-simulator
environment:
- SIM_HOST=192.168.0.101
- SIM_NAME=TEMP1
- SIM_PERIOD=2
- SIM_TYPE=temperature
pressure_sensor:
image: polinazhirakova/data-simulator
environment:
- SIM_HOST=192.168.0.101
- SIM_NAME=PRESS1
- SIM_PERIOD=2
- SIM_TYPE=pressure
current_sensor:
image: polinazhirakova/data-simulator
environment:
- SIM_HOST=192.168.0.101
- SIM_NAME=CURRENT1
- SIM_PERIOD=2
- SIM_TYPE=current
co_sensor:
image: polinazhirakova/data-simulator
environment:
- SIM_HOST=192.168.0.101
- SIM_NAME=CO1
- SIM_PERIOD=2
- SIM_TYPE=carbon_oxid
temp_sensor_2:
image: polinazhirakova/data-simulator
environment:
- SIM_HOST=192.168.0.101
- SIM_NAME=TEMP2
- SIM_PERIOD=4
- SIM_TYPE=temperature
co_sensor_2:
image: polinazhirakova/data-simulator
environment:
- SIM_HOST=192.168.0.101
- SIM_NAME=CO2
- SIM_PERIOD=6
- SIM_TYPE=carbon_oxid
```
С помощью команды `docker compose up` запустим одноврменно 6 контейнеров:

<p align="center">
<img width=100% src = "assets\images\docker-compose-simulator.png">
</p>

При этом брокер отображает:
<p align="center">
<img width=100% src = "assets\images\MQTT-docker-compose.png">
</p>

# Шаг 3: Получение данных от симулятора
Первоначально необходимо настроить Telegraf, который подписывается на MQTT, где датчики публикуют данные. Данные будут сохраняться в InfluxDB. Отображение информации с датчиков будет происходить при помощи Grafana.

## Telegraf
Перед использованием Telegram необходимо настроить его.
Для этого откроем конфигурационный файл *telegraf.conf* и в разделе `[[inputs.mqtt_consumer]]`пропишем следующее:

```c
servers = ["tcp://192.168.0.101:1883"] # адрес vm с mqtt-брокером
topics = [
"sensors/#"
]
data_format = "value"
data_type = "float"
```
Тем самым мы настраиваем Telegraf на чтение данных с машины IP адрес которой 192.168.0.101 через порт 1883.

Также настроим разедл вывода `[[outputs.influxdb]]`:
```c
urls = ["http://influxdb:8086"]
database = "sensors"
skip_database_creation = true
username = "telegraf"
password = "telegraf"
```
Настройка Telegraf на этом завршена.

## InfluDB

Для создания базы данных необходимо в конфигурационном файле *influxdb-init.iql* прописать следующее:
```sql
CREATE database sensors
CREATE USER telegraf WITH PASSWORD 'telegraf' WITH ALL PRIVILEGES
```

## Grafana

Данные для отображения датчиков берутся из InfluxDB.
Для настройки в конфигурационном файле необходимо прописать следующее:
```yaml
apiVersion: 1

datasources:
- name: InfluxDB_v1
type: influxdb
access: proxy
database: sensors
user: telegraf
url: http://influxdb:8086
jsonData:
httpMode: GET
secureJsonData:
password: telegraf
```

Для запуска всех трех контенйеров воспользуемся docker-compose.

В *docker-compose.yml* пропишем следующее:

```yml
version: "3"
services:
influxdb:
image: influxdb:1.8
container_name: influxdb
volumes:
- ./influxdb/scripts:/docker-entrypoint-initdb.d
- influx_data:/var/lib/influxdb
networks:
- server-net
telegraf:
image: telegraf
container_name: telegraf
volumes:
- ./telegraf:/etc/telegraf:ro
restart: unless-stopped
networks:
- server-net
grafana:
image: grafana/grafana
container_name: grafana
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/:/etc/grafana/

environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
restart: unless-stopped
ports:
- 3000:3000
networks:
- server-net

volumes:
influx_data: {}
grafana_data: {}

networks:
server-net: {}
```

После чего можно выполнить команду `docker compose up`

<p align="center">
<img width=100% src = "assets\images\telegraf-influx-grafana.png">
</p>

# Настройка дашборда
После запуска всех необходимых контейнеров, в раузере переходим по `192.168.0.101:3000`

<p align="center">
<img width=100% src = "assets\images\grafana-login.png">
</p>

Для проверки соединения перейдем в Menu -> Connections -> Data sources. Находим в истончиках InfluxDB и проверяем подключение:
<p align="center">
<img width=100% src = "assets\images\grafana-influx-test.png">
</p>

После переходим через Меню в раздел Dashboards, где создаем собственный дашбоард.

<p align="center">
<img width=100% src = "assets\images\grafana-new-view.png">
</p>

Для отображения информации с датчиков необходимо создать запрос (query).

<p align="center">
<img width=100% src = "assets\images\query.png">
</p>

После создания необходимо количества графиков, отображающих инфомрацию с Simluator, экспортируем дашборд как JSON-файл.

Для этого находим функцию `Share` -> ``Export` -> `Save to file`. Сохраненный файл помещаем в папку `vms\server\infra\grafana\provisioning\dashboards\mqtt.json`

# Пример выполненной работы

<p align="center">
<img width=100% src = "assets\images\dashboard.png">
</p>
Binary file added assets/images/MQTT-docker-compose.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 assets/images/MQTT-docker_run.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 assets/images/dashboard.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 assets/images/docker-compose-simulator.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 assets/images/example_run.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 assets/images/example_run_logs.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 assets/images/example_run_with_error.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 assets/images/grafana-influx-test.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 assets/images/grafana-login.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 assets/images/grafana-new-view.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 assets/images/image-data-simulator.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 assets/images/query.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 assets/images/telegraf-influx-grafana.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion vms/client/simulator/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.7
FROM python:alpine3.19
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
Expand Down
45 changes: 33 additions & 12 deletions vms/client/simulator/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,44 @@ version: "3"

services:
temp_sensor:
image: antonaleks/data-simulator
image: polinazhirakova/data-simulator
environment:
- SIM_HOST=192.168.1.1
- SIM_NAME=TIRCAHL24
- SIM_PERIOD=5
- SIM_HOST=192.168.0.101
- SIM_NAME=TEMP1
- SIM_PERIOD=2
- SIM_TYPE=temperature
pressure_sensor:
image: antonaleks/data-simulator
image: polinazhirakova/data-simulator
environment:
- SIM_HOST=192.168.1.1
- SIM_NAME=PIRCAHL11
- SIM_PERIOD=10
- SIM_HOST=192.168.0.101
- SIM_NAME=PRESS1
- SIM_PERIOD=2
- SIM_TYPE=pressure
current_sensor:
image: antonaleks/data-simulator
image: polinazhirakova/data-simulator
environment:
- SIM_HOST=192.168.1.1
- SIM_NAME=A0_CURRENT
- SIM_PERIOD=1
- SIM_HOST=192.168.0.101
- SIM_NAME=CURRENT1
- SIM_PERIOD=2
- SIM_TYPE=current
co_sensor:
image: polinazhirakova/data-simulator
environment:
- SIM_HOST=192.168.0.101
- SIM_NAME=CO1
- SIM_PERIOD=2
- SIM_TYPE=carbon_oxid
temp_sensor_2:
image: polinazhirakova/data-simulator
environment:
- SIM_HOST=192.168.0.101
- SIM_NAME=TEMP2
- SIM_PERIOD=4
- SIM_TYPE=temperature
co_sensor_2:
image: polinazhirakova/data-simulator
environment:
- SIM_HOST=192.168.0.101
- SIM_NAME=CO2
- SIM_PERIOD=6
- SIM_TYPE=carbon_oxid
Loading