Weiterarbeit Users, Server implementier für Config-Data austausch, Data funktioniert noch nicht korrekt

This commit is contained in:
2024-04-18 17:27:48 +02:00
parent 46f2083490
commit 04ad35a91f
14 changed files with 208 additions and 67 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1 +1 @@
{"timestamps": ["2024-04-12 16:43"], "Producer_sum": {"values": {"success": [true], "day_energy": [205790], "pac": [19349], "total_energy": [58877902], "year_energy": [7792097]}}, "Fronius_15kW": {"values": {"success": [true], "day_energy": [84970], "pac": [8075], "total_energy": [30943902], "year_energy": [3146688]}}, "Fronius_20kW": {"values": {"success": [true], "day_energy": [120820], "pac": [11274], "total_energy": [27934000], "year_energy": [4645409]}}, "Meter_Sum": {"values": {"success": [true], "Current_AC_Phase_1": [-10.55], "Current_AC_Phase_2": [-21.65], "Current_AC_Phase_3": [-19.2], "PowerReal_P_Sum": [-11792.6]}}, "Meter_Fronius": {"values": {"success": [true], "Current_AC_Phase_1": [-10.55], "Current_AC_Phase_2": [-21.65], "Current_AC_Phase_3": [-19.2], "PowerReal_P_Sum": [-11792.6]}}, "User_data": {"values": {"Current_Power": [0], "Used_Energy": [0], "Current_Prio": [0], "Current_deltaPower": [0], "measured_Temp": [0]}}, "Umod1": {"values": {"Current_Power": [0], "Used_Energy": [6], "Current_Prio": [1], "Current_deltaPower": [0], "measured_Temp": [0]}}, "Umod3": {"values": {"Current_Power": [0], "Used_Energy": [6], "Current_Prio": [3], "Current_deltaPower": [0], "measured_Temp": [0]}}, "Umod2.0": {"values": {"Current_Power": [0], "Used_Energy": [6], "Current_Prio": [2], "Current_deltaPower": [0], "measured_Temp": [0]}}, "Umod2.1": {"values": {"Current_Power": [0], "Used_Energy": [6], "Current_Prio": [2], "Current_deltaPower": [0], "measured_Temp": [0]}}, "Umod2.2": {"values": {"Current_Power": [0], "Used_Energy": [6], "Current_Prio": [2], "Current_deltaPower": [0], "measured_Temp": [0]}}, "Umod2.3": {"values": {"Current_Power": [0], "Used_Energy": [6], "Current_Prio": [2], "Current_deltaPower": [0], "measured_Temp": [0]}}, "Usta2.0": {"values": {"Current_Power": [0], "Used_Energy": [4], "Current_Prio": [2], "Current_deltaPower": [0], "measured_Temp": [0]}}, "Usta2.1": {"values": {"Current_Power": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "Used_Energy": [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], "Current_Prio": [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], "Current_deltaPower": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}}, "shelly_Boiler": {"values": {"Current_Power": [0], "Used_Energy": [0], "Current_Prio": [2], "Current_deltaPower": [0], "measured_Temp": [25.19]}}}
{"timestamps": ["2024-04-18 17:18", "2024-04-18 17:19", "2024-04-18 17:20", "2024-04-18 17:21", "2024-04-18 17:22", "2024-04-18 17:23", "2024-04-18 17:24"], "Producer_sum": {"values": {"success": [true, true, true, true, true, true, true], "day_energy": [35718, 35866, 35991, 36109, 36236, 36329, 36438], "pac": [7995, 8083, 7758, 7083, 6439, 6084, 5755], "total_energy": [59811200, 59811300, 59811400, 59811604, 59811604, 59811804, 59811902], "year_energy": [8725390, 8725539, 8725663, 8725781, 8725906, 8725999, 8726110]}}, "Fronius_15kW": {"values": {"success": [true, true, true, true, true, true, true], "day_energy": [17347, 17409, 17461, 17512, 17564, 17603, 17649], "pac": [3359, 3388, 3251, 2959, 2688, 2538, 2393], "total_energy": [31330000, 31330100, 31330100, 31330202, 31330202, 31330302, 31330302], "year_energy": [3532817, 3532880, 3532932, 3532982, 3533033, 3533072, 3533119]}}, "Fronius_20kW": {"values": {"success": [true, true, true, true, true, true, true], "day_energy": [18371, 18457, 18530, 18597, 18672, 18726, 18789], "pac": [4636, 4695, 4507, 4124, 3751, 3546, 3362], "total_energy": [28481200, 28481200, 28481300, 28481402, 28481402, 28481502, 28481600], "year_energy": [5192573, 5192659, 5192731, 5192799, 5192873, 5192927, 5192991]}}, "Meter_Sum": {"values": {"success": [true, true, true, true, true, true, true], "Current_AC_Phase_1": [5, 4.45, 6.4, 7.25, 11.2, 6.3, 9], "Current_AC_Phase_2": [5.75, 5.45, 6.5, 7.5, 7.5, 2.714, 2.175], "Current_AC_Phase_3": [-4.55, -4.6, -4.3, -3.9, 7.55, 4.4, 4.7], "PowerReal_P_Sum": [443, 200.8, 1714.5, 1879.3, 5569.2, 2260.1, 3062.9]}}, "Meter_Fronius": {"values": {"success": [true, true, true, true, true, true, true], "Current_AC_Phase_1": [5, 4.45, 6.4, 7.25, 11.2, 6.3, 9], "Current_AC_Phase_2": [5.75, 5.45, 6.5, 7.5, 7.5, 2.714, 2.175], "Current_AC_Phase_3": [-4.55, -4.6, -4.3, -3.9, 7.55, 4.4, 4.7], "PowerReal_P_Sum": [443, 200.8, 1714.5, 1879.3, 5569.2, 2260.1, 3062.9]}}, "User_data": {"values": {"Current_Power": [0, 0, 0, 0, 0, 0, 0], "Used_Energy": [0, 0, 0, 0, 0, 0, 0], "Current_Prio": [0, 0, 0, 0, 0, 0, 0], "Current_deltaPower": [0, 0, 0, 0, 0, 0, 0], "measured_Temp": [0, 0, 0, 0, 0, 0, 0]}}, "Umod1": {"values": {"Current_Power": [0, 0, 0, 0, 0, 0, 0], "Used_Energy": [6, 6, 6, 6, 6, 6, 6], "Current_Prio": [1, 1, 1, 1, 1, 1, 1], "Current_deltaPower": [0, 0, 0, 0, 0, 0, 0], "measured_Temp": [0, 0, 0, 0, 0, 0, 0]}}, "Umod3": {"values": {"Current_Power": [0, 0, 0, 0, 0, 0, 0], "Used_Energy": [6, 6, 6, 6, 6, 6, 6], "Current_Prio": [3, 3, 3, 3, 3, 3, 3], "Current_deltaPower": [0, 0, 0, 0, 0, 0, 0], "measured_Temp": [0, 0, 0, 0, 0, 0, 0]}}, "Umod2.0": {"values": {"Current_Power": [0, 0, 0, 0, 0, 0, 0], "Used_Energy": [6, 6, 6, 6, 6, 6, 6], "Current_Prio": [2, 2, 2, 2, 2, 2, 2], "Current_deltaPower": [0, 0, 0, 0, 0, 0, 0], "measured_Temp": [0, 0, 0, 0, 0, 0, 0]}}, "Umod2.1": {"values": {"Current_Power": [0, 0, 0, 0, 0, 0, 0], "Used_Energy": [6, 6, 6, 6, 6, 6, 6], "Current_Prio": [2, 2, 2, 2, 2, 2, 2], "Current_deltaPower": [0, 0, 0, 0, 0, 0, 0], "measured_Temp": [0, 0, 0, 0, 0, 0, 0]}}, "Umod2.2": {"values": {"Current_Power": [0, 0, 0, 0, 0, 0, 0], "Used_Energy": [6, 6, 6, 6, 6, 6, 6], "Current_Prio": [2, 2, 2, 2, 2, 2, 2], "Current_deltaPower": [0, 0, 0, 0, 0, 0, 0], "measured_Temp": [0, 0, 0, 0, 0, 0, 0]}}, "Umod2.3": {"values": {"Current_Power": [0, 0, 0, 0, 0, 0, 0], "Used_Energy": [6, 6, 6, 6, 6, 6, 6], "Current_Prio": [2, 2, 2, 2, 2, 2, 2], "Current_deltaPower": [0, 0, 0, 0, 0, 0, 0], "measured_Temp": [0, 0, 0, 0, 0, 0, 0]}}, "Usta2.0": {"values": {"Current_Power": [0, 0, 0, 0, 0, 0, 0], "Used_Energy": [4, 4, 4, 4, 4, 4, 4], "Current_Prio": [2, 2, 2, 2, 2, 2, 2], "Current_deltaPower": [0, 0, 0, 0, 0, 0, 0], "measured_Temp": [0, 0, 0, 0, 0, 0, 0]}}, "shelly_Boiler": {"values": {"Current_Power": [0, 0, 0, 0, 0, 0, 0], "Used_Energy": [0, 0, 0, 0, 0, 0, 0], "Current_Prio": [2, 2, 2, 2, 2, 2, 2], "Current_deltaPower": [0, 0, 0, 0, 0, 0, 0], "measured_Temp": [20.56, 20.56, 20.56, 20.56, 20.56, 20.56, 20.56]}}}

