boneIO 0.8.0.dev7__py3-none-any.whl → 0.8.0.dev9__py3-none-any.whl

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: boneIO
3
- Version: 0.8.0dev7
3
+ Version: 0.8.0dev9
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>
@@ -1,17 +1,20 @@
1
1
  boneio/__init__.py,sha256=hoLKnu6h1uEsiCHA9Ql2MMDC7VQS0E-s_2cxBS-CTOg,147
2
- boneio/bonecli.py,sha256=30NobXHwuCYeDm3jZWcZD99Fx1nj9F4Q_YsgBQL5vbA,8052
2
+ boneio/bonecli.py,sha256=CpqKJxIG8wQGE26r-wXU36aPbqWMtP3oOSQ3HdlJ7a4,9713
3
3
  boneio/const.py,sha256=bGvnwS28zFLSrbV3F2nkqV0hklCgcrQKpBys8PC75Ds,5087
4
4
  boneio/cover.py,sha256=EfO1DAOGTPQykfgJHzg1WqPs0U8b1AnD2NMI-sLZccM,8444
5
5
  boneio/example_config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  boneio/example_config/adc.yaml,sha256=GKNpl2t7ebsH57UhJlJioXNuBflsL6eO4JMnyYwZrFs,168
7
7
  boneio/example_config/binary_sensor.yaml,sha256=4oErCX-5t6e9e0KVo5GkkFplKkgKs0st-wTmyiCZNzM,286
8
+ boneio/example_config/binary_sensor_v_0_7.yaml,sha256=uaIDVV7t4drhlBDu_IK-ZK1DiMqqCP9tCi_HfS7KP5I,185
8
9
  boneio/example_config/config.yaml,sha256=7QOFD5P8wJYJrpA2qOwNM975ZKgeO7oKZphgJCP589k,397
9
10
  boneio/example_config/cover.yaml,sha256=rs7lv3vIEgAb3q96RKsJL7VMRsEvSNHG848dzZzSKsI,150
10
11
  boneio/example_config/event.yaml,sha256=9TMKXGLTAz4umSJCiMs53ReFmhY84LtmEPnanIIw-uY,2692
11
12
  boneio/example_config/event_all.yaml,sha256=9TMKXGLTAz4umSJCiMs53ReFmhY84LtmEPnanIIw-uY,2692
13
+ boneio/example_config/event_v_0_7.yaml,sha256=n78Hsdq03zNSKICZ9muL5p3ZJQLCKU1juDVC1oCRNXw,4819
12
14
  boneio/example_config/led32x4A.yaml,sha256=YkcZ5XH2JF9Oa3pAmrYM5wsE8qQODCHcjYH47AEQpUI,3392
13
15
  boneio/example_config/output24x16A.yaml,sha256=BTtHToRgz-U_rMMDbmHkM4wQxHakdzInb3zKMkOkj4w,1691
14
16
  boneio/example_config/output24x16A_v0.3.yaml,sha256=XkI4rHn_XdX37xG02-wHieZzSHKiKN5mtnyfRE24NII,1713
17
+ boneio/example_config/output32x10A.yaml,sha256=A4uzkZLSkC66Ck6bWkdMbnT0gQUByU8qi0muAgpOn40,2318
15
18
  boneio/example_config/output32x5A.yaml,sha256=G2Pb6qL8mXs6MliIM1roAanPag9ozRe3McYYuFsiBc0,2403
16
19
  boneio/fonts/danube__.ttf,sha256=KBRPUcGvmroCjrWC8zK4MulUb9lV8R0lXkOY7lNnQWc,19372
17
20
  boneio/group/__init__.py,sha256=eUN51J6nU1MdQfcl6JQ2AQwkP6K91mR9caDZyZ18rig,80
@@ -22,10 +25,10 @@ boneio/helper/click_timer.py,sha256=Gu8sEi1S8GG42SYbfaMju7WXFhnnil9gYfirLZX7kJk,
22
25
  boneio/helper/config.py,sha256=5cDnJ7usJDlUvXv8K2rSWEx30OFcU2k1U1vUEjO69WY,2431
23
26
  boneio/helper/events.py,sha256=ttb2_xOgyTXPIZv4ywJ2udCdqYLIVejBo7ATqsm7OQQ,8818
24
27
  boneio/helper/exceptions.py,sha256=vyYSUojwB7OttOPUjbxeHFM7C_o5ZQmRUcZ_vYpxYYI,717
25
- boneio/helper/filter.py,sha256=8jgSbHDaInEVlAPd7nrahnFYsi1y6C2fmI0yn55XzK0,935
28
+ boneio/helper/filter.py,sha256=XwlaapfTTYXwcvJmKYJBksJD7i1u_xHIm_XrvyiuC6o,1005
26
29
  boneio/helper/gpio.py,sha256=q2r2uklPWePuuekPO63kVfoaQdkvNObUJ3ktwsHgOB0,4771
27
30
  boneio/helper/ha_discovery.py,sha256=B2t1cfOfKWys4EM1H7OxvOaYL8H_v18CTuHCEVP2w2c,7107
28
- boneio/helper/loader.py,sha256=3MVgTLp1NlYbQ0nCw-MfF1nSvcwb-VXGUbgXIdg84VM,17496
31
+ boneio/helper/loader.py,sha256=-kOCe0ooYfWJu0EIcn4lzWjNz_4RJkwMQ5XF1NyYfwQ,17563
29
32
  boneio/helper/logger.py,sha256=zyF_Vk3o2eSHuXypJhNzK99eZgkWDWybuB5KcJgurDs,1801
30
33
  boneio/helper/mqtt.py,sha256=1YgwO0RjkarN5qS5HS5rONf4H3_m3ak7tT_hHm-HeOQ,931
31
34
  boneio/helper/oled.py,sha256=f0XYbaFstUbJ6ISmFe1vQCnmNVMctQWtnStNdROrblc,351
@@ -46,16 +49,18 @@ boneio/input/gpio.py,sha256=3Eh_3ko0RkTKqq7pKlgTROJeaSYgt05NkfeGoWudqfY,2674
46
49
  boneio/input/gpio_new.py,sha256=gpPfDr39B8FVUyh9XHtLgVQr4glMGFBgQsyIMzXDPaw,2822
