boneIO 0.8.0.dev3__tar.gz → 0.8.0.dev6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/PKG-INFO +1 -1
  2. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/bonecli.py +6 -6
  3. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/const.py +1 -2
  4. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/client.py +22 -22
  5. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/cwt.json +4 -1
  6. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/modbuscli.py +16 -8
  7. boneIO-0.8.0.dev6/boneio/modbus/r4dcb08.json +91 -0
  8. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/sensor.py +5 -2
  9. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/oled.py +18 -6
  10. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/schema/schema.yaml +1 -0
  11. boneIO-0.8.0.dev6/boneio/version.py +2 -0
  12. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/pyproject.toml +1 -1
  13. boneIO-0.8.0.dev3/boneio/modbus/r4dcb08.json +0 -76
  14. boneIO-0.8.0.dev3/boneio/version.py +0 -2
  15. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/LICENSE +0 -0
  16. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/README.md +0 -0
  17. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/__init__.py +0 -0
  18. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/cover.py +0 -0
  19. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/__init__.py +0 -0
  20. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/adc.yaml +0 -0
  21. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/binary_sensor.yaml +0 -0
  22. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/config.yaml +0 -0
  23. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/cover.yaml +0 -0
  24. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/event.yaml +0 -0
  25. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/event_all.yaml +0 -0
  26. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/led32x4A.yaml +0 -0
  27. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/output24x16A.yaml +0 -0
  28. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/output24x16A_v0.3.yaml +0 -0
  29. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/output32x5A.yaml +0 -0
  30. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/fonts/danube__.ttf +0 -0
  31. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/group/__init__.py +0 -0
  32. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/group/output.py +0 -0
  33. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/__init__.py +0 -0
  34. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/async_updater.py +0 -0
  35. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/click_timer.py +0 -0
  36. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/config.py +0 -0
  37. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/events.py +0 -0
  38. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/exceptions.py +0 -0
  39. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/filter.py +0 -0
  40. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/gpio.py +0 -0
  41. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/ha_discovery.py +0 -0
  42. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/loader.py +0 -0
  43. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/logger.py +0 -0
  44. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/mqtt.py +0 -0
  45. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/oled.py +0 -0
  46. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/onewire/W1ThermSensor.py +0 -0
  47. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/onewire/__init__.py +0 -0
  48. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/onewire/ds2482.py +0 -0
  49. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/onewire/onewire.py +0 -0
  50. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/pcf8575.py +0 -0
  51. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/queue.py +0 -0
  52. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/sensor/ina_219_smbus.py +0 -0
  53. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/state_manager.py +0 -0
  54. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/stats.py +0 -0
  55. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/timeperiod.py +0 -0
  56. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/util.py +0 -0
  57. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/yaml_util.py +0 -0
  58. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/input/__init__.py +0 -0
  59. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/input/gpio.py +0 -0
  60. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/input/gpio_new.py +0 -0
  61. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/manager.py +0 -0
  62. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/__init__.py +0 -0
  63. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/dts1964_3f.json +0 -0
  64. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/orno-or-we-517.json +0 -0
  65. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/pt100.json +0 -0
  66. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/sdm120.json +0 -0
  67. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/sdm630.json +0 -0
  68. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/socomec_e23.json +0 -0
  69. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/sofar.json +0 -0
  70. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/utils.py +0 -0
  71. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/mqtt_client.py +0 -0
  72. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/relay/__init__.py +0 -0
  73. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/relay/basic.py +0 -0
  74. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/relay/gpio.py +0 -0
  75. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/relay/mcp.py +0 -0
  76. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/relay/pca.py +0 -0
  77. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/relay/pcf.py +0 -0
  78. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/runner.py +0 -0
  79. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/schema/actions.yaml +0 -0
  80. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/schema/actions_sensor.yaml +0 -0
  81. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/schema/actions_switch.yaml +0 -0
  82. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/schema/filters.yaml +0 -0
  83. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/schema/filters_adc.yaml +0 -0
  84. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/schema/id.yaml +0 -0
  85. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/schema/temp_unit.yaml +0 -0
  86. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/schema/update_interval.yaml +0 -0
  87. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/sensor/__init__.py +0 -0
  88. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/sensor/adc.py +0 -0
  89. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/sensor/gpio.py +0 -0
  90. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/sensor/gpio_new.py +0 -0
  91. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/sensor/ina219.py +0 -0
  92. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/sensor/temp/__init__.py +0 -0
  93. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/sensor/temp/dallas.py +0 -0
  94. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/sensor/temp/lm75.py +0 -0
  95. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/sensor/temp/mcp9808.py +0 -0
  96. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/tests/32_5_config.yaml +0 -0
  97. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/tests/bandit.yaml +0 -0
  98. {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/tests/relay_32_5.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: boneIO
3
- Version: 0.8.0.dev3
3
+ Version: 0.8.0.dev6
4
4
  Summary: Python App for BoneIO
5
5
  License: GNU General Public License v3.0
6
6
  Author-email: Paweł Szafer <pszafer@gmail.com>
@@ -113,7 +113,7 @@ def get_arguments() -> argparse.Namespace:
113
113
  modbus_parser.add_argument(
114
114
  "--bytesize",
115
115
  type=int,
116
- required=True,
116
+ required=False,
117
117
  default=8,
118
118
  help="Bytesize",
119
119
  )
@@ -121,7 +121,7 @@ def get_arguments() -> argparse.Namespace:
121
121
  modbus_parser.add_argument(
122
122
  "--stopbits",
123
123
  type=int,
124
- required=True,
124
+ required=False,
125
125
  default=1,
126
126
  help="stopbits",
127
127
  )
@@ -131,7 +131,7 @@ def get_arguments() -> argparse.Namespace:
131
131
  type=str,
132
132
  choices=["P", "E", "N"],
133
133
  default="N",
134
- required=True,
134
+ required=False,
135
135
  help="Parity",
136
136
  )
