Skip to content

Commit cae5de9

Browse files
committed
mate3_pg: Adding reconnection and logging
1 parent 5446977 commit cae5de9

File tree

1 file changed

+60
-13
lines changed

1 file changed

+60
-13
lines changed

Diff for: mate3/mate3_pg.py

+60-13
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
import argparse
22
from sys import argv
33
from typing import NamedTuple, List, Type, Iterable
4+
import logging
45

56
from pymodbus.constants import Defaults
7+
from pymodbus.exceptions import ModbusIOException, ConnectionException
68

79
from mate3 import mate3_connection
810
import time
911

1012
from mate3.api import AnyBlock, Device
1113

14+
15+
logger = logging.getLogger('mate3.mate3_pg')
16+
17+
1218
try:
1319
from yaml import load, FullLoader
1420
except ImportError:
@@ -37,6 +43,7 @@ class Definition(NamedTuple):
3743

3844

3945
def read_definitions(f) -> List[Table]:
46+
logger.info(f"Reading field definitions from {f.name}")
4047
in_yaml = load(f, Loader=FullLoader)
4148
tables = []
4249

@@ -55,10 +62,12 @@ def read_definitions(f) -> List[Table]:
5562
Table(table_name, definitions)
5663
)
5764

65+
logger.debug(f"Found definitions: {tables}")
5866
return tables
5967

6068

6169
def create_tables(conn, tables: List[Table], hypertables: bool):
70+
logger.info("Creating tables (if needed)")
6271
with conn.cursor() as curs:
6372
for table in tables:
6473
sql = (
@@ -70,13 +79,17 @@ def create_tables(conn, tables: List[Table], hypertables: bool):
7079
sql = sql.rstrip(',')
7180
sql += '\n)'
7281

82+
logger.debug(f"Executing: {sql}")
7383
curs.execute(sql)
84+
7485
if hypertables:
7586
try:
76-
curs.execute("SELECT create_hypertable(%s, 'timestamp')", [table.name])
87+
sql = f"SELECT create_hypertable('{table.name}', 'timestamp')"
88+
logger.debug(f"Executing: {sql}")
89+
curs.execute(sql, [table.name])
7790
except psycopg2.DatabaseError as e:
7891
if 'already a hypertable' in str(e):
79-
pass
92+
logger.debug("Table is already a hypertable")
8093
else:
8194
raise
8295

@@ -107,7 +120,9 @@ def insert(conn, tables: List[Table], blocks: List[AnyBlock]):
107120
f"(timestamp, {', '.join(column_names)}) "
108121
f"VALUES (NOW(), {', '.join(placeholders)})"
109122
)
110-
curs.execute(sql, list(insert_kv.values()))
123+
values = list(insert_kv.values())
124+
logger.debug(f"Executing: {sql}; With values {values}")
125+
curs.execute(sql, values)
111126

112127

113128
def main():
@@ -152,24 +167,56 @@ def main():
152167
help="Should we create tables as hypertables? Use only if you are using TimescaleDB",
153168
action='store_true',
154169
)
170+
parser.add_argument(
171+
"--quiet", "-q",
172+
dest="quiet",
173+
help="Hide status output. Only errors will be shown",
174+
action='store_true',
175+
)
176+
parser.add_argument(
177+
"--debug",
178+
dest="debug",
179+
help="Show debug logging",
180+
action='store_true',
181+
)
155182

156183
args = parser.parse_args(argv[1:])
184+
185+
logging.basicConfig(format="%(asctime)s - %(levelname)s - %(name)s - %(message)s", level=logging.ERROR)
186+
root_logger = logging.getLogger()
187+
mate3_logger = logging.getLogger('mate3')
188+
189+
if args.debug:
190+
root_logger.setLevel(logging.DEBUG)
191+
elif args.quiet:
192+
mate3_logger.setLevel(logging.ERROR)
193+
else:
194+
mate3_logger.setLevel(logging.INFO)
195+
157196
tables = read_definitions(args.definitions)
158197

198+
logger.info(f"Connecting to Postgres at {args.database_url}")
159199
with psycopg2.connect(args.database_url) as conn:
160200
conn.autocommit = True
161-
201+
logger.debug(f"Connected to Postgres")
162202
create_tables(conn, tables, hypertables=args.hypertables)
163-
with mate3_connection(args.host, args.port) as client:
164-
while True:
165-
start = time.time()
166-
167-
insert(conn, tables, list(client.all_blocks()))
168203

169-
total = time.time() - start
170-
sleep_time = args.interval - total
171-
if sleep_time > 0:
172-
time.sleep(args.interval - total)
204+
while True: # Reconnect loop
205+
try:
206+
logger.info(f"Connecting to mate3 at {args.host}:{args.port}")
207+
with mate3_connection(args.host, args.port) as client:
208+
while True:
209+
start = time.time()
210+
211+
insert(conn, tables, list(client.all_blocks()))
212+
213+
total = time.time() - start
214+
sleep_time = args.interval - total
215+
if sleep_time > 0:
216+
time.sleep(args.interval - total)
217+
except (ModbusIOException, ConnectionException) as e:
218+
logger.error(f"Communication error: {e}. Will try to reconnect in {args.interval} seconds")
219+
time.sleep(args.interval)
173220

174221

175222
if __name__ == '__main__':

0 commit comments

Comments
 (0)