improvement

This commit is contained in:
2024-08-20 21:24:02 +00:00
parent 3692cb01a9
commit e6bf16a74c
10 changed files with 509 additions and 69 deletions

View File

@@ -1,37 +1,143 @@
import mysql.connector
from mysql.connector import Error
import os
import re
import requests
from bs4 import BeautifulSoup
from requests.exceptions import HTTPError, Timeout, RequestException
# FHEM URL
# FHEM_URL = "http://192.168.2.200:8083/fhem"
FHEM_URL = "https://fhem.auwiesen2.de/fhem"
# Import the get_token function from the utilities module
from utilities.get_token import get_token
# Parameters including CSRF token
PARAMS = {
"cmd": "jsonlist2",
"XHR": "1",
"fwcsrf": "csrf_334814865250639" # CSRF token as a parameter
}
# Database connection details
DB_HOST = 'mariadb'
DB_USER = 'root'
DB_PASSWORD = os.getenv('MYSQL_ROOT_PASSWORD', 'S3raph1n!')
DB_NAME = 'fhem'
TABLE_NAME = 'devices'
# Headers including CSRF token
HEADERS = {
"X-FHEM-csrfToken": "csrf_822558611144652",
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "application/json"
}
# FHEM server URL
FHEM_URL_BASE = "https://fhem.auwiesen2.de/fhem"
# Send the request with both parameters and headers
response = requests.get(FHEM_URL, params=PARAMS, headers=HEADERS)
# Path to the log file created by the first script
LOG_FILE_PATH = 'fhem_script.log'
# Debugging: Check the status code and response content
print("Response Status Code:", response.status_code)
print("Response Content:", response.text)
# Session to handle requests
session = requests.Session()
try:
# Attempt to parse the response as JSON
data = response.json()
devices = data['Results']
for device in devices:
print(f"Device: {device['Name']}, State: {device['Internals']['STATE']}")
except requests.exceptions.JSONDecodeError:
print("Error: Failed to decode JSON response.")
except KeyError:
print("Error: Expected keys not found in the JSON data.")
def connect_to_db():
"""Establish a connection to the MySQL database."""
connection = None
try:
connection = mysql.connector.connect(
host=DB_HOST,
user=DB_USER,
password=DB_PASSWORD,
charset='utf8mb4',
collation='utf8mb4_unicode_ci'
)
if connection.is_connected():
print(f"Connected to MySQL Server.")
return connection
except Error as e:
print(f"Error while connecting to MySQL: {e}")
return connection
def create_database(connection):
"""Create the fhem database if it doesn't exist."""
try:
cursor = connection.cursor()
cursor.execute(f"CREATE DATABASE IF NOT EXISTS {DB_NAME} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;")
print(f"Database '{DB_NAME}' created or already exists with utf8mb4_unicode_ci collation.")
except Error as e:
print(f"Error creating database: {e}")
def create_table(connection):
"""Create the devices table in the fhem database."""
try:
cursor = connection.cursor()
cursor.execute(f"USE {DB_NAME};")
create_table_query = f"""
CREATE TABLE IF NOT EXISTS {TABLE_NAME} (
Device_id VARCHAR(255) PRIMARY KEY,
Room VARCHAR(255),
alias VARCHAR(255) NOT NULL
) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
"""
cursor.execute(create_table_query)
print(f"Table '{TABLE_NAME}' created or already exists in database '{DB_NAME}'.")
except Error as e:
print(f"Error creating table: {e}")
def insert_device_data(connection, device_id, room, alias):
"""Insert a device's data into the devices table."""
try:
cursor = connection.cursor()
insert_query = f"""
INSERT INTO {TABLE_NAME} (Device_id, Room, alias)
VALUES (%s, %s, %s)
ON DUPLICATE KEY UPDATE Room = VALUES(Room), alias = VALUES(alias);
"""
cursor.execute(insert_query, (device_id, room, alias))
connection.commit()
print(f"Inserted/Updated Device: {device_id}, Room: {room}, Alias: {alias}")
except Error as e:
print(f"Error inserting data: {e}")
def get_device_details(device_name, csrf_token):
"""Fetch the room and alias attributes for a given device from FHEM."""
try:
detail_url = f"{FHEM_URL_BASE}?detail={device_name}"
headers = {
"X-FHEM-csrfToken": csrf_token,
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "application/json"
}
response = session.get(detail_url, headers=headers, timeout=10)
response.raise_for_status()
soup = BeautifulSoup(response.text, 'html.parser')
attributes_table = soup.find('table', class_='block wide attributes')
alias = None
room = None
if attributes_table:
rows = attributes_table.find_all('tr')
for row in rows:
name_div = row.find('div', class_='dname')
value_div = row.find('div', class_='dval')
if name_div and value_div:
attr_name = name_div.text.strip()
attr_value = value_div.text.strip()
if attr_name == "alias":
alias = attr_value
elif attr_name == "room":
room = attr_value
return alias, room
except (HTTPError, Timeout) as err:
print(f"Error fetching details for device {device_name}: {err}")
return None, None
except RequestException as req_err:
print(f"An error occurred: {req_err}")
return None, None
def read_log_and_insert_into_db(connection, csrf_token):
"""Read the log file, fetch device details, and insert them into the database."""
try:
with open(LOG_FILE_PATH, 'r') as log_file:
for line in log_file:
match = re.search(r'Device: (MA_[a-zA-Z0-9]+), State:', line)
if match:
device_name = match.group(1)
alias, room = get_device_details(device_name, csrf_token)
if alias and room:
insert_device_data(connection, device_name, room, alias)
elif alias: # In case room is not defined
insert_device_data(connection, device_name, None, alias)
except FileNotFoundError:
print(f"Log file '{LOG_FILE_PATH}' not found.")
def main():