View File

@@ -8,9 +8,10 @@ import time
import datetime
import json
import main
import serverrequests
# Gehe in eine Dauerschlaufe
ID = "SRING_TO_DEFINE"
ID = "BasToken"
producer_values = []
producers =[]
@@ -23,16 +24,15 @@ users = []
Collector = JsonHandling.DataCollector()
data = {}
def calcSomeStuff():
return
while True:
# Neue Konfig holen
config = serverrequests.update_config_on_server(ID, data)
config = json.dumps(serverrequests.get_config(ID))
if JsonHandling.JsonHandling.check_config_has_changed(config):
producers = energyproducer.EnergyProducer.create_producerlist_from_json(config)
meter = energymeter.EnergyMeter.create_meterlist_from_json(config)
@@ -45,10 +45,13 @@ while True:
for user in users:
user.calc_used_power()
main.EnergyUserFactory.distribute_energy(users, meter_values["Meter_Sum"]["PowerReal_P_Sum"])
main.EnergyUserFactory.distribute_energy(users, -1*(meter_values["Meter_Sum"]["PowerReal_P_Sum"]))
user_values = energyuser.EnergyUser.get_all_current_values(users)
Collector.collect_and_store_data(producer_values, meter_values, user_values)
data = Collector.data
serverrequests.set_data(ID, data)
time.sleep(5)

