diff --git a/.gitignore b/.gitignore
index 8647625..8b10401 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
__pycache__
-devices.yml
\ No newline at end of file
+devices.yml
+history.*
\ No newline at end of file
diff --git a/Charts/data.json b/Charts/data.json
new file mode 100644
index 0000000..032d501
--- /dev/null
+++ b/Charts/data.json
@@ -0,0 +1,194 @@
+[
+ {
+ "data": {
+ "timestamp": "2024-06-22T23:59:06+02:00",
+ "mac": "A4:C1:38:46:D7:75",
+ "temperature": 20.4,
+ "humidity": 69,
+ "battery_percent": 87,
+ "battery_volt": 2.985,
+ "count": 241
+ },
+ "device": {
+ "mac": "A4:C1:38:46:D7:75",
+ "name": "4",
+ "room": "dinner_room"
+ }
+ },
+ {
+ "data": {
+ "timestamp": "2024-06-22T23:59:07+02:00",
+ "mac": "A4:C1:38:DD:9F:EB",
+ "temperature": 20.3,
+ "humidity": 70,
+ "battery_percent": 85,
+ "battery_volt": 2.975,
+ "count": 240
+ },
+ "device": {
+ "mac": "A4:C1:38:DD:9F:EB",
+ "name": "5",
+ "room": "kitchen"
+ }
+ },
+ {
+ "data": {
+ "timestamp": "2024-06-22T23:59:07+02:00",
+ "mac": "A4:C1:38:9A:81:25",
+ "temperature": 25.1,
+ "humidity": 51,
+ "battery_percent": 82,
+ "battery_volt": 2.946,
+ "count": 143
+ },
+ "device": {
+ "mac": "A4:C1:38:9A:81:25",
+ "name": "6",
+ "room": "server"
+ }
+ },
+ {
+ "data": {
+ "timestamp": "2024-06-22T23:59:09+02:00",
+ "mac": "A4:C1:38:83:05:E8",
+ "temperature": 22.2,
+ "humidity": 61,
+ "battery_percent": 80,
+ "battery_volt": 2.933,
+ "count": 32
+ },
+ "device": {
+ "mac": "A4:C1:38:83:05:E8",
+ "name": "my_room",
+ "room": "my_room"
+ }
+ },
+ {
+ "data": {
+ "timestamp": "2024-06-23T00:13:48+02:00",
+ "mac": "A4:C1:38:DD:9F:EB",
+ "temperature": 20.3,
+ "humidity": 70,
+ "battery_percent": 85,
+ "battery_volt": 2.974,
+ "count": 1
+ },
+ "device": {
+ "mac": "A4:C1:38:DD:9F:EB",
+ "name": "5",
+ "room": "kitchen"
+ }
+ },
+ {
+ "data": {
+ "timestamp": "2024-06-23T00:13:49+02:00",
+ "mac": "A4:C1:38:46:D7:75",
+ "temperature": 20.4,
+ "humidity": 69,
+ "battery_percent": 87,
+ "battery_volt": 2.986,
+ "count": 2
+ },
+ "device": {
+ "mac": "A4:C1:38:46:D7:75",
+ "name": "4",
+ "room": "dinner_room"
+ }
+ },
+ {
+ "data": {
+ "timestamp": "2024-06-23T00:13:50+02:00",
+ "mac": "A4:C1:38:83:05:E8",
+ "temperature": 22.2,
+ "humidity": 61,
+ "battery_percent": 80,
+ "battery_volt": 2.932,
+ "count": 90
+ },
+ "device": {
+ "mac": "A4:C1:38:83:05:E8",
+ "name": "my_room",
+ "room": "my_room"
+ }
+ },
+ {
+ "data": {
+ "timestamp": "2024-06-23T00:13:55+02:00",
+ "mac": "A4:C1:38:9A:81:25",
+ "temperature": 25.1,
+ "humidity": 51,
+ "battery_percent": 82,
+ "battery_volt": 2.945,
+ "count": 160
+ },
+ "device": {
+ "mac": "A4:C1:38:9A:81:25",
+ "name": "6",
+ "room": "server"
+ }
+ },
+ {
+ "data": {
+ "timestamp": "2024-06-23T00:14:11+02:00",
+ "mac": "A4:C1:38:83:05:E8",
+ "temperature": 22.3,
+ "humidity": 61,
+ "battery_percent": 81,
+ "battery_volt": 2.932,
+ "count": 92
+ },
+ "device": {
+ "mac": "A4:C1:38:83:05:E8",
+ "name": "my_room",
+ "room": "my_room"
+ }
+ },
+ {
+ "data": {
+ "timestamp": "2024-06-23T00:14:11+02:00",
+ "mac": "A4:C1:38:46:D7:75",
+ "temperature": 20.4,
+ "humidity": 69,
+ "battery_percent": 87,
+ "battery_volt": 2.986,
+ "count": 2
+ },
+ "device": {
+ "mac": "A4:C1:38:46:D7:75",
+ "name": "4",
+ "room": "dinner_room"
+ }
+ },
+ {
+ "data": {
+ "timestamp": "2024-06-23T00:14:12+02:00",
+ "mac": "A4:C1:38:9A:81:25",
+ "temperature": 25.1,
+ "humidity": 51,
+ "battery_percent": 82,
+ "battery_volt": 2.945,
+ "count": 160
+ },
+ "device": {
+ "mac": "A4:C1:38:9A:81:25",
+ "name": "6",
+ "room": "server"
+ }
+ },
+ {
+ "data": {
+ "timestamp": "2024-06-23T00:14:12+02:00",
+ "mac": "A4:C1:38:DD:9F:EB",
+ "temperature": 20.3,
+ "humidity": 70,
+ "battery_percent": 85,
+ "battery_volt": 2.974,
+ "count": 1
+ },
+ "device": {
+ "mac": "A4:C1:38:DD:9F:EB",
+ "name": "5",
+ "room": "kitchen"
+ }
+ }
+]
\ No newline at end of file
diff --git a/Charts/index.html b/Charts/index.html
new file mode 100644
index 0000000..1ff615a
--- /dev/null
+++ b/Charts/index.html
@@ -0,0 +1,143 @@
+
+
+
+
+
+ Geräte-Diagramme
+
+
+
+
+ Geräte-Diagramme
+
+
+
+
+
diff --git a/Charts/script.js b/Charts/script.js
new file mode 100644
index 0000000..2ba5ddc
--- /dev/null
+++ b/Charts/script.js
@@ -0,0 +1,107 @@
+document.addEventListener('DOMContentLoaded', function () {
+ fetch('data.json')
+ .then(response => {
+ if (!response.ok) {
+ throw new Error('Network response was not ok ' + response.statusText);
+ }
+ return response.json();
+ })
+ .then(data => {
+ const devices = {};
+
+ data.forEach(entry => {
+ const mac = entry.device.mac;
+ if (!devices[mac]) {
+ devices[mac] = {
+ temperatureData: [],
+ humidityData: [],
+ labels: [],
+ name: entry.device.name,
+ room: entry.device.room
+ };
+ }
+ devices[mac].labels.push(new Date(entry.data.timestamp));
+ devices[mac].temperatureData.push(entry.data.temperature);
+ devices[mac].humidityData.push(entry.data.humidity);
+ });
+
+ const chartsContainer = document.getElementById('chartsContainer');
+
+ Object.keys(devices).forEach(mac => {
+ const device = devices[mac];
+
+ const chartContainer = document.createElement('div');
+ chartContainer.className = 'chart-container';
+
+ const canvas = document.createElement('canvas');
+ canvas.id = `chart-${mac}`;
+
+ const title = document.createElement('h3');
+ title.textContent = `Device ${device.name} in ${device.room}`;
+
+ chartContainer.appendChild(title);
+ chartContainer.appendChild(canvas);
+ chartsContainer.appendChild(chartContainer);
+
+ const ctx = canvas.getContext('2d');
+ new Chart(ctx, {
+ type: 'line',
+ data: {
+ labels: device.labels,
+ datasets: [
+ {
+ label: 'Temperatur (°C)',
+ data: device.temperatureData,
+ borderColor: 'rgba(255, 99, 132, 1)',
+ backgroundColor: 'rgba(255, 99, 132, 0.2)',
+ borderWidth: 1,
+ yAxisID: 'y1'
+ },
+ {
+ label: 'Luftfeuchtigkeit (%)',
+ data: device.humidityData,
+ borderColor: 'rgba(54, 162, 235, 1)',
+ backgroundColor: 'rgba(54, 162, 235, 0.2)',
+ borderWidth: 1,
+ yAxisID: 'y2'
+ }
+ ]
+ },
+ options: {
+ responsive: true,
+ scales: {
+ x: {
+ type: 'time',
+ time: {
+ unit: 'minute',
+ tooltipFormat: 'll HH:mm'
+ }
+ },
+ y1: {
+ type: 'linear',
+ position: 'left',
+ beginAtZero: true,
+ title: {
+ display: true,
+ text: 'Temperatur (°C)'
+ }
+ },
+ y2: {
+ type: 'linear',
+ position: 'right',
+ beginAtZero: true,
+ title: {
+ display: true,
+ text: 'Luftfeuchtigkeit (%)'
+ },
+ grid: {
+ drawOnChartArea: false
+ }
+ }
+ }
+ }
+ });
+ });
+ })
+ .catch(error => console.error('Error loading JSON data:', error));
+});
diff --git a/Charts/styles.css b/Charts/styles.css
new file mode 100644
index 0000000..9cfcc97
--- /dev/null
+++ b/Charts/styles.css
@@ -0,0 +1,20 @@
+body {
+ font-family: Arial, sans-serif;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ background-color: #f4f4f4;
+ margin: 0;
+ padding: 20px;
+}
+
+.chart-container {
+ width: 80%;
+ margin: 20px 0;
+}
+
+canvas {
+ background-color: #ffffff;
+ border-radius: 8px;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
diff --git a/python/src/data_class.py b/python/src/data_class.py
index 79213e7..490c059 100644
--- a/python/src/data_class.py
+++ b/python/src/data_class.py
@@ -29,11 +29,11 @@ class Data:
def to_json(self):
return {
- 'timestamp': self.timestamp,
- 'mac': self.mac,
- 'temperature': self.temperature,
- 'humidity': self.humidity,
- 'battery_percent': self.battery_percent,
- 'battery_volt': self.battery_volt,
- 'count': self.count,
+ "timestamp": self.timestamp,
+ "mac": self.mac,
+ "temperature": self.temperature,
+ "humidity": self.humidity,
+ "battery_percent": self.battery_percent,
+ "battery_volt": self.battery_volt,
+ "count": self.count,
}
diff --git a/python/src/devices.py b/python/src/devices.py
index f0af17f..603b611 100644
--- a/python/src/devices.py
+++ b/python/src/devices.py
@@ -11,6 +11,13 @@ class Device:
self.name = data['name']
self.room = data['room']
+ def to_json(self):
+ return {
+ "mac": self.mac,
+ "name": self.name,
+ "room": self.room
+ }
+
def get_devices():
devices_list = []
diff --git a/python/src/discovery.py b/python/src/discovery.py
index 88e1bbe..0b7451b 100644
--- a/python/src/discovery.py
+++ b/python/src/discovery.py
@@ -29,7 +29,8 @@ class ScanDelegate(DefaultDelegate):
if len(val) != 30: return False
return True
- def is_atc_device(self, dev, data_obj):
+ @staticmethod
+ def is_atc_device(dev, data_obj):
global devices
if 'A4:C1:38' not in dev.addr.upper(): return False
for device in devices:
@@ -37,8 +38,8 @@ class ScanDelegate(DefaultDelegate):
device_from_config = get_device(dev)
- try:print(f"Device: {dev.addr.upper()} ({dev.addrType}), RSSI: {dev.rssi} dB, Room: {device_from_config.room}")
- except:print(f"Device: {dev.addr.upper()} ({dev.addrType}), RSSI: {dev.rssi} dB, Room: ?")
+ try:print(f"Device: {dev.addr.upper()} ({dev.addrType}), RSSI: {dev.rssi}dB, Room: {device_from_config.room}")
+ except:print(f"Device: {dev.addr.upper()} ({dev.addrType}), RSSI: {dev.rssi}dB, Room: ?")
print(f'\tTemp: {data_obj.temperature}°C, Humid: {data_obj.humidity}%, Batt: {data_obj.battery_percent}%\n')
return True
diff --git a/python/src/log_data.py b/python/src/log_data.py
index 4640904..2724848 100644
--- a/python/src/log_data.py
+++ b/python/src/log_data.py
@@ -1 +1,32 @@
-# TODO
+import os
+import json
+from data_class import Data
+from devices import Device
+
+workdir, filename = os.path.split(os.path.abspath(__file__))
+
+
+def log_to_txt(devices):
+ with open(f'{workdir}{os.sep}history.json', 'r') as file:
+ data = json.load(file)
+
+ with open(f'{workdir}{os.sep}history.json', 'w') as file:
+ for device in devices:
+ dev, data_obj, from_config = device
+ data_obj:Data
+ from_config:Device
+ data.append({
+ "data": data_obj.to_json(),
+ "device": from_config.to_json()
+ })
+ final_data = {"measurements": data}
+ file.write(json.dumps(data, indent=2))
+
+
+def log_to_mongodb(data):
+ pass
+
+
+def log_to_mqtt(data):
+ pass
+
diff --git a/python/src/main.py b/python/src/main.py
index b2f60ab..420c42b 100644
--- a/python/src/main.py
+++ b/python/src/main.py
@@ -1,5 +1,7 @@
from discovery import start_discovery
from loop import start_loop
+from log_data import log_to_txt
devices = start_discovery()
+log_to_txt(devices)