137
137
 
@@ -142,7 +142,7 @@ def get_arguments() -> argparse.Namespace:
142
142
  set_modbus_parser.add_argument(
143
143
  "--device",
144
144
  type=str,
145
- choices=["cwt"],
145
+ choices=["cwt", "r4dcb08"],
146
146
  help="Choose device to set modbus address/baudrate",
147
147
  required=True,
148
148
  )
@@ -156,8 +156,8 @@ def get_arguments() -> argparse.Namespace:
156
156
  set_modbus_parser_group.add_argument(
157
157
  "--new-baudrate",
158
158
  type=int,
159
- choices=[2400, 4800, 9600, 19200],
160
- help="Choose new baudrate to set",
159
+ choices=[1200, 2400, 4800, 9600, 19200],
160
+ help="Choose new baudrate to set. CWT doesn't work on 1200.",
161
161
  )
162
162
 
163
163
  get_modbus_parser = modbus_sub_parser.add_parser("get")
@@ -71,8 +71,7 @@ SHOW_HA = "show_in_ha"
71
71
  # OLED CONST
72
72
  OLED = "oled"
73
73
  FONTS = "fonts"
74
- OLED_PIN = ("",)
75
- "P9_41"
74
+ OLED_PIN = "P9_41"
76
75
  GIGABYTE = 1073741824
77
76
  MEGABYTE = 1048576
78
77
  WIDTH = 128
@@ -101,34 +101,26 @@ class Modbus:
101
101
  _LOGGER.error(exception_error)
102
102
  return False
103
103
 