47
50
  boneio/manager.py,sha256=leMDXrmyHmlndgt_GdlkvKnFRaUDZI8uDzCr8yLvcY8,29869
48
51
  boneio/modbus/__init__.py,sha256=yeHIxZ0_u7eCL7CqScvob5Utcru6Iza0LEtTagEtNtw,116
49
- boneio/modbus/client.py,sha256=-TMFQPVWWTlzS1HG1QVX4QwpfwSIxf0cgFOv3_gu7so,5851
50
- boneio/modbus/cwt.json,sha256=JwkQuRZFA03C3o9RgryMuCaYoCwM4RkiakEB6dkKgxE,886
52
+ boneio/modbus/client.py,sha256=0bc8T7DIvbyD2vkfI_bJmMTxIQTMtdJxyGE8Z0J5iZY,5912
53
+ boneio/modbus/cwt.json,sha256=PCn9t5wQkNCD8AqwXSoJ3cEm50bKAX4FmPw6fWCvLrg,908
51
54
  boneio/modbus/dts1964_3f.json,sha256=WABph_2X4OgMidSM28vw4dLd9ZByRoiUP-RqE0UMpR8,8810
52
- boneio/modbus/modbuscli.py,sha256=VJKI85HRD7Usi0x4pSMS9GzuhYfLCx8qVjNsHuao0Is,6231
55
+ boneio/modbus/liquid-sensor.json,sha256=y00XpFFktm2a-ZrF_jujbqy2YAjHYBCBV_Avzlqih4s,737
56
+ boneio/modbus/modbuscli.py,sha256=wvj1QKDSIoXg9_zpoMqRD43CEYLLt6fBkQ0g-IRhs8w,8498
53
57
  boneio/modbus/orno-or-we-517.json,sha256=w4kPFD8Wtr6Vv5BbGuvCiTHflo71FOxwp3fY8gZN2pQ,842
54
58
  boneio/modbus/pt100.json,sha256=bzKNYDc3lMto94Ut8gutVIsHytQiMobwFCkonOiMegs,526
55
- boneio/modbus/r4dcb08.json,sha256=uoQ5EGiFVY_uhYlOWYyFLCXpWxgtEB4SRAAkgON9ii8,2550
59
+ boneio/modbus/r4dcb08.json,sha256=3SeAs_BYEoh12HOfQ-m7HB_UeFYrJLAGF6CV3hzalLo,2623
56
60
  boneio/modbus/sdm120.json,sha256=4sueFfSw7G6a77gdIUhbfJvE-MNVJFOeVbRvHDw5Rvk,4145
57
61
  boneio/modbus/sdm630.json,sha256=TUiuc060IpF64p_HSDvdxEQcwkWHWUpnd48_xaGU-_o,8255
58
- boneio/modbus/sensor.py,sha256=TZYMPzgrrNE2gYO9dYeEZ6bSBUvHmubNK3gc-ukVkm8,8429
62
+ boneio/modbus/sensor.py,sha256=JmmG3CcfmKEheOQY0XasVEjygnwxvtD01JpwBGLgpdE,8957
63
+ boneio/modbus/sht20.json,sha256=KV7TAvYo3oIQPM65SKyJYEugo6D8Ubz34hg6AGMwq3Y,907
59
64
  boneio/modbus/socomec_e23.json,sha256=Is51YelEd4d6SYmz4Gd_oKx4Qi3bp-VHsl9zxWOFI5s,2882
60
65
  boneio/modbus/sofar.json,sha256=A_YztQN_ctyItIm2LH1tfcs-pSyG18I530qleLd2tOw,5592
61
66
  boneio/modbus/utils.py,sha256=cG75mmKTGaw_qrCG_D1qw-jl9XybUXa03i1ap5oBxGE,1753
@@ -74,21 +79,21 @@ boneio/schema/actions_switch.yaml,sha256=cDgSi12k4S-TWADQ20Fy9NvYKOXnm7YkyMaWpPy
74
79
  boneio/schema/filters.yaml,sha256=WopX1SmCZsSZXNiGccLoi7uMCsUpdbs0eVfsAjmbay4,286
75
80
  boneio/schema/filters_adc.yaml,sha256=3e0ts92MoFKOnfGOOn6WYIHxu0-tnZe9OjAjN9m7hiI,304
76
81
  boneio/schema/id.yaml,sha256=vHI_6dxkJwoiGp5ien_pPpyaWA1F06eirTgfWMyWa1E,75
77
- boneio/schema/schema.yaml,sha256=Chcsh1kHMxhE_cx-T3GWpfXWmSZANhzyNQa-Qw4PKoY,18658
82
+ boneio/schema/schema.yaml,sha256=DTgAbtgAhLuNf1llj7pmEJd3D9Z9QIUU_OmslOH7XL0,18942
78
83
  boneio/schema/temp_unit.yaml,sha256=m32VGz9RTW92Lz08l9n6RftkcVNZquOGPPr5mc3eZVc,65
79
84
  boneio/schema/update_interval.yaml,sha256=L_YLddAZdybcdO-T57Qhlv1GaWIVDwhvH-GadD1oOIo,133
80
85
  boneio/sensor/__init__.py,sha256=Ztj-xzey-SWrEdVEozcwFsZSuEmJW8STVaf_vPMWiVc,619
81
86
  boneio/sensor/adc.py,sha256=tCUdr3KN5uSbgXiwhNXbMjeNkO2CzPYhIOncHR5_LD0,1328
82
87
  boneio/sensor/gpio.py,sha256=8m07tW1xDsrhBM2dZ9_VvmvYRn-5hLQVTTUhPlKg1rg,1199
83
88
  boneio/sensor/gpio_new.py,sha256=m54agOF2gUh3aoC6f8WpCPAmBRADvqlKeWLqwlon9fg,1223
