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.
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/PKG-INFO +1 -1
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/bonecli.py +6 -6
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/const.py +1 -2
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/client.py +22 -22
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/cwt.json +4 -1
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/modbuscli.py +16 -8
- boneIO-0.8.0.dev6/boneio/modbus/r4dcb08.json +91 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/sensor.py +5 -2
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/oled.py +18 -6
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/schema/schema.yaml +1 -0
- boneIO-0.8.0.dev6/boneio/version.py +2 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/pyproject.toml +1 -1
- boneIO-0.8.0.dev3/boneio/modbus/r4dcb08.json +0 -76
- boneIO-0.8.0.dev3/boneio/version.py +0 -2
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/LICENSE +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/README.md +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/__init__.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/cover.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/__init__.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/adc.yaml +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/binary_sensor.yaml +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/config.yaml +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/cover.yaml +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/event.yaml +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/event_all.yaml +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/led32x4A.yaml +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/output24x16A.yaml +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/output24x16A_v0.3.yaml +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/example_config/output32x5A.yaml +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/fonts/danube__.ttf +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/group/__init__.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/group/output.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/__init__.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/async_updater.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/click_timer.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/config.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/events.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/exceptions.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/filter.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/gpio.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/ha_discovery.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/loader.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/logger.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/mqtt.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/oled.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/onewire/W1ThermSensor.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/onewire/__init__.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/onewire/ds2482.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/onewire/onewire.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/pcf8575.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/queue.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/sensor/ina_219_smbus.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/state_manager.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/stats.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/timeperiod.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/util.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/helper/yaml_util.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/input/__init__.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/input/gpio.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/input/gpio_new.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/manager.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/__init__.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/dts1964_3f.json +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/orno-or-we-517.json +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/pt100.json +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/sdm120.json +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/sdm630.json +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/socomec_e23.json +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/sofar.json +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/modbus/utils.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/mqtt_client.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/relay/__init__.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/relay/basic.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/relay/gpio.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/relay/mcp.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/relay/pca.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/relay/pcf.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/runner.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/schema/actions.yaml +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/schema/actions_sensor.yaml +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/schema/actions_switch.yaml +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/schema/filters.yaml +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/schema/filters_adc.yaml +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/schema/id.yaml +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/schema/temp_unit.yaml +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/schema/update_interval.yaml +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/sensor/__init__.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/sensor/adc.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/sensor/gpio.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/sensor/gpio_new.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/sensor/ina219.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/sensor/temp/__init__.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/sensor/temp/dallas.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/sensor/temp/lm75.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/boneio/sensor/temp/mcp9808.py +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/tests/32_5_config.yaml +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/tests/bandit.yaml +0 -0
- {boneIO-0.8.0.dev3 → boneIO-0.8.0.dev6}/tests/relay_32_5.py +0 -0
|
@@ -113,7 +113,7 @@ def get_arguments() -> argparse.Namespace:
|
|
|
113
113
|
modbus_parser.add_argument(
|
|
114
114
|
"--bytesize",
|
|
115
115
|
type=int,
|
|
116
|
-
required=
|
|
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=
|
|
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=
|
|
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")
|
|
@@ -101,34 +101,26 @@ class Modbus:
|
|
|
101
101
|
_LOGGER.error(exception_error)
|
|
102
102
|
return False
|
|
103
103
|
|
|
104
|
-
async def
|
|
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
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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
|
|
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
|
-
|
|
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):
|
|
@@ -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 = "
|
|
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.
|
|
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
|
-
|
|
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=
|
|
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.
|
|
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.
|
|
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.
|
|
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(
|
|
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(
|
|
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]),
|
|
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
|
|
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)
|
|
@@ -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
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|