Sélectionner une révision Git
enercoop_operation.py
acc_operation.py 51,14 Kio
# Copyright 2021 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import fields, models, api
from datetime import datetime, timedelta
from odoo.tools import date_utils
import dateutil.parser as parser
from dateutil.relativedelta import relativedelta
class AccOperation(models.Model):
_inherit = 'acc.operation'
# ------------------------------------------------------
# Actions
# ------------------------------------------------------
def action_view_courbes(self):
"""
Action qui ouvre la vue Qweb
:return: Vue Qweb
"""
self.ensure_one()
partner_id = self.env['res.partner'].browse(self.env.context.get('default_partner_id'))
action = self.env["ir.actions.actions"]._for_xml_id(
"acc_cdc.acc_operation_action_client_courbes")
action['params'] = {
'operation_ids': self.ids,
}
action['context'] = {
'active_id': self.id,
'active_ids': self.ids,
'search_default_name': self.name,
}
return action
# ------------------------------------------------------
# Business methods
# ------------------------------------------------------
def get_auto_power_tot(self):
"""
Fonction retournant l autoconsommation totale du dernier mois.
:return: la somme de l'autoconso totale de tous les consommateurs
"""
# Récupère les dates du dernier mois disponible
date_start, date_end = self.get_last_day('month')
# Conso Totale
autoconso_ids = self.env['acc.enedis.cdc'].search([
('acc_operation_id', '=', self.id),
('comp_data_type', '=', 'autocons'),
('date_slot', '>=', date_start),
('date_slot', '<', date_end)])
autoconso_tot = (sum(autoconso_ids.mapped('power')) / 1000) / 2
return autoconso_tot
def get_power_tot(self):
"""
Fonction retournant la consommation totale, l'autoconsommation totale et la production totale du dernier mois.
:return: la somme de la conso totale de tous les consommateurs,
la somme de l autoconso totale de tous les consommateurs,
la sommme de la prod totale de tous les producteurs
"""
# Récupère les dates du dernier mois disponible
date_start, date_end = self.get_last_day('month')
# Conso Totale
conso_ids = self.env['acc.enedis.cdc'].search([
('acc_operation_id', '=', self.id),
('comp_data_type', '=', 'cons'),
('date_slot', '>=', date_start),
('date_slot', '<', date_end)])
conso_tot = (sum(conso_ids.mapped('power')) / 1000) / 2
# Prod Totale
prod_ids = self.env['acc.enedis.cdc'].search([
('acc_operation_id', '=', self.id),
('comp_data_type', '=', 'prod'),
('date_slot', '>=', date_start),
('date_slot', '<', date_end)])
prod_tot = (sum(prod_ids.mapped('power')) / 1000) / 2
# Auto cons Totale
autoconso_ids = self.env['acc.enedis.cdc'].search([
('acc_operation_id', '=', self.id),
('comp_data_type', '=', 'autocons'),
('date_slot', '>=', date_start),
('date_slot', '<', date_end)])
autoconso_tot = (sum(autoconso_ids.mapped('power')) / 1000) / 2
return conso_tot, prod_tot, autoconso_tot
def get_power_install_tot(self):
"""
Fonction retournant la puissance totale installée.
:return: la somme de toutes les puissances d'injection
"""
puiss_tot = 0.0
for counter in self.acc_injection_ids:
puiss_tot += counter.acc_counter_id.power_instal
return puiss_tot
def get_last_day(self, scale):
"""
Fonction retournant une date de début et une date de fin.
Ces dates sont calculées en fonction de l'échelle choisie
- day: la date de début est égale à la dernière date
avec un enreisgtrement pour l'opération donnée
la date de fin ets la date de début + 1
- week: la date de début est égale à la dernière date
avec un enreisgtrement pour l'opération donnée moins 7 jours
la date de fin est égale à la dernière date
avec un enreisgtrement pour l'opération donnée
- month: la date de début est égale à la dernière date
avec un enreisgtrement pour l'opération donnée moins 1 mois
la date de fin est égale à la dernière date
avec un enreisgtrement pour l'opération donnée
- semestre: la date de début est égale à la dernière date
avec un enreisgtrement pour l'opération donnée moins 6 mois
la date de fin est égale à la dernière date
avec un enreisgtrement pour l'opération donnée
- year: la date de début est égale à la dernière date
avec un enreisgtrement pour l'opération donnée moins 1 an
la date de fin est égale à la dernière date
avec un enreisgtrement pour l'opération donnée
:param scale: type d'affichage des graphes
(day/week/month/semestre/year)
:return: une date de début et une date de fin
"""
# Get last date slot recorded
last_record = self.env['acc.enedis.cdc'].search([
('acc_operation_id', 'in', self.ids),
], limit=1, order='date_slot DESC')
date_end = last_record.date_slot
if scale == 'semestre':
date_first = date_end - relativedelta(months=1)
date_end = date_utils.end_of(date_first, 'month')
date_start = date_end - relativedelta(months=5)
date_start = date_utils.start_of(date_start, 'month')
elif scale == 'month':
date_start = date_end - relativedelta(months=1)
date_start = date_utils.start_of(date_start, scale)
date_end = date_utils.end_of(date_start, scale)
elif scale == 'week':
date_start = date_end - relativedelta(days=6)
date_start = date_utils.start_of(date_start, 'day')
elif scale == 'day':
date_start = date_utils.start_of(date_end, 'day')
else:
date_first = date_end - relativedelta(months=1)
date_end = date_utils.end_of(date_first, 'month')
date_start = date_utils.start_of(date_end, scale)
return date_start, date_end
def get_first_day(self):
"""
Fonction retournant la première date où des données ont été enregistrées.
:return: une date
"""
# Get last date slot recorded
first_record = self.env['acc.enedis.cdc'].search([
('acc_operation_id', 'in', self.ids),
], limit=1, order='date_slot ASC')
date_min = first_record.date_slot
return date_min
def get_step_from_date(self, date_start, date_end, scale=None):
"""
Fonction retournant le pas des courbes en fonction de 2 dates.
:return: step: hour/day/month/year
"""
# Calculate delta between 2 dates
delta = (date_end - date_start).days
if delta < 1:
step_display_courbe = 'hour'
step = 'hour'
if not scale:
scale = 'day'
elif delta < 29:
step_display_courbe = 'day'
step = 'hour'
if not scale:
scale = 'week'
elif delta <= 365:
step = 'month'
step_display_courbe = 'month'
if not scale:
scale = 'month'
else:
step = 'month'
step_display_courbe = 'month'
if not scale:
scale = 'year'
return scale, step, step_display_courbe
def get_cdc_by_query_cons(self, slot_type, date_start, date_end, prm_ids=None):
"""
Fonction permettant de récupérer les données pour la
construction des chart pour une ou des opérations données pour les consommateurs
:param slot_type: type de slot pour la query ('month' ou 'hour' ou 'year')
date_start: date début
date_end: date de fin
:return: un dictionnaire de données
(labels et data pour les charts à afficher)
"""
label = []
data_autocons = []
data_allocons = []
data_cons = []
data_prod = []
data_surplus = []
query = """
SELECT
date_trunc(%s, A.date_slot) AS date_slot,
(SUM( (CASE WHEN comp_data_type = 'autocons' THEN A.power ELSE 0 END) )/2) / 1000 as autocons,
(SUM( (CASE WHEN comp_data_type = 'prod' THEN A.power ELSE 0 END) )/2) / 1000 as prod,
((SUM( (CASE WHEN comp_data_type = 'cons' THEN A.power ELSE 0 END)) -
SUM(CASE WHEN comp_data_type = 'autocons' THEN A.power ELSE 0 END) ) / 2) / 1000 as allocons
FROM acc_enedis_cdc A
JOIN acc_operation E ON E.id = A.acc_operation_id
WHERE A.acc_operation_id IS NOT NULL
AND A.acc_operation_id IN %s
AND ( A.acc_counter_id IN %s OR A.comp_data_type = 'prod' )
AND A.date_slot >= %s
AND A.date_slot < %s
GROUP BY date_trunc(%s, A.date_slot)
ORDER BY date_slot ASC;
"""
query_params = (slot_type, tuple(self.ids), tuple(prm_ids.ids), date_start, date_end, slot_type)
self.env.cr.execute(query, query_params)
raw_data = self.env.cr.fetchall()
for row in raw_data:
if slot_type == 'month' or slot_type == 'year':
data_autocons.append(int(row[1]))
data_prod.append(int(row[2]))
data_allocons.append(int(row[3]))
label.append(row[0])
else:
data_autocons.append({'x': row[0], 'y': round(row[1], 2)})
data_prod.append({'x': row[0], 'y': round(row[2], 2)})
data_allocons.append({'x': row[0], 'y': round(row[3], 2)})
label.append(row[0])
cdc_jour = {
'autocons': data_autocons,
'prod': data_prod,
'allocons': data_allocons,
'label': label,
'cons': data_cons,
'surplus': data_surplus,
}
return cdc_jour
def get_cdc_by_query_histo_cons(self, slot_type, date_start, date_end, prm_ids=None):
"""
Fonction permettant de récupérer les données pour la
construction des chart pour une ou des opérations données pour les consommateurs
:param slot_type: type de slot pour la query ('month' ou 'hour' ou 'year')
date_start: date début
date_end: date de fin
:return: un dictionnaire de données
(labels et data pour les charts à afficher)
"""
label_histo = []
data_autocons_histo = []
data_allocons_histo = []
query = """
SELECT
date_trunc(%s, A.date_slot) AS date_slot,
(SUM( (CASE WHEN comp_data_type = 'autocons' THEN A.power ELSE 0 END) )/2) / 1000 as autocons,
((SUM( (CASE WHEN comp_data_type = 'cons' THEN A.power ELSE 0 END)) -
SUM(CASE WHEN comp_data_type = 'autocons' THEN A.power ELSE 0 END) ) / 2) / 1000 as allocons
FROM acc_enedis_cdc A
JOIN acc_operation E ON E.id = A.acc_operation_id
WHERE A.acc_operation_id IS NOT NULL
AND A.acc_operation_id IN %s
AND A.acc_counter_id IN %s
AND A.date_slot >= %s
AND A.date_slot < %s
GROUP BY date_trunc(%s, A.date_slot)
ORDER BY date_slot ASC;
"""
query_params = (slot_type, tuple(self.ids), tuple(prm_ids.ids), date_start, date_end, slot_type)
self.env.cr.execute(query, query_params)
raw_data = self.env.cr.fetchall()
for row in raw_data:
data_autocons_histo.append(round(row[1], 2))
data_allocons_histo.append(round(row[2], 2))
label_histo.append(row[0])
cdc_jour = {
'autocons_histo': data_autocons_histo,
'allocons_histo': data_allocons_histo,
'label_histo': label_histo,
}
return cdc_jour
def get_cdc_by_query_prod(self, slot_type, date_start, date_end, prm_ids=None):
"""
Fonction permettant de récupérer les données pour la
construction des chart pour une ou des opérations données pour les consommateurs
:param slot_type: type de slot pour la query ('month' ou 'hour' ou 'year')
date_start: date début
date_end: date de fin
:return: un dictionnaire de données
(labels et data pour les charts à afficher)
"""
label = []
data_autocons = []
data_surplus = []
label_histo = []
data_autocons_histo = []
data_surplus_histo = []
query = """
SELECT
date_trunc(%s, A.date_slot) AS date_slot,
((SUM((CASE WHEN comp_data_type = 'prod' THEN A.power ELSE 0 END)) - SUM(CASE
WHEN comp_data_type = 'surplus' THEN A.power ELSE 0 END)) / 2) / 1000 as autocons,
(SUM( (CASE WHEN comp_data_type = 'surplus' THEN A.power ELSE 0 END) )/2) / 1000 as surplus
FROM acc_enedis_cdc A
JOIN acc_operation E ON E.id = A.acc_operation_id
WHERE A.acc_operation_id IS NOT NULL
AND A.acc_counter_id IN %s
AND A.acc_operation_id IN %s
AND A.date_slot >= %s
AND A.date_slot < %s
GROUP BY date_trunc(%s, A.date_slot)
ORDER BY date_slot ASC;
"""
query_params = (slot_type, tuple(prm_ids.ids), tuple(self.ids), date_start, date_end, slot_type)
self.env.cr.execute(query, query_params)
raw_data = self.env.cr.fetchall()
for row in raw_data:
if slot_type == 'month' or slot_type == 'year':
data_autocons.append(int(row[1]))
data_surplus.append(int(row[2]))
label.append(row[0])
elif slot_type == 'day':
data_autocons_histo.append(round(row[1], 2))
data_surplus_histo.append(round(row[2], 2))
label_histo.append(row[0])
else:
data_autocons.append({'x': row[0], 'y': round(row[1], 2)})
data_surplus.append({'x': row[0], 'y': round(row[2], 2)})
label.append(row[0])
cdc_jour = {
'autocons_prod': data_autocons,
'label': label,
'surplus': data_surplus,
'autocons_histo': data_autocons_histo,
'label_histo': label_histo,
'surplus_histo': data_surplus_histo,
}
return cdc_jour
def get_cdc_by_query_histo_prod(self, slot_type, date_start, date_end, prm_ids=None):
"""
Fonction permettant de récupérer les données pour la
construction des chart pour une ou des opérations données pour les consommateurs
:param slot_type: type de slot pour la query ('month' ou 'hour' ou 'year')
date_start: date début
date_end: date de fin
:return: un dictionnaire de données
(labels et data pour les charts à afficher)
"""
label_histo = []
data_autocons_prod_histo = []
data_surplus_histo = []
query = """
SELECT
date_trunc(%s, A.date_slot) AS date_slot,
((SUM((CASE WHEN comp_data_type = 'prod' THEN A.power ELSE 0 END)) - SUM(CASE
WHEN comp_data_type = 'surplus' THEN A.power ELSE 0 END)) / 2) / 1000 as autocons,
(SUM( (CASE WHEN comp_data_type = 'surplus' THEN A.power ELSE 0 END) )/2) / 1000 as surplus
FROM acc_enedis_cdc A
JOIN acc_operation E ON E.id = A.acc_operation_id
WHERE A.acc_operation_id IS NOT NULL
AND A.acc_counter_id IN %s
AND A.acc_operation_id IN %s
AND A.date_slot >= %s
AND A.date_slot < %s
GROUP BY date_trunc(%s, A.date_slot)
ORDER BY date_slot ASC;
"""
query_params = (slot_type, tuple(prm_ids.ids), tuple(self.ids), date_start, date_end, slot_type)
self.env.cr.execute(query, query_params)
raw_data = self.env.cr.fetchall()
for row in raw_data:
data_autocons_prod_histo.append(round(row[1], 2))
data_surplus_histo.append(round(row[2], 2))
label_histo.append(row[0])
cdc_jour = {
'autocons_prod_histo': data_autocons_prod_histo,
'label_histo': label_histo,
'surplus_histo': data_surplus_histo,
}
return cdc_jour
def get_cdc_by_query(self, slot_type, date_start, date_end, prm_ids=None):
"""
Fonction permettant de récupérer les données pour la
construction des chart pour une ou des opérations données
:param slot_type: type de slot pour la query ('month' ou 'hour' ou 'year')
date_start: date début
date_end: date de fin
:return: un dictionnaire de données
(labels et data pour les charts à afficher)
"""
label = []
data_autocons = []
data_autocons_prod = []
data_allocons = []
data_cons = []
data_prod = []
data_surplus = []
# if prm_ids:
query = """
SELECT
date_trunc(%s, A.date_slot) AS date_slot,
(SUM((CASE WHEN comp_data_type = 'cons' THEN A.power ELSE 0 END)) / 2) / 1000 as cons,
(SUM((CASE WHEN comp_data_type = 'autocons' THEN A.power ELSE 0 END)) / 2) / 1000 as autocons,
(SUM((CASE WHEN comp_data_type = 'prod' THEN A.power ELSE 0 END)) / 2) / 1000 as prod_s,
(SUM( (CASE WHEN comp_data_type = 'surplus' THEN A.power ELSE 0 END) )/2) / 1000 as surplus,
((SUM( (CASE WHEN comp_data_type = 'cons' THEN A.power ELSE 0 END)) -
SUM(CASE WHEN comp_data_type = 'autocons' THEN A.power ELSE 0 END) ) / 2) / 1000 as allocons,
((SUM((CASE WHEN comp_data_type = 'prod' THEN A.power ELSE 0 END)) - SUM(CASE
WHEN comp_data_type = 'surplus' THEN A.power ELSE 0 END)) / 2) / 1000 as autocons_prod
FROM acc_enedis_cdc A
JOIN acc_operation E ON E.id = A.acc_operation_id
WHERE A.acc_operation_id IS NOT NULL
AND A.acc_operation_id IN %s
AND A.date_slot >= %s
AND A.date_slot < %s
GROUP BY date_trunc(%s, A.date_slot)
ORDER BY date_slot ASC;
"""
query_params = (slot_type, tuple(self.ids), date_start, date_end, slot_type)
self.env.cr.execute(query, query_params)
raw_data = self.env.cr.fetchall()
for row in raw_data:
if slot_type == 'month' or slot_type == 'year':
data_cons.append(int(row[1]))
data_autocons.append(int(row[2]))
data_prod.append(int(row[3]))
data_surplus.append(int(row[4]))
data_allocons.append(int(row[5]))
data_autocons_prod.append(int(row[6]))
label.append(row[0])
else:
data_cons.append({'x': row[0], 'y': round(row[1], 2)})
data_autocons.append({'x': row[0], 'y': round(row[2], 2)})
data_prod.append({'x': row[0], 'y': round(row[3], 2)})
data_surplus.append({'x': row[0], 'y': round(row[4], 2)})
data_allocons.append({'x': row[0], 'y': round(row[5], 2)})
data_autocons_prod.append({'x': row[0], 'y': round(row[6], 2)})
label.append(row[0])
cdc_jour = {
'autocons': data_autocons,
'autocons_prod': data_autocons_prod,
'cons': data_cons,
'prod': data_prod,
'surplus': data_surplus,
'allocons': data_allocons,
'label': label,
}
return cdc_jour
def get_cdc_by_query_histo(self, slot_type, date_start, date_end, prm_ids=None):
"""
Fonction permettant de récupérer les données pour la
construction des chart pour une ou des opérations données
:param slot_type: type de slot pour la query ('month' ou 'hour' ou 'year')
date_start: date début
date_end: date de fin
:return: un dictionnaire de données
(labels et data pour les charts à afficher)
"""
label_histo = []
data_autocons_histo = []
data_autocons_prod_histo = []
data_allocons_histo = []
data_surplus_histo = []
query = """
SELECT
date_trunc(%s, A.date_slot) AS date_slot,
(SUM((CASE WHEN comp_data_type = 'autocons' THEN A.power ELSE 0 END)) / 2) / 1000 as autocons,
(SUM( (CASE WHEN comp_data_type = 'surplus' THEN A.power ELSE 0 END) )/2) / 1000 as surplus,
((SUM( (CASE WHEN comp_data_type = 'cons' THEN A.power ELSE 0 END)) -
SUM(CASE WHEN comp_data_type = 'autocons' THEN A.power ELSE 0 END) ) / 2) / 1000 as allocons,
((SUM((CASE WHEN comp_data_type = 'prod' THEN A.power ELSE 0 END)) - SUM(CASE
WHEN comp_data_type = 'surplus' THEN A.power ELSE 0 END)) / 2) / 1000 as autocons_prod
FROM acc_enedis_cdc A
JOIN acc_operation E ON E.id = A.acc_operation_id
WHERE A.acc_operation_id IS NOT NULL
AND A.acc_operation_id IN %s
AND A.date_slot >= %s
AND A.date_slot < %s
GROUP BY date_trunc(%s, A.date_slot)
ORDER BY date_slot ASC;
"""
query_params = (slot_type, tuple(self.ids), date_start, date_end, slot_type)
self.env.cr.execute(query, query_params)
raw_data = self.env.cr.fetchall()
for row in raw_data:
data_autocons_histo.append(round(row[1], 2))
data_surplus_histo.append(round(row[2], 2))
data_allocons_histo.append(round(row[3], 2))
data_autocons_prod_histo.append(round(row[4], 2))
label_histo.append(row[0])
cdc_jour = {
'autocons_histo': data_autocons_histo,
'surplus_histo': data_surplus_histo,
'allocons_histo': data_allocons_histo,
'autocons_prod_histo': data_autocons_prod_histo,
'label_histo': label_histo,
}
return cdc_jour
def chart_data_line_cons(self, chart_data, scale):
"""
Fonction retournant le dictionnaire permettant la construiction
des graphes de la partie consommation par mois
:param chart_data: données à afficher dans les chart (labels et data)
:return: un dictionnaire de chart
"""
if scale == 'day':
offsetGridLines = False
else:
offsetGridLines = True
result = {}
result['line_chart_conso_line'] = {
'type': 'line',
'data': {
'labels': chart_data['label'],
'datasets': [
{
'label': 'Allo Conso',
'data': chart_data['allocons'],
'backgroundColor': 'rgba(57, 120, 187, 0.2)',
'borderColor': 'rgba(57, 120, 187, 1)',
'borderWidth': 1,
'hoverRadius': 1,
'radius': 0,
},
{
'label': 'Production solaire',
'data': chart_data['prod'],
'backgroundColor': 'rgba(244, 165, 25, 0)',
'borderColor': 'rgba(244, 165, 25, 1)',
'borderWidth': 2,
'hoverRadius': 1,
'radius': 0,
},
{
'label': 'Autoconso',
'data': chart_data['autocons'],
'backgroundColor': 'rgba(91, 154, 81, 0.4)',
'borderColor': 'rgba(91, 154, 81, 1)',
'borderWidth': 2,
'hoverRadius': 1,
'radius': 0,
},
],
},
'options': {
'scales': {
'xAxes': [{
'type': 'time',
'time': {
'unit': scale,
},
'gridLines': {
'offsetGridLines': offsetGridLines
},
}],
'yAxes': [{
'scaleLabel': {
'display': True,
'labelString': 'kW',
}
}]
},
'tooltips': {
'backgroundColor': '#f5f5f5',
'titleFontColor': '#333',
'bodyFontColor': '#666',
'bodySpacing': 4,
'xPadding': 12,
'mode': 'x',
'intersect': False,
},
'elements': {
'point': {
'radius': 0
}
}
},
}
result['line_chart_prod_prm'] = {
'type': 'line',
'data': {
'labels': chart_data['label'],
'datasets': [
{
'label': 'Production solaire',
'data': chart_data['prod'],
'backgroundColor': 'rgba(244, 165, 25, 0)',
'borderColor': 'rgba(244, 165, 25, 1)',
},
],
},
}
return result
def chart_data_histo_cons(self, chart_data, scale, scale_spe):
"""
Fonction retournant le dictionnaire permettant la construiction
des graphes de la partie consommation par mois
:param chart_data: données à afficher dans les chart (labels et data)
:return: un dictionnaire de chart
"""
result = {}
if scale_spe == 'week':
data_autocons = chart_data['autocons_histo']
data_allocons = chart_data['allocons_histo']
data_label = chart_data['label_histo']
else:
data_autocons = chart_data['autocons']
data_allocons = chart_data['allocons']
data_label = chart_data['label']
result['histo_chart_conso'] = {
'type': 'bar',
'data': {
'labels': data_label,
'datasets': [
{
'label': 'AutoConso',
'data': data_autocons,
'backgroundColor': 'rgba(91, 154, 81, 0.4)',
'hoverBackgroundColor': 'rgba(91, 154, 81, 0.7)',
},
{
'label': 'AlloConso',
'data': data_allocons,
'backgroundColor': 'rgba(57, 120, 187, 0.4)',
'hoverBackgroundColor': 'rgba(57, 120, 187, 0.7)',
}]
},
'options': {
'plugins': {
'datalabels': {
'color': 'white',
'font': {
'weight': 'bold'
},
}
},
'interaction': {
'intersect': False,
},
'scales': {
'xAxes': [{
'type': 'time',
'time': {
'unit': scale
},
'stacked': True,
'offset': True,
'gridLines': {
'offsetGridLines': True
},
}],
'yAxes': [{
'stacked': True,
'ticks': {
'beginAtZero': True,
},
'scaleLabel': {
'display': True,
'labelString': 'kWh',
}
}]
},
'tooltips': {
'backgroundColor': '#f5f5f5',
'titleFontColor': '#333',
'bodyFontColor': '#666',
'bodySpacing': 4,
'xPadding': 12,
'mode': 'nearest',
'intersect': 0,
}
}
}
return result
def chart_data_donuts_cons(self, chart_data, scale):
"""
Fonction retournant le dictionnaire permettant la construiction
des graphes de la partie consommation par mois
:param chart_data: données à afficher dans les chart (labels et data)
:return: un dictionnaire de chart
"""
result = {}
if scale == 'hour':
sum_res1 = sum(int(item['y']) for item in chart_data['autocons'])
sum_res2 = sum(int(item['y']) for item in chart_data['allocons'])
else:
sum_res1 = sum(chart_data['autocons'])
sum_res2 = sum(chart_data['allocons'])
if sum_res1 == 0:
label = ['Alloconso']
res = [sum_res2]
elif sum_res2 == 0:
label = ['Autoconso']
res = [sum_res1]
else:
label = ['Autoconso', 'Alloconso']
res = [sum_res1, sum_res2]
result['donuts_chart_conso'] = {
'type': 'doughnut',
'data': {
'labels': label,
'datasets': [{
'label': 'Inférieur à 3',
'data': res,
'backgroundColor': [
'rgba(91, 154, 81, 0.4)',
'rgba(57, 120, 187, 0.4)',
],
'hoverBackgroundColor': [
'rgba(91, 154, 81, 0.7)',
'rgba(57, 120, 187, 0.7)',
],
'borderWidth': 1
}],
},
'options': {
'cutoutPercentage': 60,
'animation': {
'animateScale': True,
},
'plugins': {
'datalabels': {
'color': 'white',
'font': {
'weight': 'bold'
},
'padding': 6,
}
},
'tooltips': {
'backgroundColor': '#f5f5f5',
'titleFontColor': '#333',
'bodyFontColor': '#666',
'bodySpacing': 4,
'xPadding': 12,
'mode': 'nearest',
'intersect': 0,
}
}
}
return result
def chart_data_line_prod(self, chart_data, scale):
"""
Fonction retournant le dictionnaire permettant la construiction
des graphes de la partie production
:param chart_data: données à afficher dans les chart (labels et data)
:return: un dictionnaire de chart
"""
if scale == 'day':
offsetGridLines = False
else:
offsetGridLines = True
result = {}
result['line_chart_prod_line'] = {
'type': 'line',
'data': {
'labels': chart_data['label'],
'datasets': [
{
'label': 'AutoProd',
'data': chart_data['autocons_prod'],
'backgroundColor': 'rgba(91, 154, 81, 0.4)',
'borderColor': 'rgba(91, 154, 81, 1)',
'borderWidth': 2,
'hoverRadius': 1,
'radius': 0,
'fill': 'origin'
},
{
'label': 'Surplus',
'data': chart_data['surplus'],
'backgroundColor': 'rgba(225, 80, 96, 0.4)',
'borderColor': 'rgba(225, 80, 96, 1)',
'borderWidth': 2,
'hoverRadius': 1,
'radius': 0,
'fill': '-1'
},
],
},
'options': {
'scales': {
'xAxes': [{
'type': 'time',
'time': {
'unit': scale,
},
'ticks': {
# 'min': result.date_start,
},
'gridLines': {
'offsetGridLines': offsetGridLines
}
}],
'yAxes': [{
'stacked': True,
'scaleLabel': {
'display': True,
'labelString': 'kW',
}
}]
},
'tooltips': {
'backgroundColor': '#f5f5f5',
'titleFontColor': '#333',
'bodyFontColor': '#666',
'bodySpacing': 4,
'xPadding': 12,
'mode': 'x',
'intersect': False,
},
'elements': {
'point': {
'radius': 0
}
},
},
}
return result
def chart_data_donuts_prod(self, chart_data, scale):
"""
Fonction retournant le dictionnaire permettant la construction
des graphes de la partie production
:param chart_data: données à afficher dans les chart (labels et data)
:return: un dictionnaire de chart
"""
result = {}
if scale == 'hour':
sum_res1 = sum(int(item['y']) for item in chart_data['autocons_prod'])
sum_res2 = sum(int(item['y']) for item in chart_data['surplus'])
else:
sum_res1 = sum(chart_data['autocons_prod'])
sum_res2 = sum(chart_data['surplus'])
if sum_res1 == 0:
label = ['Surplus']
res = [sum_res2]
elif sum_res2 == 0:
label = ['AutoProd']
res = [sum_res1]
else:
label = ['AutoProd', 'Surplus']
res = [sum_res1, sum_res2]
result['donuts_chart_prod'] = {
'type': 'doughnut',
'data': {
'labels': label,
'datasets': [{
'label': 'Inférieur à 3',
'data': res,
'backgroundColor': [
'rgba(91, 154, 81, 0.4)',
'rgba(225, 80, 96, 0.4)',
],
'hoverBackgroundColor': [
'rgba(91, 154, 81, 0.7)',
'rgba(225, 80, 96, 0.7)',
],
'borderWidth': 1
}],
},
'options': {
'plugins': {
'datalabels': {
'color': 'white',
'font': {
'weight': 'bold'
},
'padding': 6,
}
},
'cutoutPercentage': 60,
'animation': {
'animateScale': True,
},
'tooltips': {
'backgroundColor': '#f5f5f5',
'titleFontColor': '#333',
'bodyFontColor': '#666',
'bodySpacing': 4,
'xPadding': 12,
'mode': 'nearest',
'intersect': 0,
}
}
}
return result
def chart_data_histo_prod(self, chart_data, scale, scale_spe):
"""
Fonction retournant le dictionnaire permettant la construiction
des graphes de la partie production
:param chart_data: données à afficher dans les chart (labels et data)
:return: un dictionnaire de chart
"""
result = {}
if scale_spe == 'week':
data_autocons = chart_data['autocons_prod_histo']
data_surplus = chart_data['surplus_histo']
data_label = chart_data['label_histo']
else:
data_autocons = chart_data['autocons_prod']
data_surplus = chart_data['surplus']
data_label = chart_data['label']
result['histo_chart_prod'] = {
'type': 'bar',
'data': {
'labels': data_label,
'datasets': [
{
'label': 'AutoProd',
'data': data_autocons,
'backgroundColor': 'rgba(91, 154, 81, 0.4)',
'hoverBackgroundColor': 'rgba(91, 154, 81, 0.7)',
'borderColor': 'rgba(91, 154, 81, 1)',
},
{
'label': 'Surplus',
'data': data_surplus,
'backgroundColor': 'rgba(225, 80, 96, 0.4)',
'hoverBackgroundColor': 'rgba(225, 80, 96, 0.7)',
'borderColor': 'rgba(225, 80, 96, 1)',
}]
},
'options': {
'plugins': {
'datalabels': {
'color': 'white',
'font': {
'weight': 'bold'
},
}
},
'interaction': {
'intersect': False,
},
'scales': {
'xAxes': [{
'type': 'time',
'time': {
'unit': scale
},
'stacked': True,
'offset': True,
'gridLines': {
'offsetGridLines': True
}
}],
'yAxes': [{
'stacked': True,
'ticks': {
'beginAtZero': True,
},
'type': 'linear',
'scaleLabel': {
'display': True,
'labelString': 'kWh',
}
}]
},
'tooltips': {
'backgroundColor': '#f5f5f5',
'titleFontColor': '#333',
'bodyFontColor': '#666',
'bodySpacing': 4,
'xPadding': 12,
'mode': 'nearest',
'intersect': 0,
},
}
}
return result
def get_cdc(self, scale, step_courbe, date_start, date_end, prm_ids=None):
"""
Fonction permettant de récupérer les données pour la
construction des chart pour une ou des opérations données
:param step_courbe: Pas à prendre en courbe pour le calcul des courbes
(hour/day/week/month/year)
date_start: date début
date_end: date de fin
prm_ids: PRMs
:return: un dictionnaire de données
(labels et data pour les charts à afficher)
"""
chart_data = self.get_cdc_by_query(step_courbe, date_start, date_end, None)
if scale == 'week':
chart_data_histo = self.get_cdc_by_query_histo('day', date_start, date_end, None)
chart_data.update(chart_data_histo)
return chart_data
@api.model
def graph_view(self, domain, scale, first_day, last_day, acc_counter_id=None):
"""
Fonction appelée lors du chargement de la vue Qweb
:param domain: représente le champ recherche de la vue
scale: type d'affichage des graphes
(day/week/month/semestre/year)
défini par le clic bouton
:return: dictionnaire pour la construction des graphes
"""
result_graph = {}
# Get the operations depending to the domain
operation_ids = self.env['acc.operation'].search(domain)
if operation_ids:
# Get date start and date end depending on type of scale
if first_day and last_day:
date_start = fields.Datetime.to_datetime(first_day)
date_end = fields.Datetime.to_datetime(last_day)
date_end = date_utils.end_of(date_end, 'day')
elif first_day:
date_start, date_end = operation_ids.get_last_day('day')
date_end = date_utils.end_of(date_end, 'day')
else:
date_start, date_end = operation_ids.get_last_day('month')
date_end = date_utils.end_of(date_end, 'day')
counter_ids = None
if acc_counter_id:
counter_ids = self.env['acc.counter'].search([('name', '=', acc_counter_id)]).ids
scale, step_courbe, step_display_courbe = operation_ids.get_step_from_date(
date_start=date_start, date_end=date_end, scale=scale)
# Get the data to display in chart
chart_data = operation_ids.get_cdc(scale=scale, step_courbe=step_courbe, date_start=date_start, date_end=date_end,
prm_ids=counter_ids)
# Build the chart with data and options
result_graph_line = self.chart_data_line_prod(chart_data, step_display_courbe)
result_graph.update(result_graph_line)
result_graph_histo = self.chart_data_histo_prod(chart_data, step_display_courbe, scale)
result_graph.update(result_graph_histo)
result_graph_donuts = self.chart_data_donuts_prod(chart_data, step_courbe)
result_graph.update(result_graph_donuts)
result_graph_line = self.chart_data_line_cons(chart_data, step_display_courbe)
result_graph.update(result_graph_line)
result_graph_histo = self.chart_data_histo_cons(chart_data, step_display_courbe, scale)
result_graph.update(result_graph_histo)
result_graph_donuts = self.chart_data_donuts_cons(chart_data, step_courbe)
result_graph.update(result_graph_donuts)
# result_graph.update(result_graph2)
result_graph.update({'scale': scale})
date_end = date_end.strftime("%d/%m/%Y")
date_min = operation_ids.get_first_day()
date_min = date_min.strftime("%d/%m/%Y")
result_graph.update({
'date_end': date_end,
'date_min': date_min,
'date_start': date_start,
})
return result_graph
# ------------------------------------------------------
# Functions to manage route
# ------------------------------------------------------
def build_graph_data_options(self, chart_data, step_display_courbe=None, scale=None, step_courbe=None):
result_graph = {}
result_graph_line = self.chart_data_line_prod(chart_data, step_display_courbe)
result_graph.update(result_graph_line)
result_graph_histo = self.chart_data_histo_prod(chart_data, step_display_courbe, scale)
result_graph.update(result_graph_histo)
result_graph_donuts = self.chart_data_donuts_prod(chart_data, step_courbe)
result_graph.update(result_graph_donuts)
result_graph_line = self.chart_data_line_cons(chart_data, step_display_courbe)
result_graph.update(result_graph_line)
result_graph_histo = self.chart_data_histo_cons(chart_data, step_display_courbe, scale)
result_graph.update(result_graph_histo)
result_graph_donuts = self.chart_data_donuts_cons(chart_data, step_courbe)
result_graph.update(result_graph_donuts)
return result_graph
def build_graph_data_options_prod(self, chart_data, step_display_courbe=None, scale=None, step_courbe=None):
result_graph = {}
result_graph_line = self.chart_data_line_prod(chart_data, step_display_courbe)
result_graph.update(result_graph_line)
result_graph_histo = self.chart_data_histo_prod(chart_data, step_display_courbe, scale)
result_graph.update(result_graph_histo)
result_graph_donuts = self.chart_data_donuts_prod(chart_data, step_courbe)
result_graph.update(result_graph_donuts)
return result_graph
def build_graph_data_options_cons(self, chart_data, step_display_courbe=None, scale=None, step_courbe=None):
result_graph = {}
result_graph_line = self.chart_data_line_cons(chart_data, step_display_courbe)
result_graph.update(result_graph_line)
result_graph_histo = self.chart_data_histo_cons(chart_data, step_display_courbe, scale)
result_graph.update(result_graph_histo)
result_graph_donuts = self.chart_data_donuts_cons(chart_data, step_courbe)
result_graph.update(result_graph_donuts)
return result_graph
# ------------------------------------------------------
# Functions to manage route
# ------------------------------------------------------
def graph_view_global(self, scale=None, date_start=None, date_end=None):
"""
Fonction appelée pour l'affichage des courbes consommation
sur le portail
:param scale: type d'affichage des graphes
(day/week/month/semestre/year)
défini par le clic bouton
:return: dictionnaire pour la construction des graphes
"""
result_graph = {}
if not date_start and not date_end:
date_start, date_end = self.get_last_day(scale)
else:
date_end = date_utils.end_of(date_end, 'day')
scale, step_courbe, step_display_courbe = self.get_step_from_date(
date_start=date_start, date_end=date_end, scale=scale)
# Get the data to display in chart
chart_data = self.get_cdc(
scale=scale, step_courbe=step_courbe, date_start=date_start,
date_end=date_end, prm_ids=None)
# Build the chart with data and options
result_graph = self.build_graph_data_options(
chart_data, step_display_courbe=step_display_courbe, scale=scale, step_courbe=step_courbe)
date_deb, date_max = self.get_last_day('day')
date_max = date_max.strftime("%d/%m/%Y")
date_min = self.get_first_day()
date_min = date_min.strftime("%d/%m/%Y")
result_graph.update({
'date_start': date_start,
'date_end': date_end,
'date_min': date_min,
'date_max': date_max,
'scale': scale
})
return result_graph
# ------------------------------------------------------
# Functions to manage route
# ------------------------------------------------------
def graph_view_type(self, type=None, scale=None, date_start=None, date_end=None, prm_id=None, partner_id=None):
"""
Fonction appelée pour l'affichage des courbes consommation
sur le portail
:param scale: type d'affichage des graphes
(day/week/month/semestre/year)
défini par le clic bouton
:return: dictionnaire pour la construction des graphes
"""
result_graph = {}
if not date_start and not date_end:
date_start, date_end = self.get_last_day(scale)
else:
date_end = date_utils.end_of(date_end, 'day')
# Get the step to display curve in chart
scale, step_courbe, step_display_courbe = self.get_step_from_date(
date_start=date_start, date_end=date_end, scale=scale)
# Get PRM ids
if prm_id:
acc_counter_ids = self.env['acc.counter'].browse(prm_id)
elif partner_id:
acc_counter_ids = self.env['acc.counter'].search([('partner_id', '=', partner_id)])
else:
if type == 'cons':
acc_counter_ids = self.acc_delivery_ids
else:
acc_counter_ids = self.acc_injection_ids
if type == 'cons':
chart_data = self.get_cdc_by_query_cons(step_courbe, date_start, date_end, acc_counter_ids)
if scale == 'week':
chart_data_histo = self.get_cdc_by_query_histo_cons('day', date_start, date_end, acc_counter_ids)
chart_data.update(chart_data_histo)
# Build the chart with data and options
result_graph = self.build_graph_data_options_cons(chart_data, step_display_courbe=step_display_courbe,
scale=scale, step_courbe=step_courbe)
else:
chart_data = self.get_cdc_by_query_prod(step_courbe, date_start, date_end, acc_counter_ids)
if scale == 'week':
chart_data_histo = self.get_cdc_by_query_histo_prod('day', date_start, date_end, acc_counter_ids)
chart_data.update(chart_data_histo)
# Build the chart with data and options
result_graph = self.build_graph_data_options_prod(chart_data, step_display_courbe=step_display_courbe,
scale=scale, step_courbe=step_courbe)
date_deb, date_max = self.get_last_day('day')
date_max = date_max.strftime("%d/%m/%Y")
date_min = self.get_first_day()
date_min = date_min.strftime("%d/%m/%Y")
result_graph.update({
'date_start': date_start,
'date_end': date_end,
'date_min': date_min,
'date_max': date_max,
'scale': scale
})
return result_graph