84
- boneio/sensor/ina219.py,sha256=mIvu-nIfpfrSi_sn7FBYS8n3y2AkGsXBO_OLAy3tQ48,3518
89
+ boneio/sensor/ina219.py,sha256=4APsSUI1L_FmsDb1T1kmyYyMUZveGpCjsOevqd_SHjg,3529
85
90
  boneio/sensor/temp/__init__.py,sha256=JLNH6Nc78ezleftnIYylIcNtKIm0rdqetbPZLsuCgDc,1844
86
91
  boneio/sensor/temp/dallas.py,sha256=xrvd1LNBh1fRcjz_yd_9S29Lv26ItVtLCmhZgVQWJos,2485
87
92
  boneio/sensor/temp/lm75.py,sha256=-mpOv78429plRPBp9s09Ljz1x2Bdxuagalqz40vlAKE,243
88
93
  boneio/sensor/temp/mcp9808.py,sha256=yAh5yJzZLGTqa39xV4fyqsruj7oy3niOZAUV2W6eyCM,271
89
- boneio/version.py,sha256=RFQ1JEqV7cWikzWZr2EAD060ikkbEdYQD3TfyHPLTxQ,41
90
- boneIO-0.8.0.dev7.dist-info/entry_points.txt,sha256=Igl1SMDEWwMg144bwRz28UOCb80hdxomC99QJ3u6qC0,46
91
- boneIO-0.8.0.dev7.dist-info/WHEEL,sha256=B19PGBCYhWaz2p_UjAoRVh767nYQfk14Sn4TpIZ-nfU,87
92
- boneIO-0.8.0.dev7.dist-info/METADATA,sha256=N3sdSQeUm6182kxusgS8Zt4KWz9qKjHBHVe2-d1zXyA,1801
93
- boneIO-0.8.0.dev7.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
94
- boneIO-0.8.0.dev7.dist-info/RECORD,,
94
+ boneio/version.py,sha256=vxdmMbd3NYDLNsRFB8-mOyjJajj0gvw80S3LgODVhfU,41
95
+ boneIO-0.8.0.dev9.dist-info/entry_points.txt,sha256=Igl1SMDEWwMg144bwRz28UOCb80hdxomC99QJ3u6qC0,46
96
+ boneIO-0.8.0.dev9.dist-info/WHEEL,sha256=B19PGBCYhWaz2p_UjAoRVh767nYQfk14Sn4TpIZ-nfU,87
97
+ boneIO-0.8.0.dev9.dist-info/METADATA,sha256=mPoc_48R7ndLtTCZVEx1mDtB6yhQkxICYE_NRDvoSnY,1801
98
+ boneIO-0.8.0.dev9.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
99
+ boneIO-0.8.0.dev9.dist-info/RECORD,,
boneio/bonecli.py CHANGED
@@ -13,7 +13,11 @@ import sys
13
13
  from colorlog import ColoredFormatter
14
14
  from yaml import MarkedYAMLError
15
15
 
16
- from boneio.modbus.modbuscli import async_run_modbus_set, async_run_modbus_get
16
+ from boneio.modbus.modbuscli import (
17
+ async_run_modbus_set,
18
+ async_run_modbus_get,
19
+ async_run_modbus_search,
20
+ )
17
21
  from boneio.modbus.client import VALUE_TYPES
18
22
 
19
23
 
@@ -99,13 +103,14 @@ def get_arguments() -> argparse.Namespace:
99
103
  modbus_parser.add_argument(
100
104
  "--address",
101
105
  type=lambda x: int(x, 0),
102
- required=True,
106
+ required=False,
107
+ default=1,
103
108
  help="Current device address (hex or integer)",
104
109
  )
105
110
  modbus_parser.add_argument(
106
111
  "--baudrate",
107
112
  type=int,
108
- choices=[2400, 4800, 9600, 19200],
113
+ choices=[2400, 4800, 9600, 14400, 19200],
109
114
  required=True,
110
115
  help="Current baudrate",
111
116
  )
@@ -139,11 +144,21 @@ def get_arguments() -> argparse.Namespace:
139
144
  dest="modbus_action", required=True
140
145
  )
141
146
  set_modbus_parser = modbus_sub_parser.add_parser("set")
147
+ set_modbus_parser.add_argument(
148
+ "--custom-value",
149
+ type=int,
150
+ help="Set Custom value",
151
+ )
152
+ set_modbus_parser.add_argument(
153
+ "--custom-register-address",
154
+ type=int,
155
+ help="Register address for custom value",
156
+ )
142
157
  set_modbus_parser.add_argument(
143
158
  "--device",
144
159
  type=str,
145
- choices=["cwt", "r4dcb08"],
146
- help="Choose device to set modbus address/baudrate",
160
+ choices=["cwt", "r4dcb08", "liquid-sensor", "sht20", "custom"],
161
+ help="Choose device to set modbus address/baudrate. For custom you must provide --custom-value and --custom-register-address",
147
162
  required=True,
148
163
  )
149
164
  set_modbus_parser_group = set_modbus_parser.add_mutually_exclusive_group()
@@ -182,6 +197,23 @@ def get_arguments() -> argparse.Namespace:
182
197
  required=True,
183
198
  )
184
199
  parser.add_argument("--version", action="version", version=__version__)
200
+ search_modbus_parser = modbus_sub_parser.add_parser(
201
+ name="search",
202
+ help="Search for device. Iterate over every address 1-253 with provided register address",
203
+ )
204
+ search_modbus_parser.add_argument(
205
+ "--register-address",
206
+ type=int,
207
+ help="Register address",
208
+ required=True,
209
+ )
210
+ search_modbus_parser.add_argument(
211
+ "--register-type",
212
+ type=str,
213
+ choices=["input", "holding"],
214
+ help="Register type",
215
+ required=True,
216
+ )
185
217
  arguments = parser.parse_args()
186
218
 
187
219
  return arguments
