diff --git a/REPORT.md b/REPORT.md
new file mode 100644
index 0000000..2065817
--- /dev/null
+++ b/REPORT.md
@@ -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 . `
+
+Таким образом мы создали образ, из которого можно развернуть контейнер.
+
+
+
+
+
+Собтвенно запустив контейнер через
+
+`docker run -e SIM_HOST=192.168.0.101 -e SIM_TYPE=temperature --name test -d polinazhirakova/data-simulator`
+
+Получим ошибку, т.к. брокер еще не настроен.
+
+
+
+
+
+
+# Шаг 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), получим следующее:
+
+
+
+
+
+Логи контейнера:
+
+
+
+
+
+Брокер же отображает присоединившегося клиента.
+
+
+
+
+
+Теперь можно запустить несколько датчиков. Но перед этим необходимо прописать *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 контейнеров:
+
+
+
+
+
+При этом брокер отображает:
+
+
+
+
+# Шаг 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`
+
+
+
+
+
+# Настройка дашборда
+После запуска всех необходимых контейнеров, в раузере переходим по `192.168.0.101:3000`
+
+
+
+
+
+Для проверки соединения перейдем в Menu -> Connections -> Data sources. Находим в истончиках InfluxDB и проверяем подключение:
+
+
+
+
+После переходим через Меню в раздел Dashboards, где создаем собственный дашбоард.
+
+
+
+
+
+Для отображения информации с датчиков необходимо создать запрос (query).
+
+
+
+
+
+После создания необходимо количества графиков, отображающих инфомрацию с Simluator, экспортируем дашборд как JSON-файл.
+
+Для этого находим функцию `Share` -> ``Export` -> `Save to file`. Сохраненный файл помещаем в папку `vms\server\infra\grafana\provisioning\dashboards\mqtt.json`
+
+# Пример выполненной работы
+
+
+
+
\ No newline at end of file
diff --git a/assets/images/MQTT-docker-compose.png b/assets/images/MQTT-docker-compose.png
new file mode 100644
index 0000000..7e7b5b5
Binary files /dev/null and b/assets/images/MQTT-docker-compose.png differ
diff --git a/assets/images/MQTT-docker_run.png b/assets/images/MQTT-docker_run.png
new file mode 100644
index 0000000..d6b816a
Binary files /dev/null and b/assets/images/MQTT-docker_run.png differ
diff --git a/assets/images/dashboard.png b/assets/images/dashboard.png
new file mode 100644
index 0000000..8ddb737
Binary files /dev/null and b/assets/images/dashboard.png differ
diff --git a/assets/images/docker-compose-simulator.png b/assets/images/docker-compose-simulator.png
new file mode 100644
index 0000000..d35375a
Binary files /dev/null and b/assets/images/docker-compose-simulator.png differ
diff --git a/assets/images/example_run.png b/assets/images/example_run.png
new file mode 100644
index 0000000..9bd3ecf
Binary files /dev/null and b/assets/images/example_run.png differ
diff --git a/assets/images/example_run_logs.png b/assets/images/example_run_logs.png
new file mode 100644
index 0000000..9f61b98
Binary files /dev/null and b/assets/images/example_run_logs.png differ
diff --git a/assets/images/example_run_with_error.png b/assets/images/example_run_with_error.png
new file mode 100644
index 0000000..1d518e3
Binary files /dev/null and b/assets/images/example_run_with_error.png differ
diff --git a/assets/images/grafana-influx-test.png b/assets/images/grafana-influx-test.png
new file mode 100644
index 0000000..68fad83
Binary files /dev/null and b/assets/images/grafana-influx-test.png differ
diff --git a/assets/images/grafana-login.png b/assets/images/grafana-login.png
new file mode 100644
index 0000000..f0cba04
Binary files /dev/null and b/assets/images/grafana-login.png differ
diff --git a/assets/images/grafana-new-view.png b/assets/images/grafana-new-view.png
new file mode 100644
index 0000000..18285d9
Binary files /dev/null and b/assets/images/grafana-new-view.png differ
diff --git a/assets/images/image-data-simulator.png b/assets/images/image-data-simulator.png
new file mode 100644
index 0000000..362fea2
Binary files /dev/null and b/assets/images/image-data-simulator.png differ
diff --git a/assets/images/query.png b/assets/images/query.png
new file mode 100644
index 0000000..f9a4792
Binary files /dev/null and b/assets/images/query.png differ
diff --git a/assets/images/telegraf-influx-grafana.png b/assets/images/telegraf-influx-grafana.png
new file mode 100644
index 0000000..cd8edcd
Binary files /dev/null and b/assets/images/telegraf-influx-grafana.png differ
diff --git a/vms/client/simulator/Dockerfile b/vms/client/simulator/Dockerfile
index e875bd0..e890783 100644
--- a/vms/client/simulator/Dockerfile
+++ b/vms/client/simulator/Dockerfile
@@ -1,4 +1,4 @@
-FROM python:3.7
+FROM python:alpine3.19
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
diff --git a/vms/client/simulator/docker-compose.yml b/vms/client/simulator/docker-compose.yml
index b9e08bb..ddeb7d1 100644
--- a/vms/client/simulator/docker-compose.yml
+++ b/vms/client/simulator/docker-compose.yml
@@ -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
diff --git a/vms/client/simulator/entity/sensor.py b/vms/client/simulator/entity/sensor.py
index 922fea5..27280f6 100644
--- a/vms/client/simulator/entity/sensor.py
+++ b/vms/client/simulator/entity/sensor.py
@@ -52,3 +52,14 @@ def generate_new_value(self):
import math
self.value = math.sin(self.step)
self.step = self.step + 1
+
+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
\ No newline at end of file
diff --git a/vms/client/simulator/main.py b/vms/client/simulator/main.py
index cccbc47..7130fc1 100644
--- a/vms/client/simulator/main.py
+++ b/vms/client/simulator/main.py
@@ -9,7 +9,8 @@
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}
+
+sensors = {"temperature": Temperature, "pressure": Pressure, "current": Current, "carbon_oxid": CO}
def on_publish(client, userdata, result): # create function for callback
diff --git a/vms/client/simulator/requirements.txt b/vms/client/simulator/requirements.txt
index c7b9a31..02a9b56 100644
--- a/vms/client/simulator/requirements.txt
+++ b/vms/client/simulator/requirements.txt
@@ -1 +1 @@
-paho_mqtt
\ No newline at end of file
+paho_mqtt==1.6.1
\ No newline at end of file
diff --git a/vms/gateway/docker-compose.yml b/vms/gateway/docker-compose.yml
new file mode 100644
index 0000000..869e743
--- /dev/null
+++ b/vms/gateway/docker-compose.yml
@@ -0,0 +1,9 @@
+version: "3"
+services:
+ broker:
+ image: eclipse-mosquitto
+ container_name: broker
+ volumes:
+ - ./mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf
+ ports:
+ - "1883:1883"
\ No newline at end of file
diff --git a/vms/server/infra/docker-compose.yml b/vms/server/infra/docker-compose.yml
index 94e705e..3170e2b 100644
--- a/vms/server/infra/docker-compose.yml
+++ b/vms/server/infra/docker-compose.yml
@@ -22,6 +22,7 @@ services:
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/:/etc/grafana/
+ # - ./grafana/provisioning/dashboards/default.yaml:/etc/grafana/provisioning/dashboards/main.yaml
environment:
- GF_SECURITY_ADMIN_USER=admin
diff --git a/vms/server/infra/grafana/provisioning/dashboards/mqtt.json b/vms/server/infra/grafana/provisioning/dashboards/mqtt.json
index ec65ac0..03b6880 100644
--- a/vms/server/infra/grafana/provisioning/dashboards/mqtt.json
+++ b/vms/server/infra/grafana/provisioning/dashboards/mqtt.json
@@ -3,7 +3,10 @@
"list": [
{
"builtIn": 1,
- "datasource": "-- Grafana --",
+ "datasource": {
+ "type": "datasource",
+ "uid": "grafana"
+ },
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
@@ -21,6 +24,7 @@
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
+ "id": 1,
"links": [],
"liveNow": false,
"panels": [
@@ -35,6 +39,184 @@
"mode": "palette-classic"
},
"custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "fillOpacity": 80,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "lineWidth": 1,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "ppm"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 7,
+ "w": 8,
+ "x": 0,
+ "y": 0
+ },
+ "id": 3,
+ "options": {
+ "barRadius": 0,
+ "barWidth": 0.97,
+ "fullHighlight": false,
+ "groupWidth": 0.7,
+ "legend": {
+ "calcs": [],
+ "displayMode": "list",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "orientation": "auto",
+ "showValue": "auto",
+ "stacking": "none",
+ "tooltip": {
+ "mode": "single",
+ "sort": "none"
+ },
+ "xTickLabelRotation": 0,
+ "xTickLabelSpacing": 0
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "influxdb",
+ "uid": "P4B5EB7AC8565B06F"
+ },
+ "groupBy": [
+ {
+ "params": [
+ "$__interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "mqtt_consumer",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "topic::tag",
+ "operator": "=",
+ "value": "sensors/carbon oxid/CO1"
+ }
+ ]
+ },
+ {
+ "datasource": {
+ "type": "influxdb",
+ "uid": "P4B5EB7AC8565B06F"
+ },
+ "groupBy": [
+ {
+ "params": [
+ "$__interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "hide": false,
+ "measurement": "mqtt_consumer",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "B",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "topic::tag",
+ "operator": "=",
+ "value": "sensors/carbon oxid/CO2"
+ }
+ ]
+ }
+ ],
+ "title": "Panel: CO",
+ "type": "barchart"
+ },
+ {
+ "datasource": {
+ "type": "influxdb",
+ "uid": "P4B5EB7AC8565B06F"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
@@ -46,14 +228,151 @@
"tooltip": false,
"viz": false
},
- "lineInterpolation": "linear",
+ "insertNulls": false,
+ "lineInterpolation": "smooth",
+ "lineStyle": {
+ "fill": "solid"
+ },
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
- "spanNulls": false,
+ "spanNulls": true,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "line"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "dark-red",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": -0.5
+ },
+ {
+ "color": "red",
+ "value": 0.5
+ }
+ ]
+ }
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 7,
+ "w": 12,
+ "x": 8,
+ "y": 0
+ },
+ "id": 6,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "list",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "single",
+ "sort": "none"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "influxdb",
+ "uid": "P4B5EB7AC8565B06F"
+ },
+ "groupBy": [
+ {
+ "params": [
+ "$__interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "mqtt_consumer",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "topic::tag",
+ "operator": "=",
+ "value": "sensors/current/CURRENT1"
+ }
+ ]
+ }
+ ],
+ "title": "Panel: Current (Time series)",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "influxdb",
+ "uid": "P4B5EB7AC8565B06F"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "smooth",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": true,
"stacking": {
"group": "A",
"mode": "none"
@@ -75,22 +394,24 @@
"value": 80
}
]
- }
+ },
+ "unit": "celsius"
},
"overrides": []
},
"gridPos": {
- "h": 9,
- "w": 12,
+ "h": 8,
+ "w": 8,
"x": 0,
- "y": 0
+ "y": 7
},
"id": 2,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
- "placement": "bottom"
+ "placement": "bottom",
+ "showLegend": true
},
"tooltip": {
"mode": "single",
@@ -103,7 +424,20 @@
"type": "influxdb",
"uid": "P4B5EB7AC8565B06F"
},
- "groupBy": [],
+ "groupBy": [
+ {
+ "params": [
+ "$__interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
"measurement": "mqtt_consumer",
"orderByTime": "ASC",
"policy": "default",
@@ -116,35 +450,327 @@
"value"
],
"type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "topic::tag",
+ "operator": "=",
+ "value": "sensors/temp/TEMP1"
+ }
+ ]
+ },
+ {
+ "datasource": {
+ "type": "influxdb",
+ "uid": "P4B5EB7AC8565B06F"
+ },
+ "groupBy": [
+ {
+ "params": [
+ "$__interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "hide": false,
+ "measurement": "mqtt_consumer",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "B",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "topic::tag",
+ "operator": "=",
+ "value": "sensors/temp/TEMP2"
+ }
+ ]
+ }
+ ],
+ "title": "Panel: Temperatures",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "influxdb",
+ "uid": "P4B5EB7AC8565B06F"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "dark-red",
+ "value": null
+ },
+ {
+ "color": "green",
+ "value": -0.5
+ },
+ {
+ "color": "orange",
+ "value": 0.5
+ }
+ ]
+ }
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 4,
+ "x": 8,
+ "y": 7
+ },
+ "id": 5,
+ "options": {
+ "minVizHeight": 75,
+ "minVizWidth": 75,
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showThresholdLabels": false,
+ "showThresholdMarkers": true,
+ "sizing": "auto"
+ },
+ "pluginVersion": "10.4.2",
+ "targets": [
+ {
+ "datasource": {
+ "type": "influxdb",
+ "uid": "${DS_INFLUXDB_V1}"
+ },
+ "groupBy": [
+ {
+ "params": [
+ "$__interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "hide": false,
+ "measurement": "mqtt_consumer",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
+ }
+ ]
+ ],
+ "tags": [
+ {
+ "key": "topic::tag",
+ "operator": "=",
+ "value": "sensors/current/CURRENT1"
+ }
+ ]
+ }
+ ],
+ "title": "Panel: Current (Gauge)",
+ "type": "gauge"
+ },
+ {
+ "datasource": {
+ "type": "influxdb",
+ "uid": "P4B5EB7AC8565B06F"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic-by-name"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "smooth",
+ "lineStyle": {
+ "fill": "solid"
+ },
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "always",
+ "spanNulls": true,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "pressurepa"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 8,
+ "x": 12,
+ "y": 7
+ },
+ "id": 4,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "list",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "mode": "single",
+ "sort": "none"
+ }
+ },
+ "pluginVersion": "10.4.2",
+ "targets": [
+ {
+ "datasource": {
+ "type": "influxdb",
+ "uid": "P4B5EB7AC8565B06F"
+ },
+ "groupBy": [
+ {
+ "params": [
+ "$__interval"
+ ],
+ "type": "time"
+ },
+ {
+ "params": [
+ "null"
+ ],
+ "type": "fill"
+ }
+ ],
+ "measurement": "mqtt_consumer",
+ "orderByTime": "ASC",
+ "policy": "default",
+ "refId": "A",
+ "resultFormat": "time_series",
+ "select": [
+ [
+ {
+ "params": [
+ "value"
+ ],
+ "type": "field"
+ },
+ {
+ "params": [],
+ "type": "mean"
}
]
],
"tags": [
{
- "key": "topic",
+ "key": "topic::tag",
"operator": "=",
- "value": "sensors/current/A0_CURRENT"
+ "value": "sensors/pressure/PRESS1"
}
]
}
],
- "title": "Panel Title",
+ "title": "Panel: Pressure",
"type": "timeseries"
}
],
- "schemaVersion": 35,
- "style": "dark",
+ "refresh": "",
+ "schemaVersion": 39,
"tags": [],
"templating": {
"list": []
},
"time": {
- "from": "now-5m",
+ "from": "now-2m",
"to": "now"
},
"timepicker": {},
"timezone": "",
- "title": "New dashboard",
- "version": 0,
+ "title": "My dashboard",
+ "uid": "bdift4lxq3vgge",
+ "version": 8,
"weekStart": ""
}
\ No newline at end of file
diff --git a/vms/server/infra/telegraf/telegraf.conf b/vms/server/infra/telegraf/telegraf.conf
index ddd8b05..4a9c173 100644
--- a/vms/server/infra/telegraf/telegraf.conf
+++ b/vms/server/infra/telegraf/telegraf.conf
@@ -8558,7 +8558,7 @@ password = "telegraf"
# "telegraf/+/mem",
# "sensors/#",
# ]
-servers = ["tcp://192.168.26.1:1883"] # адрес vm с mqtt-брокером
+servers = ["tcp://192.168.0.101:1883"] # адрес vm с mqtt-брокером
topics = [
"sensors/#"
]