View File

@@ -1,23 +1,30 @@
import requests
import json
def update_config_on_server(token, config):
## For developement now just return json from here
with open("config.txt", 'r') as file:
json_data = file.read()
def get_config(token_id):
url = 'http://localhost:5000/getconfig'
headers = {'ID': token_id}
response = requests.post(url, headers=headers)
return json_data
## For server later
response = requests.post(f'http://your_server_ip:5000/update_config?token={token}', json=config)
if response.status_code == 200:
print('Config updated successfully.')
return response.json()
else:
print('Failed to update config.')
return response
return {'error': f'Request failed with status code {response.status_code}'}
if __name__ == '__main__':
# Beispiel für die Verwendung der Funktion update_config_on_server
token = 'your_token'
config = {'key1': 'new_value1', 'key2': 'new_value2'}
update_config_on_server(token, config)
def set_data(token_id, data):
url = 'http://localhost:5000/setdata'
headers = {'ID': token_id, 'JSON': json.dumps(data)}
response = requests.post(url, headers=headers)
if response.status_code == 200:
return {'message': 'Data sent successfully'}
else:
return {'error': f'Request failed with status code {response.status_code}'}
# Beispielaufrufe:
# config = get_config('token123')
# print(config)
# new_data = {'timestamps': ['2024-04-18 13:31', '2024-04-18 13:32'], 'Producer_sum': {'values': {'success': [True, True], 'day_energy': [6386, 6458], ...}}}
# response = set_data('token123', new_data)
# print(response)