104
- async def read_single_register(
104
+ async def read_and_decode(
105
105
  self,
106
106
  unit: int | str,
107
107
  address: int,
108
+ payload_type: str,
108
109
  count: int = 2,
109
110
  method: str = "input",
110
111
  ) -> float | None:
111
112
  """Call sync. pymodbus."""
112
- async with self._lock:
113
- if not self._pymodbus_connect():
114
- _LOGGER.error("Can't connect to Modbus address %s.", address)
115
- return None
116
- kwargs = {"unit": unit, "count": count} if unit else {}
117
- try:
118
- result: ReadInputRegistersResponse = self._read_methods[method](
119
- address, **kwargs
120
- )
121
- except (ModbusException, struct.error) as exception_error:
122
- _LOGGER.error(exception_error)
123
- return None
124
- if not hasattr(result, REGISTERS):
125
- _LOGGER.error(str(result))
126
- return None
127
- return BinaryPayloadDecoder.fromRegisters(
128
- result.registers, byteorder=Endian.Big, wordorder=Endian.Big
129
- ).decode_32bit_float()
113
+ result = await self.read_registers(
114
+ unit=unit, address=address, count=count, method=method
115
+ )
116
+ if not result or result.isError():
117
+ return None
118
+ decoded_value = self.decode_value(
119
+ payload=result.registers, value_type=payload_type
120
+ )
121
+ return decoded_value
130
122
 
131
- async def read_multiple_registers(
123
+ async def read_registers(
132
124
  self,
133
125
  unit: int | str, # device address
134
126
  address: int, # modbus register address
@@ -142,10 +134,18 @@ class Modbus:
142
134
  return None
143
135
  kwargs = {"unit": unit, "count": count} if unit else {}
144
136
  try:
145
- result: ReadInputRegistersResponse = self._read_methods[method](
137
+ read_method = self._read_methods[method]
138
+ _LOGGER.debug(
139
+ "Multiple reading %s registers from %s with method %s from device %s.",
140
+ count,
141
+ address,
142
+ method,
143
+ unit,
144
+ )
145
+ result: ReadInputRegistersResponse = read_method(
146
146
  address, **kwargs
147
147
  )
148
- except ModbusException as exception_error:
148
+ except (ModbusException, struct.error) as exception_error:
149
149
  _LOGGER.error(exception_error)
150
150
  return None
151
151
  if not hasattr(result, REGISTERS):
@@ -2,7 +2,10 @@
2
2
  "model": "CWT Temp and Humidity sensor",
3
3
  "set_base": {
4
4
  "set_address_address": 2000,
5
- "set_baudrate_address": 2001
5
+ "set_baudrate": {
6
+ "address": 2001,
7
+ "possible_baudrates": [2400, 4800, 9600, 19200]
8
+ }
6
9
  },
7
10
  "registers_base": [
8
11
  {
@@ -9,7 +9,7 @@ from .utils import REGISTERS_BASE, allowed_operations
9
9
  _LOGGER = logging.getLogger(__name__)
10
10
  SET_BASE = "set_base"
11
11
  SET_ADDRESS = "set_address_address"
12
- SET_BAUDRATE = "set_baudrate_address"
12
+ SET_BAUDRATE = "set_baudrate"
13
13
 
14
14
 
15
15
  class ModbusHelper:
@@ -53,7 +53,7 @@ class ModbusHelper:
53
53
  f"Checking connection {self._device_address}, address {address}."
54
54
  )
55
55
  count = 1 if value_type == "S_WORD" or value_type == "U_WORD" else 2
56
- value = await self._modbus.read_multiple_registers(
56
+ value = await self._modbus.read_registers(
57
57
  unit=self._device_address,
58
58
  address=address,
59
59
  count=count,
@@ -76,20 +76,23 @@ class ModbusHelper:
76
76
  return False
77
77
  return True
78
78
 
79
- def set_connection_speed(self, new_baudrate: int):
80
- ind = self.baud_rates.index(new_baudrate)
79
+ def set_connection_speed(self, new_baudrate: int) -> int:
80
+ baudrate_model = self._model[SET_BAUDRATE]
81
+ ind = baudrate_model["possible_baudrates"].index(new_baudrate)
81
82
  if ind:
82
83
  result = self._modbus.client.write_register(
83
- address=self._model[SET_BAUDRATE],
84
+ address=baudrate_model["address"],
84
85
  value=ind,
85
86
  unit=self._device_address,
86
87
  )
87
88
  if result.isError():
88
89
  _LOGGER.error("Operation failed.")
90
+ return 1
89
91
  else:
90
92
  _LOGGER.info(
91
93
  "Operation succeeded. Now restart device by disconnecting it."
92
94
  )
95
+ return 0
93
96
 
94
97
  def set_new_address(self, new_address: int):
95
98
  if 0 < new_address < 253:
@@ -128,6 +131,9 @@ async def async_run_modbus_set(
128
131
  if not first_reg_base:
129
132
  return False
130
133
  first_record = first_reg_base.get(REGISTERS, [])[0]
134
+ _LOGGER.debug(
135
+ f"Connecting with params uart: {uart}, baudrate: {baudrate}, stopbits: {stopbits}, bytesize: {bytesize}, parity: {parity}."
136
+ )
131
137
  modbus_helper = ModbusHelper(
132
138
  device=device,
133
139
  uart=uart,
@@ -144,8 +150,7 @@ async def async_run_modbus_set(
144
150
  _LOGGER.error("Can't connect with sensor. Exiting")
145
151
  return 1
146
152
  if new_baudrate:
147
- modbus_helper.set_connection_speed(new_baudrate=new_baudrate)
148
- return 0
153
+ return modbus_helper.set_connection_speed(new_baudrate=new_baudrate)
149
154
  if new_address:
150
155
  modbus_helper.set_new_address(new_address=new_address)
151
156
  return 0
@@ -164,6 +169,9 @@ async def async_run_modbus_get(
164
169
  parity: str = "N",
165
170
  ):
166
171
  """Run Modbus Get Function."""
172
+ _LOGGER.debug(
173
+ f"Connecting with params uart: {uart}, baudrate: {baudrate}, stopbits: {stopbits}, bytesize: {bytesize}, parity: {parity}."
174
+ )
167
175
  _modbus = Modbus(
168
176
  uart=UARTS[uart],
169
177
  baudrate=baudrate,
@@ -172,7 +180,7 @@ async def async_run_modbus_get(
172
180
  parity=parity,
173
181
  )
174
182
  count = 1 if value_type == "S_WORD" or value_type == "U_WORD" else 2
175
- value = await _modbus.read_multiple_registers(
183
+ value = await _modbus.read_registers(
176
184
  unit=device_address,
177
185
  address=register_address,
178
186
  count=count,
@@ -0,0 +1,91 @@
1
+ {
2
+ "model": "R4DCB08",
3
+ "set_base": {
4
+ "set_address_address": 254,
5
+ "set_baudrate": {
6
+ "address": 255,
7
+ "possible_baudrates": [1200, 2400, 4800, 9600, 19200]
8
+ }
9
+ },
10
+ "registers_base": [
11
+ {
12
+ "base": 0,
13
+ "length": 16,
14
+ "register_type": "holding",
15
+ "registers": [
16
+ {
17
+ "name": "Temperature 1",
18
+ "address": 0,
19
+ "unit_of_measurement": "°C",
20
+ "state_class": "measurement",
21
+ "device_class": "temperature",
22
+ "value_type": "S_WORD",
23
+ "filters": [{ "multiply": 0.1 }]
24
+ },
25
+ {
26
+ "name": "Temperature 2",
27
+ "address": 1,
28
+ "unit_of_measurement": "°C",
29
+ "state_class": "measurement",
30
+ "device_class": "temperature",
31
+ "value_type": "S_WORD",
32
+ "filters": [{ "multiply": 0.1 }]
33
+ },
34
+ {
35
+ "name": "Temperature 3",
36
+ "address": 2,
37
+ "unit_of_measurement": "°C",
38
+ "state_class": "measurement",
39
+ "device_class": "temperature",
40
+ "value_type": "S_WORD",
41
+ "filters": [{ "multiply": 0.1 }]
42
+ },
43
+ {
44
+ "name": "Temperature 4",
45
+ "address": 3,
46
+ "unit_of_measurement": "°C",
47
+ "state_class": "measurement",
48
+ "device_class": "temperature",
49
+ "value_type": "S_WORD",
50
+ "filters": [{ "multiply": 0.1 }]
51
+ },
52
+ {
53
+ "name": "Temperature 5",
54
+ "address": 4,
55
+ "unit_of_measurement": "°C",
56
+ "state_class": "measurement",
57
+ "device_class": "temperature",
58
+ "value_type": "S_WORD",
59
+ "filters": [{ "multiply": 0.1 }]
60
+ },
61
+ {
62
+ "name": "Temperature 6",
63
+ "address": 5,
64
+ "unit_of_measurement": "°C",
65
+ "state_class": "measurement",
66
+ "device_class": "temperature",
67
+ "value_type": "S_WORD",
68
+ "filters": [{ "multiply": 0.1 }]
69
+ },
70
+ {
71
+ "name": "Temperature 7",
72
+ "address": 6,
73
+ "unit_of_measurement": "°C",
74
+ "state_class": "measurement",
75
+ "device_class": "temperature",
76
+ "value_type": "S_WORD",
77
+ "filters": [{ "multiply": 0.1 }]
78
+ },
79
+ {
80
+ "name": "Temperature 8",
81
+ "address": 7,
82
+ "unit_of_measurement": "°C",
83
+ "state_class": "measurement",
84
+ "device_class": "temperature",
85
+ "value_type": "S_WORD",
86
+ "filters": [{ "multiply": 0.1 }]
87
+ }
88
+ ]
89
+ }
90
+ ]
91
+ }
@@ -122,10 +122,13 @@ class ModbusSensor(BasicMqtt, AsyncUpdater):
122
122
  register_method = first_register_base.get("register_type", "input")
123
123
  # Let's try fetch register 2 times in case something wrong with initial packet.
124
124
  for _ in [0, 1]:
125
- register = await self._modbus.read_single_register(
125
+ register = await self._modbus.read_and_decode(
126
126
  unit=self._address,
127
127
  address=first_register_base[REGISTERS][0][ADDRESS],
128
128
  method=register_method,
129
+ payload_type=first_register_base[REGISTERS][0].get(
130
+ "value_type", "FP32"
131
+ ),
129
132
  )
130
133
  if register is not None:
131
134
  self._discovery_sent = (
@@ -144,7 +147,7 @@ class ModbusSensor(BasicMqtt, AsyncUpdater):
144
147
  update_interval = self._update_interval.total_in_seconds
145
148
  await self.check_availability()
146
149
  for data in self._db[REGISTERS_BASE]:
147
- values = await self._modbus.read_multiple_registers(
150
+ values = await self._modbus.read_registers(
148
151
  unit=self._address,
149
152
  address=data[BASE],
150
153
  count=data[LENGTH],
@@ -26,8 +26,7 @@ fonts = {
26
26
  "big": make_font("DejaVuSans.ttf", 12),
27
27
  "small": make_font("DejaVuSans.ttf", 9),
28
28
  "extraSmall": make_font("DejaVuSans.ttf", 7),
29
- "danube": make_font("danube__.ttf", 15, local=True)
30
-
29
+ "danube": make_font("danube__.ttf", 15, local=True),
31
30
  }
32
31
 
33
32
  # screen_order = [UPTIME, NETWORK, CPU, DISK, MEMORY, SWAP]
@@ -96,7 +95,9 @@ class Oled:
96
95
 
97
96
  def _sleeptime(self):
98
97
  with canvas(self._device) as draw:
99
- draw.rectangle(self._device.bounding_box, outline="black", fill="black")
98
+ draw.rectangle(
99
+ self._device.bounding_box, outline="black", fill="black"
100
+ )
100
101
  self._sleep = True
101
102
 
102
103
  def _draw_uptime(self, data: dict, draw: ImageDraw) -> None:
@@ -116,7 +117,12 @@ class Oled:
116
117
  def _draw_output(self, data: dict, draw: ImageDraw) -> None:
117
118
  "Draw outputs of GPIO/MCP relays."
118
119
  cols = cycle(OUTPUT_COLS)
119
- draw.text((1, 1), f"Relay {self._current_screen}", font=fonts["small"], fill=WHITE)
120
+ draw.text(
121
+ (1, 1),
122
+ f"Relay {self._current_screen}",
123
+ font=fonts["small"],
124
+ fill=WHITE,
125
+ )
120
126
  i = 0
121
127
  j = next(cols)
122
128
  for k in data:
@@ -124,7 +130,10 @@ class Oled:
124
130
  j = next(cols)
125
131
  i = 0
126
132
  draw.text(
127
- (j, OUTPUT_ROWS[i]), f"{shorten_name(k)} {data[k]}", font=fonts["extraSmall"], fill=WHITE
133
+ (j, OUTPUT_ROWS[i]),
134
+ f"{shorten_name(k)} {data[k]}",
135
+ font=fonts["extraSmall"],
136
+ fill=WHITE,
128
137
  )
129
138
  i += 1
130
139
 
@@ -133,7 +142,10 @@ class Oled:
133
142
  data = self._host_data.get(self._current_screen)
134
143
  if data:
135
144
  with canvas(self._device) as draw:
136
- if self._output_groups and self._current_screen in self._output_groups:
145
+ if (
146
+ self._output_groups
147
+ and self._current_screen in self._output_groups
148
+ ):
137
149
  self._draw_output(data, draw)
138
150
  elif self._current_screen == UPTIME:
139
151
  self._draw_uptime(data, draw)
@@ -123,6 +123,7 @@ modbus:
123
123
  stopbits:
124
124
  type: integer
125
125
  default: 1
126
+ allowed: [1, 2]
126
127
  bytesize:
127
128
  type: integer
128
129
  default: 8
@@ -0,0 +1,2 @@
1
+ # flake8: noqa
2
+ __version__ = "0.8.0dev6"
@@ -30,7 +30,7 @@ dependencies = [
30
30
  "Adafruit-BBIO>=1.2.0",
31
31
  ]
32
32
  requires-python = ">=3.7"
33
- version = "0.8.0.dev3"
33
+ version = "0.8.0.dev6"
34
34
 
35
35
  [project.license]
36
36
  text = "GNU General Public License v3.0"
@@ -1,76 +0,0 @@
1
- {
2
- "model": "R4DCB08",
3
- "registers_base": [
4
- {
5
- "base": 0,
6
- "length": 16,
7
- "register_type": "holding",
8
- "registers": [
9
- {
10
- "name": "Temperature 1",
11
- "address": 0,
12
- "unit_of_measurement": "°C",
13
- "state_class": "measurement",
14
- "device_class": "temperature",
15
- "return_type": "multiply0_1"
16
- },
17
- {
18
- "name": "Temperature 2",
19
- "address": 1,
20
- "unit_of_measurement": "°C",
21
- "state_class": "measurement",
22
- "device_class": "temperature",
23
- "return_type": "multiply0_1"
24
- },
25
- {
26
- "name": "Temperature 3",
27
- "address": 2,
28
- "unit_of_measurement": "°C",
29
- "state_class": "measurement",
30
- "device_class": "temperature",
31
- "return_type": "multiply0_1"
32
- },
33
- {
34
- "name": "Temperature 4",
35
- "address": 3,
36
- "unit_of_measurement": "°C",
37
- "state_class": "measurement",
38
- "device_class": "temperature",
39
- "return_type": "multiply0_1"
40
- },
41
- {
42
- "name": "Temperature 5",
43
- "address": 4,
44
- "unit_of_measurement": "°C",
45
- "state_class": "measurement",
46
- "device_class": "temperature",
47
- "return_type": "multiply0_1"
48
- },
49
- {
50
- "name": "Temperature 6",
51
- "address": 5,
52
- "unit_of_measurement": "°C",
53
- "state_class": "measurement",
54
- "device_class": "temperature",
55
- "return_type": "multiply0_1"
56
- },
57
- {
58
- "name": "Temperature 7",
59
- "address": 6,
60
- "unit_of_measurement": "°C",
61
- "state_class": "measurement",
62
- "device_class": "temperature",
63
- "return_type": "multiply0_1"
64
- },
65
- {
66
- "name": "Temperature 8",
67
- "address": 7,
68
- "unit_of_measurement": "°C",
69
- "state_class": "measurement",
70
- "device_class": "temperature",
71
- "return_type": "multiply0_1"
72
- }
73
- ]
74
- }
75
- ]
76
- }
@@ -1,2 +0,0 @@
1
- # flake8: noqa
2
- __version__ = "0.8.0dev3"
File without changes
File without changes
File without changes