-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
229 lines (178 loc) · 6.75 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
#!/usr/bin/python3
# -*- encoding: utf-8 -*-
# @author Raúl Caro Pastorino
# @email dev@fryntiz.es
# @web https://fryntiz.es
# @gitlab https://gitlab.com/fryntiz
# @github https://github.com/fryntiz
# @twitter https://twitter.com/fryntiz
# @telegram https://t.me/fryntiz
# Create Date: 2022
# Project Name:
# Description:
#
# Dependencies:
#
# Revision 0.01 - File Created
# Additional Comments:
# @copyright Copyright © 2022 Raúl Caro Pastorino
# @license https://wwww.gnu.org/licenses/gpl.txt
# Copyright (C) 2022 Raúl Caro Pastorino
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
# Guía de estilos aplicada: PEP8
#######################################
# # Descripción # #
#######################################
## Obtiene la información del controlador solar, la almacena en base de datos
## e intenta posteriormente subir la información a la nube.
##
## Almacenarla en base de datos implica poder trabajar sin depender de internet
## por si es el caso (como en mi situación) que por la noche quedan los
## routers y modem desconectados. De esta forma aunque no sea en tiempo real
## puedo observar esos datos y almacenarlos en la nube.
##
#######################################
# # Importar Librerías # #
#######################################
from Models.SolarControllers.RenogyRoverLi import RenogyRoverLi
from Models.ApiConnection import ApiConnection
from Models.DbConnection import DbConnection
from dotenv import load_dotenv
import os
import datetime
import time
# Cargo archivos de configuración desde .env sobreescribiendo variables locales.
load_dotenv(override=True)
#######################################
# # Variables # #
#######################################
sleep = time.sleep
# Debug
DEBUG = os.getenv("DEBUG") == "True"
# Puerto de la interfaz serial
PORT = os.getenv("PORT")
# Indica si procesa subidas a la api
UPLOAD_API = os.getenv("UPLOAD_API") == "True"
# Abro conexión con la base de datos instanciando el modelo que la representa.
dbconnection = DbConnection()
# Parámetros para acceder a la API.
apiconnection = ApiConnection()
# Controlador solar
device_id = int(os.getenv("DEVICE_ID")) or 0
solar_controller = RenogyRoverLi(device_id=device_id, port=PORT, debug=DEBUG)
# Controladores
#controllers = {}
#######################################
# # FUNCIONES # #
#######################################
def upload_data_to_api(apiconnection, dbconnection):
"""
Obtiene los datos para de la DB y los envía a la API
:param apiconnection:
:param dbconnection:
"""
# Parámetros/tuplas desde la base de datos.
params_from_db = dbconnection.table_get_data_last(
solar_controller.tablename, 20)
# Columnas del modelo.
columns = dbconnection.tables[solar_controller.tablename].columns.keys()
try:
response = apiconnection.upload(
solar_controller.tablename,
'/hardware/v1/solarcharge/store',
params_from_db,
columns,
method='POST'
)
# Limpio los datos de la tabla si se ha subido correctamente.
if response:
if DEBUG:
print('Eliminando de la DB las tuplas subidas a la API')
dbconnection.table_drop_last_elements(solar_controller.tablename, 20)
except():
if DEBUG:
print('Error al subir a la api')
def loop ():
# Contador de lecturas desde la última subida a la API
n_lecturas = 0
if DEBUG:
print('Creando tabla en la base de datos')
# Crea la tabla para el controlador solar.
dbconnection.table_set_new(solar_controller.tablename, solar_controller.tablemodel())
while True:
n_lecturas = n_lecturas + 1
if DEBUG:
print('Lecturas desde la última subida: ' + str(
n_lecturas))
# Guardo el momento que inicia lectura.
marca_inicio = datetime.datetime.now(tz=None)
# Leyendo controlador solar
datas = solar_controller.get_all_datas()
info = solar_controller.get_all_controller_info_datas()
historical_today = solar_controller.get_today_historical_info_datas()
historical = solar_controller.get_historical_info_datas()
params = {**datas, **info, **historical_today, **historical}
if DEBUG:
print('Datos obtenidos: ' + str(datas))
print('Información del controlador: ' + str(info))
print('Histórico del día: ' + str(historical_today))
print('Histórico total: ' + str(historical))
print("\n")
print('Parámetros a guardar: ' + str(params))
# TODO → Quitar de parámetros los que no estén en tablemodel()
data_to_save = {}
for key in solar_controller.tablemodel():
if key in params:
data_to_save[key] = params[key]
# Almacena en la base de datos.
dbconnection.table_save_data(
tablename=solar_controller.tablename,
params=data_to_save
)
if n_lecturas == 1:
n_lecturas = 0
try:
if UPLOAD_API:
upload_data_to_api(apiconnection, dbconnection)
except():
if DEBUG:
print('Error al subir datos a la api')
# Muestro tiempo en realizarse la lectura de datos.
if DEBUG:
print('Inicio: ', str(marca_inicio))
marca_fin = datetime.datetime.now(tz=None)
if DEBUG:
print('Fin: ', str(marca_fin))
tiempo_ejecucion = marca_fin - marca_inicio
if DEBUG:
print('Tiempo de ejecución: ', str(tiempo_ejecucion))
# Pausa entre cada lectura
sleep(60)
# Acciones tras terminar con error
dbconnection.close_connection()
def main ():
print('Iniciando Aplicación')
# Pauso 6 segundos para dar margen a la interfaz si estuviera preparándose.
sleep(2)
try:
loop()
except Exception as e:
print('Ha ocurrido un error en la aplicación:', e.__class__.__name__)
print(e)
sleep(300)
main()
exit(0)
if __name__ == "__main__":
main()