View File

@@ -0,0 +1,20 @@
{
"metadata":{"config_has_changed" : "1"},
"users": [
{"type": "User1", "config": {"ID":"Umod1","user_prio":1,"lock_prio":2}},
{"type": "User1", "config": {"ID":"Umod3","user_prio":3,"lock_prio":4}},
{"type": "User1", "config": {"ID":"Umod2.0","user_prio":2,"lock_prio":3}},
{"type": "User1", "config": {"ID":"Umod2.1","user_prio":2,"lock_prio":3}},
{"type": "User1", "config": {"ID":"Umod2.2","user_prio":2,"lock_prio":3}},
{"type": "User1", "config": {"ID":"Umod2.3","user_prio":2,"lock_prio":3}},
{"type": "User2", "config": {"ID":"Usta2.0","user_prio":2,"lock_prio":6}},
{"type": "Boiler_1Stufig_Shelly", "config": {"ID":"shelly_Boiler","user_prio":2,"lock_prio":6, "shelly_ip" : "192.168.20.233", "boilerpower": 5000, "temperatur": 38}}
],
"producers": [
{"type": "Fronius", "config": {"ID":"Fronius_15kW","IP":"192.168.20.51","Adr":1}},
{"type": "Fronius", "config": {"ID":"Fronius_20kW","IP":"192.168.20.51","Adr":2}}
],
"meters": [
{"type": "Fronius", "config": {"ID":"Meter_Fronius","IP":"192.168.20.51","Adr":1}}
]
}

File diff suppressed because one or more lines are too long

42
server/json_merger.py Normal file
View File

@@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
"""
Created on Thu Apr 18 17:13:06 2024
@author: dh
"""
def merge_json(old_json, new_json):
if not isinstance(old_json, dict) or not isinstance(new_json, dict):
return old_json
for key, value in new_json.items():
if key not in old_json:
old_json[key] = value
elif isinstance(value, list):
if key not in old_json:
old_json[key] = []
if key == "timestamps":
for item in value:
if item not in old_json[key]:
old_json[key].append(item)
else:
old_json[key].extend(value)
elif isinstance(value, dict):
old_json[key] = merge_json(old_json.get(key, {}), value)
else:
old_json[key] = value
return old_json
# Beispielaufruf
old_json = {
"timestamps": ["s", "e", "r"],
"data": {"foo": [1, 2, 4], "bar": [3, 4, 6]}
}
new_json = {
"timestamps": ["r", "p"],
"data": {"foo": [4,5], "bar": [6,7]}
}
merged_json = merge_json(old_json, new_json)
print(merged_json)

View File

