From 30c1b66c417fd1b3186ebc3a2488950967613677 Mon Sep 17 00:00:00 2001 From: "Maxime Alves LIRMM@home" Date: Fri, 31 Jul 2020 22:51:55 +0200 Subject: [PATCH] [routes] update routes --- pyheatpump/db.py | 3 +- pyheatpump/heatpump.py | 18 ++++---- pyheatpump/modbus.py | 62 +++++++++++++++++++++++++ pyheatpump/modbus_get.py | 49 ++++++++++---------- pyheatpump/variable_values.py | 86 +++++++++++++++++++++++++++++++++++ pyheatpump/variables.py | 10 +++- 6 files changed, 194 insertions(+), 34 deletions(-) create mode 100755 pyheatpump/modbus.py create mode 100644 pyheatpump/variable_values.py diff --git a/pyheatpump/db.py b/pyheatpump/db.py index c27799e..251d2fd 100755 --- a/pyheatpump/db.py +++ b/pyheatpump/db.py @@ -3,6 +3,7 @@ import sqlite3 from subprocess import Popen from .conf import config import sys +from pprint import pprint conn = None @@ -28,8 +29,8 @@ def sql(query): if conn is None: connect() + pprint(conn) cursor = conn.cursor() - print(f'Will execute query : \n{query}\n') cursor.execute(query) diff --git a/pyheatpump/heatpump.py b/pyheatpump/heatpump.py index 26b5349..1085bd5 100644 --- a/pyheatpump/heatpump.py +++ b/pyheatpump/heatpump.py @@ -5,19 +5,19 @@ from starlette.responses import JSONResponse from conf import config from db.db import sql -def get_variables(request): - pass +from pyheatpump.models import * +def get_variable_values(request): + res = {} + for var_type_id, var_type in VariableType.getall(): + res[var_type_id] = {} + for address, value in var_type.get_variables_values(): + res[address] = value -def get_variables_by_type(request): - pass + return JSONResponse(res) -def get_var_type_addresses(request): - request.path_params['type'] - heatpump = [ - Route('/', get_variables, methods=['GET']), - Route('/{type:str}', get_variables_by_type, methods=['GET']) + Route('/', get_all_variable_values, methods=['GET']) ] diff --git a/pyheatpump/modbus.py b/pyheatpump/modbus.py new file mode 100755 index 0000000..cc10792 --- /dev/null +++ b/pyheatpump/modbus.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +from serial import Serial +from serial.serialutil import SerialException +from umodbus.client.serial import rtu +from pprint import pprint + +from pyheatpump.conf import config + +serial_conn = None + +def connect(): + global serial_conn + + if serial_conn is None: + print('Connecting to serial port *{}*'.format( + config.get('heatpump', 'serial_port'))) + serial_conn = Serial(config.get('heatpump', 'serial_port'), + config.get('heatpump', 'baudrate')) + + if serial_conn.open is False: + print('Opening serial port') + serial_conn.open() + + return serial_conn + +def read_coils(start, end): + global serial_con + res = [] + + # digital - boolean + req_adu = rtu.read_coils( + slave_id=1, + starting_address=start, + quantity=end - start) + + resp = rtu.send_message(req_adu, serial_conn) + + return res + + +def read_holding_registers(start, end): + global serial_conn + res = [] + + + for address in range(start, end + 1, 125): + qty = 125 if (end - address) >= 125 else (end - address) + if not qty: + break + print(start, end, address, qty) + req_adu = rtu.read_coils( + slave_id=1, + starting_address=address, + quantity=qty) + + resp = rtu.send_message(req_adu, serial_conn) + res.extend(resp) + return res + +if __name__ == '__main__': + connect() + read_holding_registers(1, 10) diff --git a/pyheatpump/modbus_get.py b/pyheatpump/modbus_get.py index 8adefe0..074b1ae 100755 --- a/pyheatpump/modbus_get.py +++ b/pyheatpump/modbus_get.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # scripts/examples/simple_tcp_client.py import fcntl import sys @@ -9,7 +9,9 @@ from serial.serialutil import SerialException from umodbus.client.serial import rtu import json -from db.db import sql +from pyheatpump.db import sql +from pyheatpump.conf import config +config.set('heatpump', 'database', '/home/emixam/src/otec/pyHeatpump/db/pyheatpump.db') s = Serial('/dev/ttyUSB0',19200) try: @@ -27,8 +29,7 @@ def read_digital(): global s start_address, end_address = sql( - f"SELECT start_address, end_address FROM var_type - WHERE slabel LIKE 'D';") + "SELECT start_address, end_address FROM var_type WHERE slabel LIKE 'D'") res = [] @@ -58,8 +59,11 @@ def read_analog(): global s start_address, end_address = sql( - f"SELECT start_address, end_address FROM var_type - WHERE slabel LIKE 'A';") + """ + SELECT start_address, end_address FROM var_type + WHERE slabel LIKE 'A'; + """ + ) # analog - float for address in range(1, end_address - start_address, 125): @@ -86,29 +90,28 @@ def read_int(): res = [] - start_address, end_address = sql( - f"SELECT start_address, end_address FROM var_type - WHERE slabel LIKE 'I';") + start_address, end_address = 1, 1000 + #next(sql( + """ + SELECT start_address, end_address FROM var_type + WHERE slabel LIKE 'I' + """ + #)) # integer - int - for address in range(1, end_address - start_address, 125): - req_adu = rtu.read_coils( - slave_id=1, - starting_address=start_address + address, - quantity=125) - - resp = rtu.send_message(req_adu, s) - - for n in range(125): - try: - res[address + n] = int(resp[n]) - except KeyError as e: - print(e) - res[address + n] = 0 + req_adu = rtu.read_holding_registers( + slave_id=1, + starting_address=start_address, + quantity=125) + resp = rtu.send_message(req_adu, s) + for r in resp: + print(r) return res +read_int() + s.close() sys.exit(0) diff --git a/pyheatpump/variable_values.py b/pyheatpump/variable_values.py new file mode 100644 index 0000000..cc736df --- /dev/null +++ b/pyheatpump/variable_values.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 +import os +from datetime import datetime +from configparser import ConfigParser +from starlette.routing import Route, Router +from starlette.responses import PlainTextResponse, JSONResponse +from starlette.exceptions import HTTPException +from pprint import pprint +import uvicorn +import json + +# pyHeatpump modules +from pyheatpump.db import sql +from pyheatpump.models.variable import Variable +from pyheatpump.models.variable_type import VariableType +from pyheatpump.models.variable_value import VariableValue + + +async def get_variable_values(request): + return JSONResponse({}) + + +async def set_variable_values(request): + raise NotImplementedError + + +async def get_variable_value(type: str, address: int, time: str=None): + try: + args = { + 'type': type, + 'address': address, + 'time': time + } + if time is None: + args.pop('time') + else: + args['time'] = datetime.fromisoformat(time) + + row = VariableValue.get(**args) + + return PlainTextResponse(str(row.value)) + except StopIteration: + raise HTTPException(404) + + +async def set_variable_value(request): + raise NotImplementedError + + +async def variable_values_routes(request, *args, **kwargs): + if request['method'] == 'GET': + return await get_variable_values(request) + elif request['method'] == 'POST': + return await set_variable_values(request) + +async def variable_value_routes(request, *args, **kwargs): + if request['method'] == 'GET': + if 'type' not in request.path_params.keys(): + raise HTTPException(422) + if 'address' not in request.path_params.keys(): + raise HTTPException(422) + if 'time' not in request.path_params.keys(): + return await get_variable_value( + request.path_params['type'], + request.path_params['address']) + return await get_variable_value( + request.path_params['type'], + request.path_params['address'], + request.path_params['time']) + + elif request['method'] == 'POST': + return await set_variable_value(request *args, **kwargs) + + +ROUTES=[ + Route('/', variable_values_routes, methods=['GET', 'POST']), + Route('/{type:str}/{address:int}', variable_value_routes, methods=['GET', 'POST']), + Route('/{type:str}/{address:int}/{time:str}', variable_value_routes, methods=['GET']) +] + +app = Router(routes=ROUTES) + +if __name__ == '__main__': + uvicorn.run('pyHeatpump:conf.app', + host='127.0.0.1', + port=8000) diff --git a/pyheatpump/variables.py b/pyheatpump/variables.py index d3d214c..a14a3c6 100644 --- a/pyheatpump/variables.py +++ b/pyheatpump/variables.py @@ -14,7 +14,15 @@ from pyheatpump.models.variable import Variable async def get_variables(request): - return JSONResponse(Variable.getall()) + return JSONResponse(dict([ + (key, dict( + [ + (add, var.__dict__) + for add, var in var_type.items() + ]) + ) + for key, var_type in Variable.getall().items() + ])) async def set_variables(request):