Projet de remplacement du "RPiPasserelle" d'Otec.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_modbus.py 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #!/usr/bin/env python3
  2. import pytest
  3. from unittest.mock import patch, MagicMock
  4. from starlette.authentication import UnauthenticatedUser
  5. from starlette.testclient import TestClient
  6. from pprint import pprint
  7. import json
  8. from tempfile import mkstemp
  9. from configparser import ConfigParser
  10. import os
  11. from serial import Serial
  12. import umodbus
  13. from umodbus.client.serial import rtu
  14. from pyheatpump.conf import config
  15. from pyheatpump.db import initialize
  16. from pyheatpump.models.variable_type import VariableType
  17. from pyheatpump import modbus
  18. @pytest.fixture(scope='module')
  19. def set_test_db():
  20. _, tmpdb = mkstemp(suffix='.db', dir=os.getcwd(), )
  21. print(f'Will store database in {tmpdb}')
  22. config['heatpump']['database'] = tmpdb
  23. if not initialize(os.path.join(os.getcwd(), 'db/pyheatpump.sql')):
  24. sys.exit(-1)
  25. if not initialize(os.path.join(os.getcwd(), 'db/test_variables.sql')):
  26. sys.exit(-1)
  27. yield
  28. #os.unlink(tmpdb)
  29. @pytest.fixture(scope='module')
  30. def serial_conn():
  31. s = modbus.connect()
  32. assert type(s) == Serial
  33. return s
  34. @patch('umodbus.client.serial.rtu.send_message')
  35. @patch('umodbus.client.serial.rtu.read_coils')
  36. def test_rtu__coils_call_mocked(RtuReadCoils, RtuSendMessage, serial_conn):
  37. modbus.read_coils(1, 3)
  38. RtuReadCoils.assert_any_call(slave_id=1, starting_address=1, quantity=2)
  39. RtuSendMessage.assert_called()
  40. modbus.read_coils(1, 3)
  41. RtuReadCoils.assert_any_call(slave_id=1, starting_address=1, quantity=2)
  42. RtuSendMessage.assert_called()
  43. @patch('umodbus.client.serial.rtu.send_message')
  44. @patch('umodbus.client.serial.rtu.read_holding_registers')
  45. def test_rtu_registers_call_mocked(RtuReadHoldingRegisters, RtuSendMessage, serial_conn):
  46. modbus.read_holding_registers(1, 3)
  47. RtuReadHoldingRegisters.assert_any_call(slave_id=1, starting_address=1, quantity=2)
  48. RtuSendMessage.assert_called()
  49. modbus.read_holding_registers(1, 500)
  50. RtuReadHoldingRegisters.assert_any_call(slave_id=1, starting_address=1, quantity=125)
  51. RtuSendMessage.assert_called()
  52. def test_rtu_call_holding_registers(serial_conn):
  53. r = modbus.read_holding_registers(1, 1)
  54. assert type(r) == list
  55. assert len(r) == 0
  56. r = modbus.read_holding_registers(1, 5)
  57. assert type(r) == list
  58. assert len(r) == 4
  59. r = modbus.read_holding_registers(1, 126)
  60. assert type(r) == list
  61. assert len(r) == 125
  62. r = modbus.read_holding_registers(1, 151)
  63. assert type(r) == list
  64. assert len(r) == 150
  65. @pytest.fixture
  66. def var_types():
  67. return VariableType.getall()
  68. def test_get_analog(set_test_db, serial_conn, var_types):
  69. analog = var_types['Analog']
  70. print(analog.__dict__)
  71. res = modbus.read_holding_registers(analog.start_address, analog.end_address)
  72. assert type(res) == list
  73. assert len(res) == analog.end_address - analog.start_address
  74. for r in res:
  75. assert type(r) == int
  76. def test_get_integer(set_test_db, serial_conn, var_types):
  77. integer = var_types['Integer']
  78. print(integer.__dict__)
  79. try:
  80. res = modbus.read_holding_registers(integer.start_address, integer.end_address)
  81. assert type(res) == list
  82. assert len(res) == integer.end_address - integer.start_address
  83. for r in res:
  84. assert type(r) == int
  85. except umodbus.exceptions.IllegalDataAddressError as e:
  86. print(e)
  87. print(f'The start and end addresses are not available [{integer.start_address}, {integer.end_address}]')
  88. assert False
  89. def test_get_digital(set_test_db, serial_conn, var_types):
  90. digital = var_types['Digital']
  91. print(digital.__dict__)
  92. try:
  93. res = modbus.read_coils(digital.start_address, digital.end_address)
  94. except umodbus.exceptions.IllegalDataAddressError:
  95. print(f'The start and end addresses are not available [{digital.start_address}, {digital.end_address}]')
  96. assert type(res) == list
  97. assert len(res) == digital.end_address - digital.start_address
  98. for r in res:
  99. assert type(r) == int
  100. assert r in [0, 1]