@@ -223,6 +255,7 @@ def run_modbus_command(
223
255
  _LOGGER.info("BoneIO %s starting.", __version__)
224
256
  try:
225
257
  configure_logger(log_config={}, debug=args.debug)
258
+ ret = 0
226
259
  if args.modbus_action == "set":
227
260
  ret = asyncio.run(
228
261
  async_run_modbus_set(
@@ -235,9 +268,11 @@ def run_modbus_command(
235
268
  stopbits=args.stopbits,
236
269
  new_baudrate=args.new_baudrate,
237
270
  new_address=args.new_address,
271
+ custom_address=args.custom_register_address,
272
+ custom_value=args.custom_value,
238
273
  ),
239
274
  )
240
- else:
275
+ elif args.modbus_action == "get":
241
276
  ret = asyncio.run(
242
277
  async_run_modbus_get(
243
278
  uart=args.uart,
@@ -251,6 +286,18 @@ def run_modbus_command(
251
286
  value_type=args.value_type,
252
287
  ),
253
288
  )
289
+ else:
290
+ ret = asyncio.run(
291
+ async_run_modbus_search(
292
+ uart=args.uart,
293
+ baudrate=args.baudrate,
294
+ register_address=args.register_address,
295
+ register_type=args.register_type,
296
+ parity=args.parity,
297
+ bytesize=args.bytesize,
298
+ stopbits=args.stopbits,
299
+ ),
300
+ )
254
301
  return ret
255
302
  except (RestartRequestException, GracefulExit) as err:
256
303
  if err is not None:
@@ -281,7 +328,10 @@ def main() -> int:
281
328
  args=args,
282
329
  )
283
330
 
284
- _LOGGER.info("Exiting with exit code %s", exit_code)
331
+ if exit_code == 0:
332
+ _LOGGER.info("Exiting with exit code %s", exit_code)
333
+ else:
334
+ _LOGGER.error("Exiting with exit code %s", exit_code)
285
335
  return exit_code
286
336
 
287
337
 
@@ -0,0 +1,11 @@
1
+ #- id: IN_02
2
+ # pin: P8_38
3
+ # gpio_mode: gpio_pu
4
+ # detection_type: new
5
+ - id: IN_26
6
+ detection_type: new
7
+ pin: P8_7
8
+ actions:
9
+ pressed:
10
+ - action: output
11
+ pin: OUT_26
@@ -0,0 +1,292 @@
1
+ - id: IN_01
2
+ pin: P8_37
3
+ gpio_mode: gpio_pu
4
+ detection_type: new
5
+ actions:
6
+ single:
7
+ - action: output
8
+ pin: OUT_01
9
+ - id: IN_02
10
+ pin: P8_38
11
+ gpio_mode: gpio_pu
12
+ actions:
13
+ single:
14
+ - action: output
15
+ pin: OUT_02
16
+ - id: IN_03
17
+ pin: P8_39
18
+ detection_type: new
19
+ actions:
20
+ single:
21
+ - action: output
22
+ pin: OUT_03
23
+ - id: IN_04
24
+ pin: P8_40
25
+ detection_type: new
26
+ actions:
27
+ single:
28
+ - action: output
29
+ pin: OUT_04
30
+ - id: IN_05
31
+ pin: P8_41
32
+ detection_type: new
33
+ actions:
34
+ single:
35
+ - action: output
36
+ pin: OUT_05
37
+ - id: IN_06
38
+ pin: P8_42
39
+ detection_type: new
40
+ actions:
41
+ single:
42
+ - action: output
43
+ pin: OUT_06
44
+ - id: IN_07
45
+ detection_type: new
46
+ pin: P8_43
47
+ actions:
48
+ single:
49
+ - action: output
50
+ pin: OUT_07
51
+ - id: IN_08
52
+ pin: P8_44
53
+ detection_type: new
54
+ actions:
55
+ single:
56
+ - action: output
57
+ pin: OUT_08
58
+ - id: IN_09
59
+ pin: P8_45
60
+ detection_type: new
61
+ gpio_mode: gpio_pu
62
+ actions:
63
+ single:
64
+ - action: output
65
+ pin: OUT_09
66
+ - id: IN_10
67
+ pin: P8_46
68
+ gpio_mode: gpio_pu
69
+ detection_type: new
70
+ actions:
71
+ single:
72
+ - action: output
73
+ pin: OUT_10
74
+ - id: IN_11
75
+ pin: P9_42
76
+ detection_type: new
77
+ actions:
78
+ single:
79
+ - action: output
80
+ pin: OUT_11
81
+ - id: IN_12
82
+ detection_type: new
83
+ pin: P9_31
84
+ actions:
85
+ single:
86
+ - action: output
87
+ pin: OUT_12
88
+ # double:
89
+ # - action: mqtt
90
+ # topic: beagle2/cmd/relay/OUT_12/set
91
+ # action_mqtt_msg: 'toggle'
92
+ - id: IN_13
93
+ detection_type: new
94
+ pin: P9_30
95
+ actions:
96
+ single:
97
+ - action: output
98
+ pin: OUT_13
99
+ # long:
100
+ # - action: mqtt
101
+ # topic: beagle2/cmd/relay/OUT_13/set
102
+ # action_mqtt_msg: 'toggle'
103
+ - id: IN_14
104
+ detection_type: new
105
+ pin: P9_29
106
+ actions:
107
+ single:
108
+ - action: output
109
+ pin: OUT_14
110
+
111
+ - id: IN_15
112
+ detection_type: new
113
+ pin: P9_28
114
+ actions:
115
+ single:
116
+ - action: output
117
+ pin: OUT_15
118
+ - id: IN_16
119
+ detection_type: new
120
+ pin: P9_27
121
+ actions:
122
+ single:
123
+ - action: output
124
+ pin: OUT_16
125
+ - id: IN_17
126
+ detection_type: new
127
+ pin: P9_25
128
+ actions:
129
+ single:
130
+ - action: output
131
+ pin: OUT_17
132
+ - id: IN_18
133
+ detection_type: new
134
+ pin: P9_23
135
+ actions:
136
+ single:
137
+ - action: output
138
+ pin: OUT_18
139
+ - id: IN_19
140
+ detection_type: new
141
+ pin: P9_22
142
+ gpio_mode: gpio_pu
143
+ actions:
144
+ single:
145
+ - action: output
146
+ pin: OUT_19
147
+ - id: IN_20
148
+ detection_type: new
149
+ pin: P9_21
150
+ gpio_mode: gpio_pu
151
+ actions:
152
+ single:
153
+ - action: output
154
+ pin: OUT_20
155
+ - id: IN_21
156
+ detection_type: new
157
+ pin: P9_18
158
+ actions:
159
+ single:
160
+ - action: output
161
+ pin: OUT_21
162
+ - id: IN_22
163
+ detection_type: new
164
+ pin: P9_17
165
+ actions:
166
+ single:
167
+ - action: output
168
+ pin: OUT_22
169
+ - id: IN_23
170
+ detection_type: new
171
+ pin: P9_16
172
+ actions:
173
+ single:
174
+ - action: output
175
+ pin: OUT_23
176
+ - id: IN_24
177
+ detection_type: new
178
+ pin: P9_15
179
+ actions:
180
+ single:
181
+ - action: output
182
+ pin: OUT_24
183
+ - id: IN_25
184
+ detection_type: new
185
+ pin: P9_14
186
+ actions:
187
+ single:
188
+ - action: output
189
+ pin: OUT_25
190
+
191
+ #- id: IN_26_binary_sensor!
192
+ # detection_type: new
193
+ # pin: P8_07
194
+
195
+ - id: IN_27
196
+ detection_type: new
197
+ pin: P8_8
198
+ actions:
199
+ single:
200
+ - action: output
201
+ pin: OUT_27
202
+ - id: IN_28
203
+ detection_type: new
204
+ pin: P8_9
205
+ actions:
206
+ single:
207
+ - action: output
208
+ pin: OUT_28
209
+ - id: IN_29
210
+ detection_type: new
211
+ pin: P8_36
212
+ gpio_mode: gpio_pu
213
+ actions:
214
+ single:
215
+ - action: output
216
+ pin: OUT_29
217
+ - id: IN_30
218
+ detection_type: new
219
+ pin: P8_35
220
+ gpio_mode: gpio_pu
221
+ actions:
222
+ single:
223
+ - action: output
224
+ pin: OUT_30
225
+ - id: IN_31
226
+ detection_type: new
227
+ pin: P8_34
228
+ gpio_mode: gpio_pu
229
+ actions:
230
+ single:
231
+ - action: output
232
+ pin: OUT_31
233
+ - id: IN_32
234
+ detection_type: new
235
+ pin: P8_33
236
+ gpio_mode: gpio_pu
237
+ actions:
238
+ single:
239
+ - action: output
240
+ pin: OUT_32
241
+ - id: IN_33
242
+ detection_type: new
243
+ pin: P8_32
244
+ gpio_mode: gpio_pu
245
+ - id: IN_34
246
+ detection_type: new
247
+ pin: P8_31
248
+ - id: IN_35
249
+ detection_type: new
250
+ pin: P8_30
251
+ - id: IN_36
252
+ detection_type: new
253
+ pin: P8_29
254
+ - id: IN_37
255
+ detection_type: new
256
+ pin: P8_28
257
+ - id: IN_38
258
+ detection_type: new
259
+ pin: P8_27
260
+ - id: IN_39
261
+ detection_type: new
262
+ pin: P8_26
263
+ - id: IN_40
264
+ detection_type: new
265
+ pin: P8_19
266
+ - id: IN_41
267
+ detection_type: new
268
+ pin: P8_18
269
+ - id: IN_42
270
+ detection_type: new
271
+ pin: P8_17
272
+ - id: IN_43
273
+ detection_type: new
274
+ pin: P8_16
275
+ - id: IN_44
276
+ detection_type: new
277
+ pin: P8_15
278
+ - id: IN_45
279
+ detection_type: new
280
+ pin: P8_14
281
+ - id: IN_46
282
+ detection_type: new
283
+ pin: P8_13
284
+ - id: IN_47
285
+ detection_type: new
286
+ pin: P8_12
287
+ - id: IN_48
288
+ detection_type: new
289
+ pin: P8_11
290
+ - id: IN_49
291
+ detection_type: new
292
+ pin: P8_10
@@ -0,0 +1,192 @@
1
+ # config to Relay board 32x10 v0.4
2
+ - id: OUT_01
3
+ kind: mcp
4
+ mcp_id: mcp2
5
+ pin: 7
6
+ output_type: light
7
+
8
+ - id: OUT_02
9
+ kind: mcp
10
+ mcp_id: mcp2
11
+ pin: 6
12
+ output_type: light
13
+
14
+ - id: OUT_03
15
+ kind: mcp
16
+ mcp_id: mcp2
17
+ pin: 5
18
+ output_type: light
19
+
20
+ - id: OUT_04
21
+ kind: mcp
22
+ mcp_id: mcp2
23
+ pin: 4
24
+ output_type: light
25
+
26
+ - id: OUT_05
27
+ kind: mcp
28
+ mcp_id: mcp2
29
+ pin: 3
30
+ output_type: light
31
+
32
+ - id: OUT_06
33
+ kind: mcp
34
+ mcp_id: mcp2
35
+ pin: 2
36
+ output_type: light
37
+
38
+ - id: OUT_07
39
+ kind: mcp
40
+ mcp_id: mcp2
41
+ pin: 1
42
+ output_type: light
43
+
44
+ - id: OUT_08
45
+ kind: mcp
46
+ mcp_id: mcp2
47
+ pin: 0
48
+ output_type: light
49
+
50
+ - id: OUT_09
51
+ kind: mcp
52
+ mcp_id: mcp1
53
+ pin: 7
54
+ output_type: light
55
+
56
+ - id: OUT_10
57
+ kind: mcp
58
+ mcp_id: mcp1
59
+ pin: 6
60
+ output_type: light
61
+
62
+ - id: OUT_11
63
+ kind: mcp
64
+ mcp_id: mcp1
65
+ pin: 5
66
+ output_type: light
67
+
68
+ - id: OUT_12
69
+ kind: mcp
70
+ mcp_id: mcp1
71
+ pin: 4
72
+ output_type: light
73
+
74
+ - id: OUT_13
75
+ kind: mcp
76
+ mcp_id: mcp1
77
+ pin: 3
78
+ output_type: light
79
+
80
+ - id: OUT_14
81
+ kind: mcp
82
+ mcp_id: mcp1
83
+ pin: 2
84
+ output_type: light
85
+
86
+ - id: OUT_15
87
+ kind: mcp
88
+ mcp_id: mcp1
89
+ pin: 1
90
+ output_type: light
91
+
92
+ - id: OUT_16
93
+ kind: mcp
94
+ mcp_id: mcp1
95
+ pin: 0
96
+ output_type: light
97
+
98
+ - id: OUT_17
99
+ kind: mcp
100
+ mcp_id: mcp2
101
+ pin: 8
102
+ output_type: light
103
+
104
+ - id: OUT_18
105
+ kind: mcp
106
+ mcp_id: mcp2
107
+ pin: 9
108
+ output_type: light
109
+
110
+ - id: OUT_19
111
+ kind: mcp
112
+ mcp_id: mcp2
113
+ pin: 10
114
+ output_type: light
115
+
116
+ - id: OUT_20
117
+ kind: mcp
118
+ mcp_id: mcp2
119
+ pin: 11
120
+ output_type: light
121
+
122
+ - id: OUT_21
123
+ kind: mcp
124
+ mcp_id: mcp2
125
+ pin: 12
126
+ output_type: light
127
+
128
+ - id: OUT_22
129
+ kind: mcp
130
+ mcp_id: mcp2
131
+ pin: 13
132
+ output_type: light
133
+
134
+ - id: OUT_23
135
+ kind: mcp
136
+ mcp_id: mcp2
137
+ pin: 14
138
+ output_type: light
139
+
140
+ - id: OUT_24
141
+ kind: mcp
142
+ mcp_id: mcp2
143
+ pin: 15
144
+ output_type: light
145
+
146
+ - id: OUT_25
147
+ kind: mcp
148
+ mcp_id: mcp1
149
+ pin: 8
150
+ output_type: light
151
+
152
+ - id: OUT_26
153
+ kind: mcp
154
+ mcp_id: mcp1
155
+ pin: 9
156
+ output_type: light
157
+
158
+ - id: OUT_27
159
+ kind: mcp
160
+ mcp_id: mcp1
161
+ pin: 10
162
+ output_type: light
163
+
164
+ - id: OUT_28
165
+ kind: mcp
166
+ mcp_id: mcp1
167
+ pin: 11
168
+ output_type: light
169
+
170
+ - id: OUT_29
171
+ kind: mcp
172
+ mcp_id: mcp1
173
+ pin: 12
174
+ output_type: light
175
+
176
+ - id: OUT_30
177
+ kind: mcp
178
+ mcp_id: mcp1
179
+ pin: 13
180
+ output_type: light
181
+
182
+ - id: OUT_31
183
+ kind: mcp
184
+ mcp_id: mcp1
185
+ pin: 14
186
+ output_type: light
187
+
188
+ - id: OUT_32
189
+ kind: mcp
190
+ mcp_id: mcp1
191
+ pin: 15
192
+ output_type: light
boneio/helper/filter.py CHANGED
@@ -19,8 +19,9 @@ FILTERS = {
19
19
  class Filter:
20
20
  _filters = []
21
21
 
22
- def _apply_filters(self, value: float) -> float | None:
23
- for filter in self._filters:
22
+ def _apply_filters(self, value: float, filters: list = []) -> float | None:
23
+ filters = filters if filters else self._filters
24
+ for filter in filters:
24
25
  for k, v in filter.items():
25
26
  if k not in FILTERS:
26
27
  _LOGGER.warning(
boneio/helper/loader.py CHANGED
@@ -211,6 +211,7 @@ def create_modbus_sensors(manager: Manager, sensors, **kwargs) -> None:
211
211
  update_interval=sensor.get(
212
212
  UPDATE_INTERVAL, TimePeriod(seconds=60)
213
213
  ),
214
+ sensors_filters=sensor.get("sensors_filters", {}),
214
215
  **kwargs,
215
216
  )
216
217
  except FileNotFoundError as err:
boneio/modbus/client.py CHANGED
@@ -43,6 +43,7 @@ class Modbus:
43
43
  stopbits: int = 1,
44
44
  bytesize: int = 8,
45
45
  parity: str = "N",
46
+ timeout: float = 3,
46
47
  ) -> None:
47
48
  """Initialize the Modbus hub."""
48
49
  rx = uart.get(RX)
@@ -68,6 +69,7 @@ class Modbus:
68
69
  stopbits=stopbits,
69
70
  bytesize=bytesize,
70
71
  parity=parity,
72
+ timeout=timeout,
71
73
  )
72
74
  self._read_methods = {
73
75
  "input": self._client.read_input_registers,
boneio/modbus/cwt.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "set_address_address": 2000,
5
5
  "set_baudrate": {
6
6
  "address": 2001,
7
- "possible_baudrates": [2400, 4800, 9600, 19200]
7
+ "possible_baudrates": { "2400": 0, "4800": 1, "9600": 2, "19200": 3 }
8
8
  }
9
9
  },
10
10
  "registers_base": [
@@ -0,0 +1,37 @@
1
+ {
2
+ "model": "Liquid sensor",
3
+ "set_base": {
4
+ "set_address_address": 0,
5
+ "set_baudrate": {
6
+ "address": 1,
7
+ "possible_baudrates": {
8
+ "1200": 0,
9
+ "2400": 1,
10
+ "4800": 2,
11
+ "9600": 3,
12
+ "19200": 4,
13
+ "38400": 5,
14
+ "57600": 6,
15
+ "115200": 7
16
+ }
17
+ }
18
+ },
19
+ "registers_base": [
20
+ {
21
+ "base": 0,
22
+ "length": 2,
23
+ "register_type": "holding",
24
+ "registers": [
25
+ {
26
+ "name": "Immersion depth",
27
+ "address": 0,
28
+ "unit_of_measurement": "mm",
29
+ "state_class": "measurement",
30
+ "device_class": "humidity",
31
+ "value_type": "S_WORD",
32
+ "filters": [{ "multiply": 0.1 }]
33
+ }
34
+ ]
35
+ }
36
+ ]
37
+ }
@@ -78,7 +78,7 @@ class ModbusHelper:
78
78
 
79
79
  def set_connection_speed(self, new_baudrate: int) -> int:
80
80
  baudrate_model = self._model[SET_BAUDRATE]
81
- ind = baudrate_model["possible_baudrates"].index(new_baudrate)
81
+ ind = baudrate_model["possible_baudrates"].get(str(new_baudrate))
82
82
  if ind:
83
83
  result = self._modbus.client.write_register(
84
84
  address=baudrate_model["address"],
@@ -110,6 +110,19 @@ class ModbusHelper:
110
110
  else:
111
111
  _LOGGER.error("Invalid new address.")
112
112
 
113
+ def set_custom_command(self, register_address: int, value: int | float):
114
+ result = self._modbus.client.write_register(
115
+ address=register_address,
116
+ value=value,
117
+ unit=self._device_address,
118
+ )
119
+ if result.isError():
120
+ _LOGGER.error("Operation failed.")
121
+ else:
122
+ _LOGGER.info(
123
+ "Operation succeeded. Now restart device by disconnecting it."
124
+ )
125
+
113
126
 
114
127
  async def async_run_modbus_set(
115
128
  device: str,
@@ -118,6 +131,8 @@ async def async_run_modbus_set(
118
131
  baudrate: int,
119
132
  new_baudrate: int,
120
133
  new_address: int,
134
+ custom_address: int,
135
+ custom_value: int,
121
136
  stopbits: int = 1,
122
137
  bytesize: int = 8,
123
138
  parity: str = "N",
@@ -125,15 +140,21 @@ async def async_run_modbus_set(
125
140
  """Run Modbus Set Function."""
126
141
  if new_address and new_baudrate:
127
142
  _LOGGER.error("Can't set both methods new_address and new_baudrate.")
128
- _db = open_json(path=os.path.dirname(__file__), model=device)
129
- set_base = _db.get(SET_BASE, {})
130
- first_reg_base = _db.get(REGISTERS_BASE, [])[0]
131
- if not first_reg_base:
132
- return False
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
- )
143
+ custom_cmd = True if device == "custom" else False
144
+ set_base = {}
145
+ if not custom_cmd:
146
+ _db = open_json(path=os.path.dirname(__file__), model=device)
147
+ set_base = _db.get(SET_BASE, {})
148
+ first_reg_base = _db.get(REGISTERS_BASE, [])[0]
149
+ if not first_reg_base:
150
+ return False
151
+ first_record = first_reg_base.get(REGISTERS, [])[0]
152
+ _LOGGER.debug(
153
+ f"Connecting with params uart: {uart}, baudrate: {baudrate}, stopbits: {stopbits}, bytesize: {bytesize}, parity: {parity}."
154
+ )
155
+ else:
156
+ first_record = {}
157
+ first_reg_base = {}
137
158
  modbus_helper = ModbusHelper(
138
159
  device=device,
139
160
  uart=uart,
@@ -146,17 +167,69 @@ async def async_run_modbus_set(
146
167
  bytesize=bytesize,
147
168
  parity=parity,
148
169
  )
149
- if not await modbus_helper.check_connection():
150
- _LOGGER.error("Can't connect with sensor. Exiting")
151
- return 1
152
- if new_baudrate:
153
- return modbus_helper.set_connection_speed(new_baudrate=new_baudrate)
154
- if new_address:
155
- modbus_helper.set_new_address(new_address=new_address)
156
- return 0
170
+
171
+ async def default_action():
172
+ if not await modbus_helper.check_connection():
173
+ _LOGGER.error("Can't connect with sensor. Exiting")
174
+ return 1
175
+ if new_baudrate:
176
+ return modbus_helper.set_connection_speed(new_baudrate=new_baudrate)
177
+ if new_address:
178
+ modbus_helper.set_new_address(new_address=new_address)
179
+ return 0
180
+
181
+ if not custom_cmd:
182
+ _LOGGER.debug("Invoking default action.")
183
+ return await default_action()
184
+ elif custom_address is not None and custom_value is not None:
185
+ _LOGGER.debug("Invoking custom command action.")
186
+ modbus_helper.set_custom_command(
187
+ register_address=custom_address, value=custom_value
188
+ )
157
189
  return 1
158
190
 
159
191
 
192
+ async def async_run_modbus_search(
193
+ uart: str,
194
+ baudrate: int,
195
+ register_address: int,
196
+ register_type: str = "holding",
197
+ stopbits: int = 1,
198
+ bytesize: int = 8,
199
+ parity: str = "N",
200
+ ):
201
+ """Run Modbus Seach Function."""
202
+ _modbus = Modbus(
203
+ uart=UARTS[uart],
204
+ baudrate=baudrate,
205
+ stopbits=stopbits,
206
+ bytesize=bytesize,
207
+ parity=parity,
208
+ timeout=0.1,
209
+ )
210
+ units_found = []
211
+ for unit_id in range(1, 248): # Modbus RTU address range is 1 to 247
212
+ _LOGGER.debug(f"Searching device at address {unit_id}.")
213
+ value = await _modbus.read_registers(
214
+ unit=unit_id,
215
+ address=register_address,
216
+ count=2,
217
+ method=register_type,
218
+ )
219
+ if value:
220
+ units_found.append(unit_id)
221
+ _LOGGER.info(f"Found device at address {unit_id}.")
222
+ else:
223
+ _LOGGER.debug(f"No device found at address {unit_id}.")
224
+ if units_found:
225
+ _LOGGER.info(
226
+ "Found devices: [%s]", ", ".join(str(x) for x in units_found)
227
+ )
228
+ else:
229
+ _LOGGER.info("No devices found.")
230
+ return 0
231
+
232
+
160
233
  async def async_run_modbus_get(
161
234
  uart: str,
162
235
  device_address: int,
@@ -4,7 +4,13 @@
4
4
  "set_address_address": 254,
5
5
  "set_baudrate": {
6
6
  "address": 255,
7
- "possible_baudrates": [1200, 2400, 4800, 9600, 19200]
7
+ "possible_baudrates": {
8
+ "1200": 0,
9
+ "2400": 1,
10
+ "4800": 2,
11
+ "9600": 3,
12
+ "19200": 4
13
+ }
8
14
  }
9
15
  },
10
16
  "registers_base": [
boneio/modbus/sensor.py CHANGED
@@ -4,6 +4,8 @@ import logging
4
4
  import os
5
5
  from datetime import datetime
6
6
  from typing import Optional
7
+
8
+ from boneio.helper.filter import Filter
7
9
  from .utils import CONVERT_METHODS, REGISTERS_BASE, allowed_operations
8
10
  from boneio.const import (
9
11
  ADDRESS,
@@ -26,7 +28,7 @@ from boneio.helper.util import open_json
26
28
  _LOGGER = logging.getLogger(__name__)
27
29
 
28
30
 
29
- class ModbusSensor(BasicMqtt, AsyncUpdater):
31
+ class ModbusSensor(BasicMqtt, AsyncUpdater, Filter):
30
32
  """Represent Modbus sensor in BoneIO."""
31
33
 
32
34
  SensorClass = None
@@ -37,6 +39,7 @@ class ModbusSensor(BasicMqtt, AsyncUpdater):
37
39
  modbus: Modbus,
38
40
  address: str,
39
41
  model: str,
42
+ sensors_filters: dict,
40
43
  config_helper: ConfigHelper,
41
44
  event_bus: EventBus,
42
45
  id: str = DefaultName,
@@ -56,6 +59,9 @@ class ModbusSensor(BasicMqtt, AsyncUpdater):
56
59
  self._address = address
57
60
  self._discovery_sent = False
58
61
  self._payload_online = OFFLINE
62
+ self._sensors_filters = {
63
+ k.lower(): v for k, v in sensors_filters.items()
64
+ }
59
65
  event_bus.add_haonline_listener(target=self.set_payload_offline)
60
66
  AsyncUpdater.__init__(self, **kwargs)
61
67
 
@@ -154,7 +160,9 @@ class ModbusSensor(BasicMqtt, AsyncUpdater):
154
160
  method=data.get("register_type", "input"),
155
161
  )
156
162
  if self._payload_online == OFFLINE and values:
157
- _LOGGER.info("Sending online payload about device.")
163
+ _LOGGER.info(
164
+ "Sending online payload about device %s.", self._name
165
+ )
158
166
  self._payload_online = ONLINE
159
167
  self._send_message(
160
168
  topic=f"{self._config_helper.topic_prefix}/{self._id}{STATE}",
@@ -204,6 +212,12 @@ class ModbusSensor(BasicMqtt, AsyncUpdater):
204
212
  if key in allowed_operations:
205
213
  lamda_function = allowed_operations[key]
206
214
  decoded_value = lamda_function(decoded_value, value)
215
+ name = register.get("name").replace(" ", "")
216
+ user_filters = self._sensors_filters.get(name.lower(), [])
217
+ decoded_value = self._apply_filters(
218
+ value=decoded_value,
219
+ filters=user_filters,
220
+ )
207
221
  output[register.get("name").replace(" ", "")] = decoded_value
208
222
  self._send_message(
209
223
  topic=f"{self._send_topic}/{data[BASE]}",
@@ -0,0 +1,37 @@
1
+ {
2
+ "model": "SHT20 Temp and Humidity sensor",
3
+ "set_base": {
4
+ "set_address_address": 257,
5
+ "set_baudrate": {
6
+ "address": 258,
7
+ "possible_baudrates": { "9600": 9600, "14400": 14400, "19200": 19200 }
8
+ }
9
+ },
10
+ "registers_base": [
11
+ {
12
+ "base": 1,
13
+ "length": 2,
14
+ "register_type": "input",
15
+ "registers": [
16
+ {
17
+ "name": "Temperature",
18
+ "address": 1,
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": "Humidity",
27
+ "address": 2,
28
+ "unit_of_measurement": "%",
29
+ "state_class": "measurement",
30
+ "device_class": "humidity",
31
+ "value_type": "S_WORD",
32
+ "filters": [{ "multiply": 0.1 }]
33
+ }
34
+ ]
35
+ }
36
+ ]
37
+ }
boneio/schema/schema.yaml CHANGED
@@ -170,6 +170,14 @@ modbus_sensors:
170
170
  default: 30s
171
171
  meta:
172
172
  label: Update interval.
173
+ sensors_filters:
174
+ type: dict
175
+ required: False
176
+ meta:
177
+ label: List of sub sensors to use to filter. Available values are temperature or humidity.
178
+ schema:
179
+ temperature: !include filters.yaml
180
+ humidity: !include filters.yaml
173
181
  lm75:
174
182
  type: list
175
183
  required: False
boneio/sensor/ina219.py CHANGED
@@ -15,7 +15,7 @@ unit_converter = {"current": "A", "power": "W", "voltage": "V"}
15
15
 
16
16
 
17
17
  class INA219Sensor(BasicMqtt, Filter):
18
- """Represent singel value from INA219 as sensor."""
18
+ """Represent single value from INA219 as sensor."""
19
19
 
20
20
  def __init__(
21
21
  self, device_class: str, filters: list, state: float | None, **kwargs
@@ -52,7 +52,7 @@ class INA219Sensor(BasicMqtt, Filter):
52
52
  return self._unit_of_measurement
53
53
 
54
54
  def update(self, time: datetime) -> None:
55
- """Fetch temperature periodically and send to MQTT."""
55
+ """Fetch sensor data periodically and send to MQTT."""
56
56
  _state = (
57
57
  self._apply_filters(value=self._raw_state)
58
58
  if self._raw_state
@@ -111,4 +111,4 @@ class INA219(AsyncUpdater, Filter):
111
111
  for k, sensor in self._sensors.items():
112
112
  if sensor.raw_state != self._states[k]:
113
113
  sensor.raw_state = self._states[k]
114
- self._loop.call_soon(sensor.update, time)
114
+ self._loop.call_soon_threadsafe(sensor.update, time)
boneio/version.py CHANGED
@@ -1,2 +1,2 @@
1
1
  # flake8: noqa
2
- __version__ = "0.8.0dev7"
2
+ __version__ = "0.8.0dev9"