2023-10-22 01:55:11 +02:00
|
|
|
from peewee import SqliteDatabase
|
|
|
|
|
from datetime import datetime, timedelta, date
|
2023-11-06 19:45:39 +01:00
|
|
|
import calendar, requests, re, time, json, os, logging
|
2023-10-22 01:55:11 +02:00
|
|
|
import http.cookiejar as cookiejar
|
|
|
|
|
from requests.exceptions import HTTPError
|
|
|
|
|
from bs4 import BeautifulSoup
|
|
|
|
|
from enum import Enum
|
2023-11-06 19:45:39 +01:00
|
|
|
from peewee import AutoField, Model, CharField, IntegerField, DateField, BooleanField, CompositeKey, DecimalField, ForeignKeyField, SQL
|
|
|
|
|
import urllib.parse
|
2023-10-22 01:55:11 +02:00
|
|
|
|
2023-11-06 19:45:39 +01:00
|
|
|
logger = logging.getLogger("energaMeter")
|
|
|
|
|
|
|
|
|
|
path = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
|
db_file = 'database.sqlite'
|
|
|
|
|
db = SqliteDatabase(os.path.join(path, db_file))
|
2023-10-22 01:55:11 +02:00
|
|
|
|
|
|
|
|
class ChartType(Enum):
|
|
|
|
|
DAY = "DAY"
|
|
|
|
|
MONTH = "MONTH"
|
|
|
|
|
YEAR = "YEAR"
|
|
|
|
|
|
|
|
|
|
class PPETable(Model):
|
2023-11-06 19:45:39 +01:00
|
|
|
id = CharField(primary_key=True)
|
|
|
|
|
ppe = CharField(unique=True)
|
2023-10-22 01:55:11 +02:00
|
|
|
tariffCode = CharField()
|
2023-11-06 19:45:39 +01:00
|
|
|
type = CharField()
|
2023-10-22 01:55:11 +02:00
|
|
|
name = CharField()
|
2023-11-06 19:45:39 +01:00
|
|
|
last_update_date = DateField(null=True)
|
2023-10-22 01:55:11 +02:00
|
|
|
is_active = BooleanField(default=True)
|
2023-11-06 19:45:39 +01:00
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
database = db
|
|
|
|
|
table_name = 'PPE'
|
|
|
|
|
constraints = [SQL('UNIQUE (ppe, tariffCode)')]
|
|
|
|
|
|
|
|
|
|
class MeterTable(Model):
|
|
|
|
|
id = AutoField() # Meter point
|
|
|
|
|
ppe_id = ForeignKeyField(PPETable, backref='zones')
|
|
|
|
|
meter_type = CharField()
|
|
|
|
|
last_update_date = DateField(null=True)
|
2023-10-22 01:55:11 +02:00
|
|
|
first_date = DateField(null=True)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
database = db
|
2023-11-06 19:45:39 +01:00
|
|
|
table_name = 'METER'
|
|
|
|
|
constraints = [SQL('UNIQUE (ppe_id, meter_type)')]
|
|
|
|
|
|
|
|
|
|
class CounterTable(Model):
|
|
|
|
|
id = AutoField()
|
|
|
|
|
meter_id = ForeignKeyField(MeterTable, backref='meter')
|
|
|
|
|
tariff = CharField()
|
|
|
|
|
measurement_date = DateField(null=True)
|
|
|
|
|
meter_value = DecimalField(max_digits=15, decimal_places=5, null=True)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
database = db
|
|
|
|
|
table_name = 'COUNTER'
|
|
|
|
|
|
|
|
|
|
# class CounterTable(Model):
|
|
|
|
|
# meter_id = ForeignKeyField(MeterTable, backref='zones')
|
|
|
|
|
# measurement_date = DateField(null=True)
|
|
|
|
|
# meter_value = DecimalField(max_digits=15, decimal_places=5, null=True)
|
|
|
|
|
|
|
|
|
|
# class Meta:
|
|
|
|
|
# database = db
|
|
|
|
|
|
2023-10-22 01:55:11 +02:00
|
|
|
|
|
|
|
|
class ChartTable(Model):
|
2023-11-06 19:45:39 +01:00
|
|
|
id = IntegerField()
|
|
|
|
|
meter_type = CharField()
|
2023-10-22 01:55:11 +02:00
|
|
|
year = IntegerField()
|
|
|
|
|
month = IntegerField(null=True)
|
|
|
|
|
day = IntegerField(null=True)
|
|
|
|
|
value =CharField()
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
database = db
|
2023-11-06 19:45:39 +01:00
|
|
|
table_name = 'CHART_CACHE'
|
2023-10-22 01:55:11 +02:00
|
|
|
primary_key = CompositeKey('id', 'year', 'month', 'day')
|
|
|
|
|
|
|
|
|
|
class MainChartTable(Model):
|
|
|
|
|
mp = CharField()
|
2023-11-06 19:45:39 +01:00
|
|
|
meter_type = CharField()
|
2023-10-22 01:55:11 +02:00
|
|
|
zone = IntegerField()
|
|
|
|
|
tm = IntegerField()
|
|
|
|
|
value = DecimalField(max_digits=20, decimal_places=16, null=True)
|
|
|
|
|
tarAvg = DecimalField(max_digits=20, decimal_places=16, null=True)
|
|
|
|
|
est = BooleanField(default=False)
|
|
|
|
|
cplt = BooleanField(default=False)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
database = db
|
2023-11-06 19:45:39 +01:00
|
|
|
table_name = 'CHART'
|
|
|
|
|
primary_key = CompositeKey('mp', 'meter_type', 'zone', 'tm')
|
|
|
|
|
|
|
|
|
|
def znajdz_typ_odbiorcy(element):
|
|
|
|
|
typ_odbiorcy = ''
|
|
|
|
|
div_elements = element.find_all('div', recursive=False)
|
|
|
|
|
for div_element in div_elements:
|
|
|
|
|
typ_span = div_element.find('span', text='Typ')
|
|
|
|
|
if typ_span:
|
|
|
|
|
typ_odbiorcy = typ_span.next_sibling.strip()
|
|
|
|
|
return typ_odbiorcy
|
|
|
|
|
typ_odbiorcy = znajdz_typ_odbiorcy(div_element) # Rekurencyjne przeszukiwanie zagnieżdżonych div
|
|
|
|
|
return typ_odbiorcy
|
|
|
|
|
|
|
|
|
|
def findCountners(page):
|
|
|
|
|
table = page.find('table')
|
|
|
|
|
countner_type_list = ["A-", "A+"]
|
|
|
|
|
data_list = []
|
|
|
|
|
|
|
|
|
|
# Jeśli znaleźliśmy tabelę, możemy przeszukać jej wiersze i komórki
|
|
|
|
|
if table:
|
|
|
|
|
for row in table.find_all('tr'):
|
|
|
|
|
cells = row.find_all('td')
|
|
|
|
|
if len(cells) > 1:
|
|
|
|
|
# Pobieramy opis z pierwszej komórki
|
|
|
|
|
description = cells[0].text.strip()
|
|
|
|
|
|
|
|
|
|
# Pomijamy, jeśli rodzaj_licznika jest pusty
|
|
|
|
|
if not description:
|
|
|
|
|
continue
|
2023-10-22 01:55:11 +02:00
|
|
|
|
2023-11-06 19:45:39 +01:00
|
|
|
# Usuwamy datę z opisu
|
|
|
|
|
description_parts = description.split('\n')
|
|
|
|
|
meter_type = description_parts[0][:2].strip()
|
|
|
|
|
|
|
|
|
|
if meter_type not in countner_type_list:
|
|
|
|
|
continue
|
2023-10-22 01:55:11 +02:00
|
|
|
|
2023-11-06 19:45:39 +01:00
|
|
|
tariff0 = description_parts[0][2:].strip()
|
|
|
|
|
tariff = ''.join(filter(str.isdigit, tariff0))
|
|
|
|
|
measurement_date = description_parts[1].strip()
|
|
|
|
|
|
|
|
|
|
# Pobieramy dane liczbowe z drugiej komórki
|
|
|
|
|
data = cells[1].text.strip()
|
|
|
|
|
|
|
|
|
|
# Usuwamy znaki nowej linii i spacje z danych
|
|
|
|
|
data = data.replace('\n', '').replace(' ', '')
|
|
|
|
|
|
|
|
|
|
data = data.replace(',', '.')
|
|
|
|
|
|
|
|
|
|
# Dzielimy dane na część całkowitą i część dziesiętną
|
|
|
|
|
parts = data.split('.')
|
|
|
|
|
if len(parts) == 2:
|
|
|
|
|
integer_part = parts[0]
|
|
|
|
|
decimal_part = parts[1]
|
|
|
|
|
else:
|
|
|
|
|
integer_part = parts[0]
|
|
|
|
|
decimal_part = '0'
|
|
|
|
|
|
|
|
|
|
data_dict = {
|
|
|
|
|
"meter_type": meter_type,
|
|
|
|
|
"tariff": tariff,
|
|
|
|
|
"measurement_date": measurement_date,
|
|
|
|
|
"meter_value": f"{integer_part}.{decimal_part}"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data_list.append(data_dict)
|
|
|
|
|
return data_list
|
2023-10-22 01:55:11 +02:00
|
|
|
|
|
|
|
|
class MojLicznik:
|
|
|
|
|
|
|
|
|
|
session = requests.Session()
|
|
|
|
|
session.cookies = cookiejar.LWPCookieJar(filename='cookies.txt')
|
|
|
|
|
|
|
|
|
|
meter_url = "https://mojlicznik.energa-operator.pl"
|
|
|
|
|
|
2023-11-06 19:45:39 +01:00
|
|
|
|
|
|
|
|
|
2023-10-22 01:55:11 +02:00
|
|
|
def databaseInit(self):
|
|
|
|
|
db.create_tables([PPETable], safe=True)
|
2023-11-06 19:45:39 +01:00
|
|
|
db.create_tables([MeterTable], safe=True)
|
|
|
|
|
db.create_tables([CounterTable], safe=True)
|
|
|
|
|
db.create_tables([ChartTable], safe=True)
|
2023-10-22 01:55:11 +02:00
|
|
|
db.create_tables([MainChartTable], safe=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self.username = None
|
|
|
|
|
self.password = None
|
|
|
|
|
self.loginStatus = False
|
|
|
|
|
self.data = [] # Change self.data to a list
|
|
|
|
|
self.ppes = []
|
|
|
|
|
self.databaseInit()
|
|
|
|
|
|
|
|
|
|
def login(self, _username, _password):
|
|
|
|
|
|
|
|
|
|
self.username = _username
|
|
|
|
|
self.password = _password
|
|
|
|
|
|
|
|
|
|
login_url = f"{self.meter_url}/dp/UserLogin.do"
|
|
|
|
|
|
2023-11-06 19:45:39 +01:00
|
|
|
self.loginStatus = False
|
|
|
|
|
|
2023-10-22 01:55:11 +02:00
|
|
|
try:
|
2023-11-06 19:45:39 +01:00
|
|
|
logger.debug("Pobieram formularz logowania.")
|
2023-10-22 01:55:11 +02:00
|
|
|
response = self.session.get(login_url)
|
|
|
|
|
response.raise_for_status()
|
2023-11-06 19:45:39 +01:00
|
|
|
if response.url == 'https://mojlicznik.energa-operator.pl/maintenance.html':
|
|
|
|
|
logger.critical("Trwają prace serwisowe w Mój Licznik. Logowanie nie jest możliwe, spróbuj później.")
|
|
|
|
|
return
|
2023-10-22 01:55:11 +02:00
|
|
|
|
|
|
|
|
except HTTPError as e:
|
2023-11-06 19:45:39 +01:00
|
|
|
logger.error(f"Wystąpił błąd HTTP: {e}")
|
2023-10-22 01:55:11 +02:00
|
|
|
|
|
|
|
|
soup = BeautifulSoup(response.text, 'html.parser')
|
|
|
|
|
csrf_token = soup.find('input', {'name': '_antixsrf'})['value']
|
|
|
|
|
|
|
|
|
|
login_data = {
|
|
|
|
|
'j_username': self.username,
|
|
|
|
|
'j_password': self.password,
|
|
|
|
|
'selectedForm': '1',
|
|
|
|
|
'save': 'save',
|
|
|
|
|
'clientOS': 'web',
|
|
|
|
|
'_antixsrf': csrf_token
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
response = self.session.post(login_url, data=login_data)
|
|
|
|
|
response.raise_for_status()
|
2023-10-22 15:09:06 +02:00
|
|
|
|
|
|
|
|
|
2023-10-22 01:55:11 +02:00
|
|
|
except HTTPError as e:
|
2023-11-06 19:45:39 +01:00
|
|
|
logger.error(f"Wystąpił błąd HTTP: {e}")
|
2023-10-22 01:55:11 +02:00
|
|
|
|
|
|
|
|
soup = BeautifulSoup(response.text, 'html.parser')
|
2023-10-22 15:09:06 +02:00
|
|
|
|
|
|
|
|
login_error_text = 'Użytkownik lub hasło niepoprawne'
|
|
|
|
|
login_error = soup.find('div', text=login_error_text)
|
|
|
|
|
|
|
|
|
|
if login_error:
|
2023-11-06 19:45:39 +01:00
|
|
|
logger.critical(login_error_text)
|
|
|
|
|
return
|
2023-10-22 15:09:06 +02:00
|
|
|
else:
|
|
|
|
|
self.loginStatus = True
|
2023-11-06 19:45:39 +01:00
|
|
|
logger.info(f"Zalogowano")
|
|
|
|
|
|
|
|
|
|
body = soup.find('body')
|
|
|
|
|
type_value = znajdz_typ_odbiorcy(body)
|
2023-10-22 15:09:06 +02:00
|
|
|
|
2023-11-06 19:45:39 +01:00
|
|
|
logger.debug(f"Typ umowy: {type_value}.")
|
2023-10-22 15:09:06 +02:00
|
|
|
select_elements = soup.find_all('script', type='text/javascript')
|
|
|
|
|
meter_isd = []
|
|
|
|
|
for el in select_elements:
|
|
|
|
|
pattern = r"id:\s+(\d+),[\s\S]*?ppe:\s+'([\d\s]+)',[\s\S]*?tariffCode:\s+'([^']+)',[\s\S]*?name:\s+'([^']+)'"
|
|
|
|
|
matches = re.search(pattern, el.text)
|
|
|
|
|
if matches:
|
|
|
|
|
id_value = matches.group(1)
|
|
|
|
|
ppe_value = matches.group(2)
|
|
|
|
|
tariffCode_value = matches.group(3)
|
|
|
|
|
name_value = matches.group(4)
|
|
|
|
|
meter_isd.append(id_value)
|
|
|
|
|
retrieved_record = PPETable.get_or_none(id=id_value)
|
|
|
|
|
if retrieved_record:
|
2023-11-06 19:45:39 +01:00
|
|
|
logger.info(f"Licznik {id_value} istnieje w systemie.")
|
2023-10-22 15:09:06 +02:00
|
|
|
if not retrieved_record.is_active:
|
|
|
|
|
retrieved_record.is_active = True
|
|
|
|
|
retrieved_record.save()
|
|
|
|
|
else:
|
2023-11-06 19:45:39 +01:00
|
|
|
logger.info(f"Licznik {id_value} nie istnieje w systemie, zostanie dodany.")
|
2023-10-22 15:09:06 +02:00
|
|
|
data = PPETable.create(
|
|
|
|
|
id=id_value,
|
|
|
|
|
ppe=ppe_value,
|
|
|
|
|
tariffCode=tariffCode_value,
|
2023-11-06 19:45:39 +01:00
|
|
|
type=type_value,
|
2023-10-22 15:09:06 +02:00
|
|
|
name=name_value
|
|
|
|
|
)
|
|
|
|
|
update_query = PPETable.update(is_active=0).where(PPETable.id.not_in(meter_isd))
|
|
|
|
|
update_query.execute()
|
2023-10-22 01:55:11 +02:00
|
|
|
|
|
|
|
|
def logout(self):
|
|
|
|
|
logout_url = f"{self.meter_url}/dp/MainLogout.go"
|
|
|
|
|
try:
|
|
|
|
|
response = self.session.get(logout_url)
|
|
|
|
|
response.raise_for_status()
|
|
|
|
|
self.loginStatus = False
|
2023-11-06 19:45:39 +01:00
|
|
|
logger.info(f"Wylogowano.")
|
2023-10-22 01:55:11 +02:00
|
|
|
except HTTPError as e:
|
2023-11-06 19:45:39 +01:00
|
|
|
logger.error(f"Wystąpił błąd HTTP: {e}")
|
2023-10-22 01:55:11 +02:00
|
|
|
|
2023-11-06 19:45:39 +01:00
|
|
|
def update_countners(self):
|
2023-10-22 01:55:11 +02:00
|
|
|
|
|
|
|
|
query = PPETable.select().where(PPETable.is_active == True)
|
|
|
|
|
result_ppes = query.execute()
|
|
|
|
|
for p in result_ppes:
|
|
|
|
|
meter_url = f"{self.meter_url}/dp/UserData.do?mpc={p.id}&ppe={p.ppe}"
|
|
|
|
|
try:
|
|
|
|
|
response = self.session.get(meter_url)
|
|
|
|
|
response.raise_for_status()
|
|
|
|
|
soup = BeautifulSoup(response.text, 'html.parser')
|
2023-11-06 19:45:39 +01:00
|
|
|
countners_dict = findCountners(soup)
|
|
|
|
|
|
|
|
|
|
for c in countners_dict:
|
|
|
|
|
mn, mu = MeterTable.get_or_create(ppe_id=p.id, meter_type=c['meter_type'])
|
|
|
|
|
mn.last_update_date = datetime.now()
|
|
|
|
|
mn.save()
|
|
|
|
|
cn, cu = CounterTable.get_or_create(
|
|
|
|
|
meter_id = mn.id,
|
|
|
|
|
tariff=c['tariff']
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
cn.meter_value = c['meter_value']
|
|
|
|
|
cn.measurement_date = c['measurement_date']
|
|
|
|
|
cn.save()
|
|
|
|
|
|
|
|
|
|
logger.info(f"Zapisano stan licznika {p.id} {c['meter_type']} taryfa {c['tariff']} z dnia: {c['measurement_date']} : {c['meter_value']}")
|
2023-10-22 01:55:11 +02:00
|
|
|
except HTTPError as e:
|
2023-11-06 19:45:39 +01:00
|
|
|
logger.error(f"Wystąpił błąd HTTP: {e}")
|
2023-10-22 01:55:11 +02:00
|
|
|
|
|
|
|
|
def update_first_date(self):
|
2023-11-06 19:45:39 +01:00
|
|
|
ppes_query = PPETable.select().where(PPETable.is_active == True)
|
|
|
|
|
result_ppes = ppes_query.execute()
|
2023-10-22 01:55:11 +02:00
|
|
|
for p in result_ppes:
|
2023-11-06 19:45:39 +01:00
|
|
|
meters_query = MeterTable.select().where((MeterTable.ppe_id == p.id) & (MeterTable.first_date.is_null(True)))
|
|
|
|
|
meters_result = meters_query.execute()
|
|
|
|
|
|
|
|
|
|
for meter in meters_result:
|
|
|
|
|
meter_type = meter.meter_type
|
|
|
|
|
|
|
|
|
|
print(f"Szukam najstarsze dane historyczne licznika {p.name} (PPE: {p.ppe}, {p.id}) typ: {meter_type}")
|
|
|
|
|
meter_point = p.id
|
|
|
|
|
max_years_back = 5
|
|
|
|
|
start_date = datetime.now()
|
|
|
|
|
last_chart_year = None
|
|
|
|
|
for n in range(max_years_back + 1):
|
|
|
|
|
first_day_of_year = datetime(start_date.year-n, 1, 1)
|
|
|
|
|
data_json = self.download_chart(ChartType.YEAR, first_day_of_year, meter_point, meter_type)
|
|
|
|
|
if data_json:
|
|
|
|
|
data = json.loads(data_json)
|
|
|
|
|
if data and data.get("mainChart") and len(data["mainChart"]) > 0:
|
|
|
|
|
last_chart_year = first_day_of_year.year
|
|
|
|
|
last_chart_month = None
|
|
|
|
|
max_month = 12
|
|
|
|
|
for n in range(max_month, 0, -1):
|
|
|
|
|
first_day_of_month = datetime(last_chart_year, n, 1)
|
|
|
|
|
data_json = self.download_chart(ChartType.MONTH, first_day_of_month, meter_point, meter_type)
|
|
|
|
|
if data_json:
|
|
|
|
|
data = json.loads(data_json)
|
|
|
|
|
if data and data.get("mainChart") and len(data["mainChart"]) > 0:
|
|
|
|
|
last_chart_month = n
|
|
|
|
|
last_chart_day = None
|
|
|
|
|
max_day = 31
|
|
|
|
|
first_day_of_day = datetime(last_chart_year, last_chart_month, 1)
|
|
|
|
|
_, max_day = calendar.monthrange(first_day_of_day.year, first_day_of_day.month)
|
|
|
|
|
for n in range(max_day, 0, -1):
|
|
|
|
|
first_day_of_day = datetime(last_chart_year, last_chart_month, n)
|
|
|
|
|
data_json = self.download_chart(ChartType.DAY, first_day_of_day, meter_point, meter_type)
|
|
|
|
|
if data_json:
|
|
|
|
|
data = json.loads(data_json)
|
|
|
|
|
if data and data.get("mainChart") and len(data["mainChart"]) > 0:
|
|
|
|
|
last_chart_day = n
|
|
|
|
|
first_date = datetime(last_chart_year, last_chart_month, last_chart_day).date()
|
|
|
|
|
print(f"Najstarsze dane historyczne dla licznika {p.name} (PPE: {p.ppe}, {p.id}) typ: {meter_type}: {first_date}")
|
|
|
|
|
meter.first_date = first_date
|
|
|
|
|
meter.save()
|
|
|
|
|
|
|
|
|
|
def save_main_charts(self, mp, vals, m_type):
|
2023-10-22 01:55:11 +02:00
|
|
|
for val in vals:
|
2023-11-06 19:45:39 +01:00
|
|
|
try:
|
|
|
|
|
logger.debug(f"save_main_charts: mp: {mp}, val: {val}, meter_type: {m_type}")
|
2023-10-22 01:55:11 +02:00
|
|
|
z = val["zones"]
|
|
|
|
|
if z[0]:
|
|
|
|
|
# MainChartTable.get_or_create(tm = val["tm"], zone = 1, value = z[0], tarAvg=val["tarAvg"], est=val["est"], cplt=val["cplt"])
|
|
|
|
|
try:
|
2023-11-06 19:45:39 +01:00
|
|
|
existing_record = MainChartTable.get((MainChartTable.meter_type == m_type) & (MainChartTable.mp == mp) & (MainChartTable.tm == val["tm"]) & (MainChartTable.zone == 1))
|
2023-10-22 01:55:11 +02:00
|
|
|
except MainChartTable.DoesNotExist:
|
|
|
|
|
# Jeśli rekord nie istnieje, utwórz nowy
|
|
|
|
|
MainChartTable.create(
|
|
|
|
|
mp=mp,
|
2023-11-06 19:45:39 +01:00
|
|
|
meter_type=m_type,
|
2023-10-22 01:55:11 +02:00
|
|
|
tm=val["tm"],
|
|
|
|
|
zone=1,
|
|
|
|
|
value=z[0],
|
|
|
|
|
tarAvg=val["tarAvg"],
|
|
|
|
|
est=val["est"],
|
|
|
|
|
cplt=val["cplt"]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if z[1]:
|
|
|
|
|
try:
|
2023-11-06 19:45:39 +01:00
|
|
|
existing_record = MainChartTable.get((MainChartTable.meter_type == m_type) & (MainChartTable.mp == mp) & (MainChartTable.tm == val["tm"]) & (MainChartTable.zone == 2))
|
2023-10-22 01:55:11 +02:00
|
|
|
except MainChartTable.DoesNotExist:
|
|
|
|
|
# Jeśli rekord nie istnieje, utwórz nowy
|
|
|
|
|
MainChartTable.create(
|
|
|
|
|
mp=mp,
|
2023-11-06 19:45:39 +01:00
|
|
|
meter_type=m_type,
|
2023-10-22 01:55:11 +02:00
|
|
|
tm=val["tm"],
|
|
|
|
|
zone=2,
|
|
|
|
|
value=z[1],
|
|
|
|
|
tarAvg=val["tarAvg"],
|
|
|
|
|
est=val["est"],
|
|
|
|
|
cplt=val["cplt"]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if z[2]:
|
|
|
|
|
try:
|
2023-11-06 19:45:39 +01:00
|
|
|
existing_record = MainChartTable.get((MainChartTable.meter_type == m_type) & (MainChartTable.mp == mp) & (MainChartTable.tm == val["tm"]) & (MainChartTable.zone == 3))
|
2023-10-22 01:55:11 +02:00
|
|
|
except MainChartTable.DoesNotExist:
|
|
|
|
|
# Jeśli rekord nie istnieje, utwórz nowy
|
|
|
|
|
MainChartTable.create(
|
|
|
|
|
mp=mp,
|
2023-11-06 19:45:39 +01:00
|
|
|
meter_type=m_type,
|
2023-10-22 01:55:11 +02:00
|
|
|
tm=val["tm"],
|
|
|
|
|
zone=3,
|
|
|
|
|
value=z[2],
|
|
|
|
|
tarAvg=val["tarAvg"],
|
|
|
|
|
est=val["est"],
|
|
|
|
|
cplt=val["cplt"]
|
|
|
|
|
)
|
|
|
|
|
|
2023-11-06 19:45:39 +01:00
|
|
|
except Exception as e:
|
|
|
|
|
logging.error(f"Wystąpił błąd: {str(e)}")
|
2023-10-22 01:55:11 +02:00
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
2023-11-06 19:45:39 +01:00
|
|
|
def download_chart(self, type, date, meter_point, meter_type, update_mode=False):
|
2023-10-22 01:55:11 +02:00
|
|
|
|
|
|
|
|
if type == ChartType.DAY:
|
|
|
|
|
chart_type = "DAY"
|
|
|
|
|
first_day = datetime(date.year, date.month, date.day)
|
|
|
|
|
tsm_date = int(time.mktime(first_day.timetuple()) * 1000)
|
|
|
|
|
|
|
|
|
|
if type == ChartType.MONTH:
|
|
|
|
|
chart_type = "MONTH"
|
|
|
|
|
first_day = datetime(date.year, date.month, 1)
|
|
|
|
|
tsm_date = int(time.mktime(first_day.timetuple()) * 1000)
|
|
|
|
|
|
|
|
|
|
if type == ChartType.YEAR:
|
|
|
|
|
chart_type = "YEAR"
|
|
|
|
|
first_day = datetime(date.year, 1, 1)
|
|
|
|
|
tsm_date = int(time.mktime(first_day.timetuple()) * 1000)
|
|
|
|
|
|
2023-11-06 19:45:39 +01:00
|
|
|
# meter_type = 'A+'
|
|
|
|
|
chart_url = f"{self.meter_url}/dp/resources/chart?mainChartDate={tsm_date}&type={chart_type}&meterPoint={meter_point}&mo={urllib.parse.quote_plus(meter_type)}"
|
|
|
|
|
logger.debug(f"chart_url: {chart_url}")
|
2023-10-22 01:55:11 +02:00
|
|
|
try:
|
|
|
|
|
response = self.session.get(chart_url)
|
|
|
|
|
data = json.loads(response.text)
|
|
|
|
|
response.raise_for_status()
|
|
|
|
|
if data["response"]:
|
|
|
|
|
id = data["response"]["meterPoint"]
|
|
|
|
|
mainChartDate = data["response"]["mainChartDate"]
|
|
|
|
|
mainChart = data["response"]["mainChart"]
|
|
|
|
|
if type == ChartType.DAY:
|
2023-11-06 19:45:39 +01:00
|
|
|
self.save_main_charts(meter_point, mainChart, meter_type)
|
2023-10-22 01:55:11 +02:00
|
|
|
|
|
|
|
|
date = int(mainChartDate) / 1000
|
|
|
|
|
month = None
|
|
|
|
|
day = None
|
|
|
|
|
dt = datetime.fromtimestamp(date)
|
|
|
|
|
year = dt.year
|
|
|
|
|
if type == ChartType.MONTH:
|
|
|
|
|
month = dt.month
|
|
|
|
|
if type == ChartType.DAY:
|
|
|
|
|
month = dt.month
|
|
|
|
|
day = dt.day
|
|
|
|
|
json_dump = json.dumps(data["response"], ensure_ascii=False)
|
|
|
|
|
if update_mode:
|
|
|
|
|
try:
|
|
|
|
|
chart_record = ChartTable.get(id=id,year=year, month=month, day=day)
|
|
|
|
|
chart_record.value = json_dump
|
|
|
|
|
chart_record.save()
|
|
|
|
|
except ChartTable.DoesNotExist:
|
2023-11-06 19:45:39 +01:00
|
|
|
chart_record = ChartTable.create(id=id, meter_type=meter_type, value=json_dump, year=year, month=month, day=day)
|
2023-10-22 01:55:11 +02:00
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
try:
|
2023-11-06 19:45:39 +01:00
|
|
|
ChartTable.create(id=id, meter_type=meter_type, value=json_dump, year=year, month=month, day=day)
|
2023-10-22 01:55:11 +02:00
|
|
|
except:
|
|
|
|
|
pass
|
|
|
|
|
return json_dump
|
|
|
|
|
return None
|
|
|
|
|
except HTTPError as e:
|
2023-11-06 19:45:39 +01:00
|
|
|
logger.error(f"Wystąpił błąd HTTP: {e}")
|
2023-10-22 01:55:11 +02:00
|
|
|
|
|
|
|
|
def download_charts(self, full_mode=False):
|
|
|
|
|
query = PPETable.select().where(PPETable.is_active == True)
|
|
|
|
|
result_ppes = query.execute()
|
|
|
|
|
for p in result_ppes:
|
2023-11-06 19:45:39 +01:00
|
|
|
meters_query = MeterTable.select().where((MeterTable.ppe_id == p.id)) # // & (MeterTable.first_date.is_null(True)))
|
|
|
|
|
meters_result = meters_query.execute()
|
|
|
|
|
|
|
|
|
|
for meter in meters_result:
|
|
|
|
|
meter_type = meter.meter_type
|
|
|
|
|
|
|
|
|
|
logger.info(f"Pobieram dane historyczne dla {p.name} ({p.id}) typ: {meter_type}")
|
|
|
|
|
current_date = meter.first_date
|
|
|
|
|
if not full_mode:
|
|
|
|
|
current_date = meter.last_update_date - timedelta(days=1)
|
|
|
|
|
|
|
|
|
|
while current_date <= date.today():
|
2023-11-07 19:54:45 +01:00
|
|
|
try:
|
|
|
|
|
if full_mode:
|
|
|
|
|
record = ChartTable.get(id=p.id, meter_type=meter_type, year=current_date.year, month=current_date.month, day=current_date.day)
|
|
|
|
|
logger.debug(f"Posiadam dane historyczne dla {p.name} ({p.id}) typ: {meter_type} na dzień: {current_date}")
|
|
|
|
|
else:
|
|
|
|
|
self.download_chart(ChartType.DAY, current_date, p.id, meter_type)
|
|
|
|
|
logger.debug(f"Aktualizuję dane dla {p.name} ({p.id}) typ: {meter_type} na dzień: {current_date}")
|
|
|
|
|
|
|
|
|
|
|
2023-11-06 19:45:39 +01:00
|
|
|
except ChartTable.DoesNotExist:
|
|
|
|
|
self.download_chart(ChartType.DAY, current_date, p.id, meter_type)
|
|
|
|
|
logger.debug(f"Pobieram dane historyczne dla {p.name} ({p.id}) typ: {meter_type} na dzień: {current_date}")
|
|
|
|
|
current_date += timedelta(days=1)
|
2023-10-22 01:55:11 +02:00
|
|
|
|
|
|
|
|
def update_last_days(self):
|
|
|
|
|
today = datetime.today().date()
|
|
|
|
|
query = PPETable.select().where(PPETable.is_active == True)
|
|
|
|
|
result_ppes = query.execute()
|
|
|
|
|
|
|
|
|
|
for p in result_ppes:
|
2023-11-06 19:45:39 +01:00
|
|
|
meters_query = MeterTable.select().where((MeterTable.ppe_id == p.id) & (MeterTable.first_date.is_null(True)))
|
|
|
|
|
meters_result = meters_query.execute()
|
|
|
|
|
|
|
|
|
|
for meter in meters_result:
|
|
|
|
|
meter_type = meter.meter_type
|
|
|
|
|
|
|
|
|
|
logger.info(f"Aktualizacja danych bieżących dla {p.name} ({p.id}) typ: {meter_type}")
|
|
|
|
|
if not p.last_update_date:
|
|
|
|
|
p.last_update_date = today - timedelta(days=5)
|
|
|
|
|
p.save()
|
|
|
|
|
last_update_date = p.last_update_date - timedelta(days=1)
|
|
|
|
|
while last_update_date <= today:
|
|
|
|
|
logger.debug(f"Aktualizacja danych dla {p.name} ({p.id}) typ: {meter_type} na dzień: {last_update_date}")
|
|
|
|
|
self.download_chart(ChartType.DAY, last_update_date, p.id, meter_type, True)
|
|
|
|
|
p.last_update_date = last_update_date
|
|
|
|
|
p.save()
|
|
|
|
|
last_update_date += timedelta(days=1)
|
2023-10-22 01:55:11 +02:00
|
|
|
|
|
|
|
|
def get_current_meters(self, add_daily_char_data=False):
|
|
|
|
|
|
|
|
|
|
query = PPETable.select().where(PPETable.is_active == True)
|
|
|
|
|
result_ppes = query.execute()
|
|
|
|
|
for p in result_ppes:
|
|
|
|
|
if add_daily_char_data:
|
|
|
|
|
query = ChartTable.select().where((ChartTable.id == p.id) & (ChartTable.year == p.measurement_date.year) & (ChartTable.month == p.measurement_date.month) & (ChartTable.day == p.measurement_date.day))
|
|
|
|
|
query_count = query.count()
|
|
|
|
|
if (query_count > 0):
|
|
|
|
|
query_first = query.first()
|
|
|
|
|
value_json = json.loads(query_first.value)
|
|
|
|
|
print(query_first.value)
|
|
|
|
|
zones = value_json.get("zones", [])
|
|
|
|
|
if zones:
|
|
|
|
|
zone1_data = zones[0]
|
|
|
|
|
zone1_main_chart = zone1_data.get("mainChart", [])
|
|
|
|
|
|
|
|
|
|
# def set_daily_zones(self):
|
|
|
|
|
# query = PPETable.select().where(PPETable.is_active == True)
|
|
|
|
|
# result_ppes = query.execute()
|
|
|
|
|
|
|
|
|
|
# for p in result_ppes:
|
2023-11-06 19:45:39 +01:00
|
|
|
# query = ChartTable.select().where(
|
|
|
|
|
# (ChartTable.id == p.id) &
|
|
|
|
|
# ((ChartTable.year > p.measurement_date.year) |
|
|
|
|
|
# ((ChartTable.year == p.measurement_date.year) &
|
|
|
|
|
# (ChartTable.month > p.measurement_date.month)) |
|
|
|
|
|
# ((ChartTable.year == p.measurement_date.year) &
|
|
|
|
|
# (ChartTable.month == p.measurement_date.month) &
|
|
|
|
|
# (ChartTable.day >= p.measurement_date.day))
|
|
|
|
|
# ))
|
|
|
|
|
|
|
|
|
|
# zones_sums = {f"zone{i+1}_daily_chart_sum": 0.0 for i in range(3)}
|
|
|
|
|
|
|
|
|
|
# for chart_entry in query:
|
|
|
|
|
# value_json = json.loads(chart_entry.value)
|
2023-10-22 01:55:11 +02:00
|
|
|
# main_chart = value_json.get("mainChart", [])
|
|
|
|
|
|
|
|
|
|
# for entry in main_chart:
|
|
|
|
|
# zones = entry.get("zones", [])
|
|
|
|
|
|
|
|
|
|
# for i, value in enumerate(zones):
|
|
|
|
|
# if value is not None:
|
2023-11-06 19:45:39 +01:00
|
|
|
# zones_sums[f"zone{i+1}_daily_chart_sum"] += value
|
|
|
|
|
|
|
|
|
|
# for key, value in zones_sums.items():
|
|
|
|
|
# setattr(p, key, value)
|
|
|
|
|
# p.save()
|
2023-10-22 01:55:11 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def print_summary_zones(self):
|
|
|
|
|
query = PPETable.select().where(PPETable.is_active == True)
|
|
|
|
|
result_ppes = query.execute()
|
|
|
|
|
for p in result_ppes:
|
|
|
|
|
zon1 = (p.zone1 if p.zone1 is not None else 0 ) + (p.zone1_daily_chart_sum if p.zone1_daily_chart_sum is not None else 0)
|
|
|
|
|
zon2 = (p.zone2 if p.zone2 is not None else 0 ) + (p.zone2_daily_chart_sum if p.zone2_daily_chart_sum is not None else 0)
|
|
|
|
|
zon3 = (p.zone3 if p.zone3 is not None else 0 ) + (p.zone3_daily_chart_sum if p.zone3_daily_chart_sum is not None else 0)
|
|
|
|
|
print(f"{p.name} : {round(zon1, 5)} "
|
|
|
|
|
f"{round(zon2,5)} "
|
|
|
|
|
f"{round(zon3,5)}")
|
|
|
|
|
|
|
|
|
|
def get_current_meters_list(self):
|
|
|
|
|
query = PPETable.select().where(PPETable.is_active == True)
|
|
|
|
|
return query.execute()
|
|
|
|
|
|
|
|
|
|
def get_current_meter_value(self, meter_id, zone):
|
|
|
|
|
if zone == "zone1":
|
|
|
|
|
pPETable = PPETable.get(PPETable.id == meter_id)
|
|
|
|
|
return pPETable.zone1
|
|
|
|
|
if zone == "zone2":
|
|
|
|
|
pPETable = PPETable.get(PPETable.id == meter_id)
|
|
|
|
|
return pPETable.zone2
|
|
|
|
|
if zone == "zone3":
|
|
|
|
|
pPETable = PPETable.get(PPETable.id == meter_id)
|
|
|
|
|
return pPETable.zone3
|
|
|
|
|
return None
|