Skip to content

Commit

Permalink
recommit
Browse files Browse the repository at this point in the history
  • Loading branch information
m4dm4rtig4n committed Dec 22, 2023
1 parent 9110228 commit 08463e4
Show file tree
Hide file tree
Showing 19 changed files with 391 additions and 87 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
/app/templates/models/__pycache__/
/app/models/__pycache__/
/app/routers/__pycache__/
tests/__pycache__/test_jobs.cpython-310-pytest-7.4.0.pyc
2 changes: 1 addition & 1 deletion app/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.9.2.b7
0.9.2.b9
10 changes: 8 additions & 2 deletions app/dependencies.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import datetime
import logging
from math import floor
from os import environ, getenv
from os import environ, getenv, path

from art import decor, text2art

Expand All @@ -15,6 +15,11 @@
else:
APPLICATION_PATH_DATA = "/data"

if "CONFIG_PATH" in environ:
CONFIG_PATH = getenv("CONFIG_PATH")
else:
CONFIG_PATH = path.join(APPLICATION_PATH_DATA, "config.yaml")

paypal_footer = """
<div style="text-align: center" id="paypal" class="paypal_link">
<form action="https://www.paypal.com/donate" method="post" target="_top" style="height: 55px;" id="paypal_form">
Expand Down Expand Up @@ -130,7 +135,8 @@ def finish():


def get_version():
f = open("/app/VERSION", "r")
version_file = path.join(APPLICATION_PATH, "VERSION")
f = open(version_file, "r")
version = f.read()
f.close()
return version.strip()
Expand Down
17 changes: 11 additions & 6 deletions app/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@
import yaml

from config import LOG_FORMAT, LOG_FORMAT_DATE
from dependencies import APPLICATION_PATH_DATA, str2bool
from dependencies import APPLICATION_PATH_DATA, CONFIG_PATH, str2bool
from models.config import Config
from models.database import Database
from models.influxdb import InfluxDB
from models.mqtt import Mqtt

# LOGGING CONFIGURATION
config = {}
if path.exists("/data/config.yaml"):
with open(f'/data/config.yaml') as file:

if path.exists(CONFIG_PATH):
with open(CONFIG_PATH) as file:
config = yaml.load(file, Loader=yaml.FullLoader)

if "DEBUG" in environ and str2bool(getenv("DEBUG")):
Expand All @@ -43,8 +44,8 @@
level=logging_level
)

if not path.exists("/data/config.yaml"):
logging.critical("Config file is not found (/data/config.yaml)")
if not path.exists(CONFIG_PATH):
logging.critical(f"Config file is not found ({CONFIG_PATH})")
exit()


Expand All @@ -68,7 +69,7 @@ def filter(self, record: logging.LogRecord) -> bool:
locale.setlocale(locale.LC_ALL, 'fr_FR.UTF-8')

CONFIG = Config(
path=APPLICATION_PATH_DATA
path=CONFIG_PATH
)
CONFIG.load()
CONFIG.display()
Expand All @@ -90,10 +91,14 @@ def filter(self, record: logging.LogRecord) -> bool:
else:
method = "SYNCHRONOUS"

if "scheme" not in INFLUXDB_CONFIG:
INFLUXDB_CONFIG["scheme"] = "http"

write_options = []
if "batching_options" in INFLUXDB_CONFIG:
write_options = INFLUXDB_CONFIG["batching_options"]
INFLUXDB = InfluxDB(
scheme=INFLUXDB_CONFIG["scheme"],
hostname=INFLUXDB_CONFIG["hostname"],
port=INFLUXDB_CONFIG["port"],
token=INFLUXDB_CONFIG["token"],
Expand Down
16 changes: 8 additions & 8 deletions app/models/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@

import yaml

from dependencies import title, separator
from dependencies import title, separator, CONFIG_PATH


class Config:

def __init__(self, path="/data"):
self.path = path
def __init__(self, path=CONFIG_PATH):
self.path = os.path.dirname(path) # Folder containing the config file
self.db = None
self.file = "config.yaml"
self.file = os.path.basename(path) # Name of the config file
self.path_file = f"{self.path}/{self.file}"
self.config = {}
self.mandatory_parameters = {}
self.default_port = 5000
self.mandatory_parameters = {}
# "myelectricaldata": {
# "pdl": {
# "enable": True,
Expand Down Expand Up @@ -51,7 +51,7 @@ def __init__(self, path="/data"):
"debug": False,
"log2file": False,
"tempo": {
"enable": True,
"enable": False,
},
"myelectricaldata": {
"pdl": {
Expand Down Expand Up @@ -128,14 +128,14 @@ def set_db(self, db):
def load(self):
config_file = f'{self.path_file}'
if os.path.exists(config_file):
with open(f'{self.path}/config.yaml') as file:
with open(config_file) as file:
self.config = yaml.load(file, Loader=yaml.FullLoader)

else:
f = open(config_file, "a")
f.write(yaml.dump(self.default))
f.close()
with open(f'{self.path}/config.yaml') as file:
with open(config_file) as file:
self.config = yaml.load(file, Loader=yaml.FullLoader)

if self.config is None:
Expand Down
20 changes: 16 additions & 4 deletions app/models/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from sqlalchemy import (create_engine, delete, inspect, update, select, func, desc, asc)
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.pool import NullPool

from config import MAX_IMPORT_TRY
from db_schema import (
Config,
Expand All @@ -26,14 +25,17 @@
Ecowatt,
Statistique
)
from dependencies import str2bool, title, get_version, title_warning
from dependencies import str2bool, title, get_version, title_warning, APPLICATION_PATH_DATA, APPLICATION_PATH

from alembic.config import Config as AlembicConfig
from alembic import command

# available_database = ["sqlite", "postgresql", "mysql+pymysql"]
available_database = ["sqlite", "postgresql"]


class Database:
def __init__(self, config, path="/data"):
def __init__(self, config, path=APPLICATION_PATH_DATA):
self.config = config
self.path = path

Expand All @@ -48,7 +50,17 @@ def __init__(self, config, path="/data"):
else:
logging.critical(f"Database {self.storage_type} not supported (only SQLite & PostgresSQL)")

os.system(f"cd /app; DB_URL='{self.uri}' alembic upgrade head ")
# Use alembic commands rather than dropping into shell for running migrations
alembic_dir = os.path.join(APPLICATION_PATH, "alembic")
alembic_ini = os.path.join(APPLICATION_PATH, "alembic.ini")
alembic_cfg = AlembicConfig(alembic_ini)
alembic_cfg.set_main_option('script_location', alembic_dir)

# Define DB_URL envvar rather than using set_main_option so that command line
# migrations are still possible
os.environ["DB_URL"] = self.uri

command.upgrade(alembic_cfg, "head")

self.engine = create_engine(
self.uri, echo=False,
Expand Down
20 changes: 10 additions & 10 deletions app/models/export_home_assistant.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def export(self):
self.ecowatt()

def sensor(self, **kwargs):
logging.info(f"- sensor.{kwargs['device_name'].lower().replace(' ', '_')}_{kwargs['uniq_id']}")
logging.info(f"- sensor.{kwargs['device_name'].lower().replace(' ', '_')}_{kwargs['name'].lower().replace(' ', '_')}")
topic = f"{self.discovery_prefix}/sensor/{kwargs['topic']}"
if "device_class" not in kwargs:
device_class = None
Expand Down Expand Up @@ -155,7 +155,7 @@ def sensor(self, **kwargs):

# sensor.linky_01226049119129_myelectricaldata_consumption_01226049119129_history
def last_x_day(self, days, measurement_direction):
uniq_id = f"linky_{measurement_direction}_last{days}day"
uniq_id = f"myelectricaldata_linky_{self.usage_point_id}_{measurement_direction}_last{days}day"
end = datetime.combine(datetime.now() - timedelta(days=1), datetime.max.time())
begin = datetime.combine(end - timedelta(days), datetime.min.time())
range = self.db.get_detail_range(self.usage_point_id, begin, end, measurement_direction)
Expand All @@ -178,7 +178,7 @@ def last_x_day(self, days, measurement_direction):
)

def history_usage_point_id(self, measurement_direction):
uniq_id = f"linky_{measurement_direction}_history"
uniq_id = f"myelectricaldata_linky_{self.usage_point_id}_{measurement_direction}_history"
stats = Stat(self.usage_point_id, measurement_direction)
state = self.db.get_daily_last(self.usage_point_id, measurement_direction)
if state:
Expand Down Expand Up @@ -552,7 +552,7 @@ def myelectricaldata_usage_point_id(self, measurement_direction):
# "info": info
}

uniq_id = f"linky_{self.usage_point_id}_{measurement_direction}"
uniq_id = f"myelectricaldata_linky_{self.usage_point_id}_{measurement_direction}"
self.sensor(
topic=f"myelectricaldata_{measurement_direction}/{self.usage_point_id}",
name=f"{measurement_direction}",
Expand All @@ -568,7 +568,7 @@ def myelectricaldata_usage_point_id(self, measurement_direction):
)

def tempo(self):
uniq_id = f"today"
uniq_id = f"myelectricaldata_tempo_today"
begin = datetime.combine(datetime.now(), datetime.min.time())
end = datetime.combine(datetime.now(), datetime.max.time())
tempo_data = self.db.get_tempo_range(begin, end, "asc")
Expand All @@ -593,7 +593,7 @@ def tempo(self):
state=state
)

uniq_id = f"tomorrow"
uniq_id = f"myelectricaldata_tempo_tomorrow"
begin = begin + timedelta(days=1)
end = end + timedelta(days=1)
tempo_data = self.db.get_tempo_range(begin, end, "asc")
Expand Down Expand Up @@ -623,7 +623,7 @@ def tempo_days(self):
self.tempo_days_sensor(f"{color}", days)

def tempo_days_sensor(self, color, days):
uniq_id = f"days_{color}"
uniq_id = f"myelectricaldata_tempo_days_{color}"
self.sensor(
topic=f"myelectricaldata_edf/tempo_days_{color}",
name=f"Days {color.capitalize()}",
Expand All @@ -635,7 +635,7 @@ def tempo_days_sensor(self, color, days):
)

def tempo_info(self):
uniq_id = f"info"
uniq_id = f"myelectricaldata_tempo_info"
tempo_days = self.db.get_tempo_config("days")
tempo_price = self.db.get_tempo_config("price")
if 22 > int(datetime.now().strftime("%H")) < 6:
Expand Down Expand Up @@ -676,7 +676,7 @@ def tempo_price(self):
f"{color.split('_')[0].capitalize()}{color.split('_')[1].capitalize()}")

def tempo_price_sensor(self, color, price, name):
uniq_id = f"price_{color}"
uniq_id = f"myelectricaldata_tempo_price_{color}"
name = f"{name[0:-2]} {name[-2:]}"
self.sensor(
topic=f"myelectricaldata_edf/tempo_price_{color}",
Expand All @@ -695,7 +695,7 @@ def ecowatt(self):
self.ecowatt_delta("J2", 2)

def ecowatt_delta(self, name, delta):
uniq_id = f"ecowatt_{name}"
uniq_id = f"myelectricaldata_ecowatt_{name}"
current_date = datetime.combine(datetime.now(), datetime.min.time()) + timedelta(days=delta)
fetch_date = current_date - timedelta(days=1)
ecowatt_data = self.db.get_ecowatt_range(fetch_date, fetch_date, "asc")
Expand Down
21 changes: 12 additions & 9 deletions app/models/influxdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@

import influxdb_client
from dateutil.tz import tzlocal
from dependencies import title, separator, separator_warning
from influxdb_client.client.util import date_utils
from influxdb_client.client.util.date_utils import DateHelper
from influxdb_client.client.write_api import ASYNCHRONOUS, SYNCHRONOUS

from dependencies import title, separator, separator_warning


class InfluxDB:

def __init__(
self,
scheme: str,
hostname: str,
port: int,
token: str,
Expand All @@ -24,6 +24,7 @@ def __init__(
):
if write_options is None:
write_options = {}
self.scheme = scheme
self.hostname = hostname
self.port = port
self.token = token
Expand Down Expand Up @@ -85,7 +86,7 @@ def connect(self):
logging.info(f"Connect to InfluxDB {self.hostname}:{self.port}")
date_utils.date_helper = DateHelper(timezone=tzlocal())
self.influxdb = influxdb_client.InfluxDBClient(
url=f"http://{self.hostname}:{self.port}",
url=f"{self.scheme}://{self.hostname}:{self.port}",
token=self.token,
org=self.org,
timeout="600000"
Expand All @@ -94,12 +95,14 @@ def connect(self):
if health.status == "pass":
title("Connection success")
else:
logging.critical([
"Impossible de se connecter à la base influxdb.",
"",
"Vous pouvez récupérer un exemple ici :",
"https://github.com/m4dm4rtig4n/enedisgateway2mqtt#configuration-file"
])
logging.critical("""
Impossible de se connecter à la base influxdb.
Vous pouvez récupérer un exemple ici :
https://github.com/m4dm4rtig4n/enedisgateway2mqtt#configuration-file
""")
exit(1)

title(f"Méthode d'importation : {self.method.upper()}")
if self.method.upper() == "ASYNCHRONOUS":
Expand Down
9 changes: 5 additions & 4 deletions app/models/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ def __init__(self, usage_point_id=None):
def boot(self):
if ("DEV" in environ and getenv("DEV")) or ("DEBUG" in environ and getenv("DEBUG")):
logging.warning("=> Import job disable")
return False
else:
self.job_import_data()
return self.job_import_data()["status"]

def job_import_data(self, wait=True, target=None):
def job_import_data(self, wait=True, target=None) -> dict:
if self.db.lock_status():
return {
"status": False,
Expand Down Expand Up @@ -159,11 +160,11 @@ def header_generate(self, token=True):
output['Authorization'] = self.usage_point_config.token
return output

def get_gateway_status(self):
def get_gateway_status(self) -> dict:
detail = "Récupération du statut de la passerelle :"
try:
title(detail)
Status(headers=self.header_generate(token=False)).ping()
return Status(headers=self.header_generate(token=False)).ping()
except Exception as e:
traceback.print_exc()
logging.error(f"Erreur lors de la {detail.lower()}")
Expand Down
Loading

0 comments on commit 08463e4

Please sign in to comment.