@@ -1,56 +1,124 @@
from flask import Flask, request, jsonify, abort
from flask import Flask, request, jsonify
import os
import json
from datetime import datetime
app = Flask(__name__)
TOKENS_FILE = "tokens.txt"
CONFIG_DIR = "configs"
# Route to get configuration
@app.route('/getconfig', methods=['POST'])
def get_config():
# Überprüfe, ob die erforderlichen Daten im Request vorhanden sind
if not request.json or 'token' not in request.json or 'data' not in request.json:
abort(400, 'Bad request. JSON data with "token" and "data" is required.')
try:
token_id = request.headers.get('ID')
token = request.json['token']
data = request.json['data']
if not token_id:
return jsonify({'error': 'Token ID is missing'}), 400
# Überprüfe, ob der Token gültig ist
if not is_valid_token(token):
abort(401, 'Unauthorized. Invalid token.')
config_file = os.path.join('config', f'{token_id}.json')
# Speichere die Daten in einem Datei für das entsprechende Token
save_data(token, data)
if not os.path.exists(config_file):
return jsonify({'error': 'Config not found for the specified token'}), 404
# Lade die Konfigurationsdatei für das Token
config = load_config(token)
return jsonify(config)
def is_valid_token(token):
# Überprüfe, ob der Token in der tokens.txt Datei vorhanden ist
with open(TOKENS_FILE, 'r') as file:
tokens = file.read().splitlines()
return token in tokens
def save_data(token, data):
# Erstelle das Verzeichnis für die Konfigurationsdateien, falls es nicht existiert
if not os.path.exists(CONFIG_DIR):
os.makedirs(CONFIG_DIR)
# Speichere die Daten in einer Datei für das entsprechende Token
with open(os.path.join(CONFIG_DIR, f'{token}.json'), 'w') as file:
file.write(jsonify(data))
def load_config(token):
config_file = os.path.join(CONFIG_DIR, f'{token}.json')
# Lade die Konfigurationsdatei für das Token
if os.path.exists(config_file):
with open(config_file, 'r') as file:
return json.load(file)
config = json.load(file)
data_file = os.path.join('config', f'{token_id}.json')
with open(data_file, 'r') as file:
data = json.load(file)
# Extract and include last timestamp in the response
try:
config['last_timestamp'] = data['timestamps'][len(data['timestamps'])-1]
except:
config['last_timestamp']=0
return jsonify(config), 200
except Exception as e:
return jsonify({'error': str(e)}), 500
# Route to set new data
@app.route('/setdata', methods=['POST'])
def set_data():
# Token-ID aus den Request-Headern extrahieren
token_id = request.headers.get('ID')
# Neue Daten aus den Request-Headern laden
new_data = request.headers.get('JSON')
try:
# Versuche, das JSON zu laden
new_data = json.loads(new_data)
except json.JSONDecodeError:
# Wenn das JSON nicht korrekt formatiert ist, schreibe das neue JSON in die Datei und beende die Funktion
write_json_file(token_id, new_data)
return 'Invalid JSON format. New JSON data has been written to the file and overwritten existing data.'
# Pfad zum Datenordner und Datei für die Token-ID erstellen
data_folder = 'data'
file_path = os.path.join(data_folder, f'{token_id}.json')
# Überprüfen, ob die Datei existiert und Daten enthält
if os.path.exists(file_path) and os.path.getsize(file_path) > 0:
# Bestehende Daten aus der Datei laden
with open(file_path, 'r') as file:
existing_data = json.load(file)
# Merge der beiden JSON-Objekte
merged_data = merge_json(existing_data, new_data)
else:
return {}
# Wenn die Datei nicht existiert oder leer ist, neue Daten verwenden
merged_data = new_data
# Daten in die Datei schreiben
with open(file_path, 'w') as file:
json.dump(merged_data, file)
return 'Data successfully set!'
def write_json_file(token_id, new_data):
"""
Funktion zum Schreiben von JSON-Daten in eine Datei.
"""
# Pfad zum Datenordner und Datei für die Token-ID erstellen
data_folder = 'data'
file_path = os.path.join(data_folder, f'{token_id}.json')
# Neue Daten in die Datei schreiben
with open(file_path, 'w') as file:
json.dump(new_data, file)
def merge_json(old_json, new_json):
if not isinstance(old_json, dict) or not isinstance(new_json, dict):
return old_json
for key, value in new_json.items():
if key not in old_json:
old_json[key] = value
elif isinstance(value, list):
if key not in old_json:
old_json[key] = []
if key == "timestamps":
for item in value:
if item not in old_json[key]:
old_json[key].append(item)
else:
old_json[key].extend(value)
elif isinstance(value, dict):
old_json[key] = merge_json(old_json.get(key, {}), value)
else:
old_json[key] = value
return old_json
if __name__ == '__main__':
app.run(debug=True)
app.run(debug=False)