Projet de remplacement du "RPiPasserelle" d'Otec.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

config.py 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #!/usr/bin/env python3
  2. import os
  3. import re
  4. import sys
  5. from datetime import datetime
  6. from configparser import ConfigParser
  7. from starlette.requests import Request
  8. from starlette.routing import Route, Router
  9. from starlette.responses import PlainTextResponse, JSONResponse
  10. from starlette.exceptions import HTTPException
  11. from pprint import pprint
  12. import uvicorn
  13. import json
  14. from pyheatpump.logger import logger_init
  15. logger = logger_init()
  16. """
  17. default_config = {
  18. 'heatpump': {
  19. 'serial_port': '/dev/ttyUSB0',
  20. 'baudrate': 19200,
  21. 'mac_address': 'None',
  22. 'ip_address': 'dhcp',
  23. 'read_only': 'False',
  24. 'database': '/var/run/pyheatpump/pyheatpump.sqlite3'
  25. },
  26. 'supervisor': {
  27. 'scheme': 'http',
  28. 'host': '127.0.0.1',
  29. 'port': 8008,
  30. 'certificate': 'None',
  31. 'get_path': '/',
  32. 'post_path': '/',
  33. 'interval': 10000,
  34. 'auth': 'None',
  35. 'initialization': str(datetime.now()),
  36. 'heatpump_id': 'None',
  37. 'last_update': 0
  38. },
  39. 'api': {
  40. 'host': '127.0.0.1',
  41. 'port': 80
  42. }
  43. }
  44. """
  45. CONFIG_FILES=[
  46. '/etc/pyheatpump.ini',
  47. './pyheatpump.ini']
  48. config = ConfigParser()#default_section='heatpump')
  49. #config.read_dict(default_config)
  50. config.read(filenames=CONFIG_FILES)
  51. API_HOST=config.get('api', 'host')
  52. API_PORT=config.get('api', 'port')
  53. def save_config():
  54. with open(CONFIG_FILES[-1], 'w') as conf_file:
  55. config.write(conf_file)
  56. def mac_address_init():
  57. from netifaces import gateways, ifaddresses, AF_INET, AF_LINK
  58. interface = gateways()['default'][AF_INET][1]
  59. if len(ifaddresses(interface)) == 0:
  60. logger.error("Can't find interface")
  61. sys.exit(1)
  62. if len(ifaddresses(interface)[AF_LINK]) == 0:
  63. logger.error("Can't find interface")
  64. sys.exit(1)
  65. addr = ifaddresses(interface)[AF_LINK][0]['addr']
  66. config.set('heatpump', 'mac_address', addr)
  67. save_config()
  68. logger.info(f'Got new mac address {addr}')
  69. return addr
  70. mac_address_init()
  71. def get_config_dict():
  72. c = config
  73. return {
  74. s: {
  75. i: j
  76. for i, j in c.items(s)
  77. }
  78. for s in c.sections()
  79. }
  80. async def get_config(request):
  81. return JSONResponse(get_config_dict())
  82. async def set_config(request):
  83. d_body = await request.json()
  84. for sect in d_body.keys():
  85. if type(d_body[sect]) is not dict:
  86. continue
  87. for item in d_body[sect].keys():
  88. if not config.has_option(sect, item):
  89. raise HTTPException(404, f'The option {sect}.{item} does not exists')
  90. else:
  91. config.set(sect, item, value=d_body[sect][item])
  92. save_config()
  93. return PlainTextResponse('OK')
  94. async def config_route(request, *args, **kwargs):
  95. config.read(filenames=CONFIG_FILES)
  96. if request['method'] == 'GET':
  97. return await get_config(request)
  98. elif request['method'] == 'POST':
  99. return await set_config(request)
  100. def get_mac():
  101. return config.get('heatpump','mac_address')
  102. async def mac_route(request, *args, **kwargs):
  103. config.read(filenames=CONFIG_FILES)
  104. if request['method'] == 'GET':
  105. return PlainTextResponse(get_mac())
  106. elif request['method'] == 'POST':
  107. body = await request.body()
  108. mac_address = body.decode()
  109. if len(mac_address) == 0:
  110. mac_address = mac_address_init()
  111. elif re.match('^([0-9a-f]{2}:?){6}$',
  112. mac_address, re.I) is not None:
  113. config.set('heatpump','mac_address',mac_address)
  114. save_config()
  115. else:
  116. print(f'Wrong mac format : {mac_address}')
  117. return PlainTextResponse(' '.join((
  118. 'Current ->',
  119. get_mac(),
  120. ', New -> ', mac_address)))
  121. def get_last_update():
  122. return config.get('supervisor', 'last_update')
  123. def set_last_update(last_update: int=0):
  124. config.set('supervisor', 'last_update', str(last_update))
  125. save_config()
  126. return get_last_update()
  127. async def last_update_route(request, *args, **kwargs):
  128. """
  129. last_update :
  130. == 0 : since current date - interval
  131. < 0 : since current_date + last_update - interval
  132. > 0 : since current_data - last_update - interval (same behaviour as < 0)
  133. """
  134. if type(request) != Request or request['method'] == 'GET':
  135. return PlainTextResponse(get_last_update())
  136. elif request['method'] == 'POST':
  137. body = await request.body()
  138. last_update = int(body.decode() or 0)
  139. if last_update == 0:
  140. print(f'Reset last update to current time')
  141. last_update = int(datetime.now().strftime('%s'))
  142. else:
  143. print(f'{"Forward" if last_update < 0 else "Rewind"} of {last_update} seconds')
  144. last_update = int(datetime.now().strftime('%s')) - last_update
  145. return PlainTextResponse(str(set_last_update(last_update)))
  146. ROUTES=[
  147. Route('/', config_route, methods=['GET', 'POST']),
  148. Route('/mac', mac_route, methods=['GET', 'POST']),
  149. Route('/last_update', last_update_route, methods=['GET', 'POST'])
  150. ]
  151. app = Router(routes=ROUTES)
  152. if __name__ == '__main__':
  153. uvicorn.run('pyHeatpump:conf.app',
  154. host='127.0.0.1',
  155. port=8000)