boneio 0.9.0.dev7__tar.gz → 0.9.0.dev8__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.9.0.dev7 → boneio-0.9.0.dev8}/PKG-INFO +1 -1
- boneio-0.9.0.dev8/boneio/boards/0.8/input.yaml +110 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/events.py +75 -23
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/gpio.py +5 -1
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/ha_discovery.py +3 -3
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/loader.py +35 -12
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/stats.py +32 -12
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/manager.py +42 -24
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/modbus/sensor.py +4 -1
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/models/__init__.py +9 -1
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/oled.py +82 -27
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/relay/basic.py +10 -5
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/relay/mcp.py +0 -5
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/relay/pcf.py +1 -7
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/schema/schema.yaml +5 -0
- boneio-0.9.0.dev8/boneio/sensor/serial_number.py +39 -0
- boneio-0.9.0.dev8/boneio/version.py +2 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/webui/app.py +7 -9
- boneio-0.9.0.dev7/boneio/webui/frontend-dist/assets/index-JxJAopze.js → boneio-0.9.0.dev8/boneio/webui/frontend-dist/assets/index-Bzix_ULo.js +14 -14
- boneio-0.9.0.dev7/boneio/webui/frontend-dist/assets/index-Bs_Dk8Uy.css → boneio-0.9.0.dev8/boneio/webui/frontend-dist/assets/index-Dt_UdFzp.css +1 -1
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/webui/frontend-dist/index.html +2 -2
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/webui/web_server.py +2 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/pyproject.toml +2 -1
- boneio-0.9.0.dev7/boneio/version.py +0 -2
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/LICENSE +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/README.md +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/__init__.py +0 -0
- {boneio-0.9.0.dev7/boneio/boards/0.8 → boneio-0.9.0.dev8/boneio/boards/0.7}/input.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/boards/0.7/output_32_10.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/boards/0.8/output_32_10.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/bonecli.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/const.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/cover.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/example_config/__init__.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/example_config/adc.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/example_config/binary_sensor.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/example_config/binary_sensor_v_0_7.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/example_config/config.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/example_config/cover.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/example_config/event.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/example_config/event_all.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/example_config/event_v_0_7.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/example_config/led32x4A.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/example_config/output24x16A.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/example_config/output24x16A_v0.3.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/example_config/output32x10A.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/example_config/output32x5A.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/fonts/danube__.ttf +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/group/__init__.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/group/output.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/__init__.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/async_updater.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/click_timer.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/config.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/exceptions.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/filter.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/gpiod.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/logger.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/message_bus.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/mqtt.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/oled.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/onewire/W1ThermSensor.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/onewire/__init__.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/onewire/ds2482.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/onewire/onewire.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/pcf8575.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/queue.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/sensor/ina_219_smbus.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/state_manager.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/timeperiod.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/util.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/helper/yaml_util.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/input/__init__.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/input/gpio.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/input/gpio_new.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/modbus/__init__.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/modbus/client.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/modbus/cwt.json +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/modbus/dts1964_3f.json +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/modbus/liquid-sensor.json +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/modbus/modbuscli.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/modbus/orno-or-we-517.json +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/modbus/pt100.json +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/modbus/r4dcb08.json +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/modbus/sdm120.json +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/modbus/sdm630.json +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/modbus/sht20.json +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/modbus/sht30.json +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/modbus/single_sensor.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/modbus/socomec_e03.json +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/modbus/socomec_e23.json +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/modbus/sofar.json +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/modbus/utils.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/models/files.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/models/logs.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/mqtt_client.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/relay/__init__.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/relay/gpio.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/relay/pca.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/runner.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/schema/actions.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/schema/actions_sensor.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/schema/actions_switch.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/schema/filters.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/schema/filters_adc.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/schema/id.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/schema/temp_unit.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/schema/update_interval.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/sensor/__init__.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/sensor/adc.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/sensor/gpio.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/sensor/gpio_new.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/sensor/ina219.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/sensor/temp/__init__.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/sensor/temp/dallas.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/sensor/temp/lm75.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/sensor/temp/mcp9808.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/webui/frontend-dist/assets/css.worker-YzWC8yAR.js +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/webui/frontend-dist/assets/editor.worker-D5ngByhL.js +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/webui/frontend-dist/assets/html.worker-D5NPIcdM.js +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/webui/frontend-dist/assets/json.worker-F0ZGA5Zk.js +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/webui/frontend-dist/assets/ts.worker-BSchkg-h.js +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/webui/frontend-dist/boneio.svg +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/webui/frontend-dist/boneio_fav.svg +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/boneio/webui/websocket_manager.py +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/tests/32_5_config.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/tests/bandit.yaml +0 -0
- {boneio-0.9.0.dev7 → boneio-0.9.0.dev8}/tests/relay_32_5.py +0 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
input_mapping:
|
|
2
|
+
in_01:
|
|
3
|
+
pin: P8_37
|
|
4
|
+
gpio_mode: gpio_pu
|
|
5
|
+
in_02:
|
|
6
|
+
pin: P8_38
|
|
7
|
+
gpio_mode: gpio_pu
|
|
8
|
+
in_03:
|
|
9
|
+
pin: P8_39
|
|
10
|
+
in_04:
|
|
11
|
+
pin: P8_40
|
|
12
|
+
in_05:
|
|
13
|
+
pin: P8_41
|
|
14
|
+
in_06:
|
|
15
|
+
pin: P8_42
|
|
16
|
+
in_07:
|
|
17
|
+
pin: P8_43
|
|
18
|
+
in_08:
|
|
19
|
+
pin: P8_44
|
|
20
|
+
in_09:
|
|
21
|
+
pin: P8_45
|
|
22
|
+
in_10:
|
|
23
|
+
pin: P8_46
|
|
24
|
+
gpio_mode: gpio_pu
|
|
25
|
+
in_11:
|
|
26
|
+
pin: P9_42
|
|
27
|
+
in_12:
|
|
28
|
+
pin: P9_31
|
|
29
|
+
in_13:
|
|
30
|
+
pin: P9_30
|
|
31
|
+
in_14:
|
|
32
|
+
pin: P9_29
|
|
33
|
+
in_15:
|
|
34
|
+
pin: P9_28
|
|
35
|
+
in_16:
|
|
36
|
+
pin: P9_27
|
|
37
|
+
in_17:
|
|
38
|
+
pin: P9_25
|
|
39
|
+
in_18:
|
|
40
|
+
pin: P9_23
|
|
41
|
+
in_19:
|
|
42
|
+
pin: P9_22
|
|
43
|
+
gpio_mode: gpio_pu
|
|
44
|
+
in_20:
|
|
45
|
+
pin: P9_21
|
|
46
|
+
gpio_mode: gpio_pu
|
|
47
|
+
in_21:
|
|
48
|
+
pin: P9_18
|
|
49
|
+
in_22:
|
|
50
|
+
pin: P9_17
|
|
51
|
+
in_23:
|
|
52
|
+
pin: P9_16
|
|
53
|
+
in_24:
|
|
54
|
+
pin: P9_15
|
|
55
|
+
in_25:
|
|
56
|
+
pin: P9_14
|
|
57
|
+
in_26:
|
|
58
|
+
pin: P8_7
|
|
59
|
+
in_27:
|
|
60
|
+
pin: P8_8
|
|
61
|
+
in_28:
|
|
62
|
+
pin: P8_9
|
|
63
|
+
in_29:
|
|
64
|
+
pin: P8_36
|
|
65
|
+
gpio_mode: gpio_pu
|
|
66
|
+
in_30:
|
|
67
|
+
pin: P8_35
|
|
68
|
+
gpio_mode: gpio_pu
|
|
69
|
+
in_31:
|
|
70
|
+
pin: P8_34
|
|
71
|
+
gpio_mode: gpio_pu
|
|
72
|
+
in_32:
|
|
73
|
+
pin: P8_33
|
|
74
|
+
gpio_mode: gpio_pu
|
|
75
|
+
in_33:
|
|
76
|
+
pin: P8_32
|
|
77
|
+
gpio_mode: gpio_pu
|
|
78
|
+
in_34:
|
|
79
|
+
pin: P8_31
|
|
80
|
+
gpio_mode: gpio_pu
|
|
81
|
+
in_35:
|
|
82
|
+
pin: P8_30
|
|
83
|
+
in_36:
|
|
84
|
+
pin: P8_29
|
|
85
|
+
in_37:
|
|
86
|
+
pin: P8_28
|
|
87
|
+
in_38:
|
|
88
|
+
pin: P8_27
|
|
89
|
+
in_39:
|
|
90
|
+
pin: P8_26
|
|
91
|
+
in_40:
|
|
92
|
+
pin: P8_19
|
|
93
|
+
in_41:
|
|
94
|
+
pin: P8_18
|
|
95
|
+
in_42:
|
|
96
|
+
pin: P8_17
|
|
97
|
+
in_43:
|
|
98
|
+
pin: P8_16
|
|
99
|
+
in_44:
|
|
100
|
+
pin: P8_15
|
|
101
|
+
in_45:
|
|
102
|
+
pin: P8_14
|
|
103
|
+
in_46:
|
|
104
|
+
pin: P8_13
|
|
105
|
+
in_47:
|
|
106
|
+
pin: P8_12
|
|
107
|
+
in_48:
|
|
108
|
+
pin: P8_11
|
|
109
|
+
in_49:
|
|
110
|
+
pin: P8_10
|
|
@@ -86,7 +86,15 @@ class EventBus:
|
|
|
86
86
|
self._loop = loop or asyncio.get_event_loop()
|
|
87
87
|
self._every_second_listeners = {}
|
|
88
88
|
self._output_listeners = {}
|
|
89
|
-
self._event_listeners = {
|
|
89
|
+
self._event_listeners = {
|
|
90
|
+
"input": {},
|
|
91
|
+
"output": {},
|
|
92
|
+
"modbus_sensor": {},
|
|
93
|
+
"sensor": {},
|
|
94
|
+
"host": {}
|
|
95
|
+
}
|
|
96
|
+
# Index to track listener_ids across all event types
|
|
97
|
+
self._listener_id_index = {}
|
|
90
98
|
self._sigterm_listeners = []
|
|
91
99
|
self._haonline_listeners = []
|
|
92
100
|
self._timer_handle = _async_create_timer(
|
|
@@ -188,7 +196,7 @@ class EventBus:
|
|
|
188
196
|
"""Add sigterm listener."""
|
|
189
197
|
self._sigterm_listeners.append(target)
|
|
190
198
|
|
|
191
|
-
def add_output_listener(self, output_id, listener_id, target):
|
|
199
|
+
def add_output_listener(self, output_id, listener_id, target) -> ListenerJob:
|
|
192
200
|
"""Add output listener.
|
|
193
201
|
|
|
194
202
|
listener_id is typically group_id for group outputs or ws (websocket)
|
|
@@ -200,7 +208,7 @@ class EventBus:
|
|
|
200
208
|
listener.set_target(target)
|
|
201
209
|
return listener
|
|
202
210
|
self._output_listeners[output_id][listener_id] = ListenerJob(target=target)
|
|
203
|
-
return self._output_listeners[output_id]
|
|
211
|
+
return self._output_listeners[output_id][listener_id]
|
|
204
212
|
|
|
205
213
|
def remove_output_listener(self, output_id, listener_id):
|
|
206
214
|
"""Add output listener.
|
|
@@ -215,36 +223,80 @@ class EventBus:
|
|
|
215
223
|
for listener in listeners.values():
|
|
216
224
|
await listener.target(event)
|
|
217
225
|
|
|
218
|
-
def
|
|
219
|
-
"""
|
|
226
|
+
async def async_trigger_event(self, event_type: str, entity_id: str, event: Any):
|
|
227
|
+
"""Trigger event for all listeners of given type and entity."""
|
|
228
|
+
listeners = self._event_listeners.get(event_type, {}).get(entity_id, {})
|
|
229
|
+
for listener in listeners.values():
|
|
230
|
+
await listener.target(event)
|
|
231
|
+
|
|
232
|
+
def add_event_listener(
|
|
233
|
+
self, event_type: str, entity_id: str, listener_id: str, target
|
|
234
|
+
) -> ListenerJob:
|
|
235
|
+
"""Add event listener.
|
|
220
236
|
|
|
221
237
|
listener_id is typically group_id for group outputs or ws (websocket)
|
|
222
238
|
"""
|
|
223
|
-
if
|
|
224
|
-
|
|
239
|
+
if not target:
|
|
240
|
+
return
|
|
225
241
|
if entity_id not in self._event_listeners[event_type]:
|
|
226
242
|
self._event_listeners[event_type][entity_id] = {}
|
|
227
243
|
if listener_id in self._event_listeners[event_type][entity_id]:
|
|
228
244
|
listener = self._event_listeners[event_type][entity_id][listener_id]
|
|
229
245
|
listener.set_target(target)
|
|
230
246
|
return listener
|
|
231
|
-
self._event_listeners[event_type][entity_id][listener_id] = ListenerJob(target=target)
|
|
232
|
-
return self._event_listeners[event_type][entity_id][listener_id]
|
|
233
247
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
+
# Add to main listeners
|
|
249
|
+
listener_job = ListenerJob(target=target)
|
|
250
|
+
self._event_listeners[event_type][entity_id][listener_id] = listener_job
|
|
251
|
+
|
|
252
|
+
# Add to index
|
|
253
|
+
if listener_id not in self._listener_id_index:
|
|
254
|
+
self._listener_id_index[listener_id] = []
|
|
255
|
+
self._listener_id_index[listener_id].append((event_type, entity_id))
|
|
256
|
+
|
|
257
|
+
return listener_job
|
|
258
|
+
|
|
259
|
+
def remove_event_listener(self, event_type: str = None, entity_id: str = None, listener_id: str = None) -> None:
|
|
260
|
+
"""Remove event listener. Can remove by event_type, listener_id, or both."""
|
|
261
|
+
if listener_id and listener_id in self._listener_id_index:
|
|
262
|
+
# Remove by listener_id
|
|
263
|
+
for evt_type, ent_id in self._listener_id_index[listener_id]:
|
|
264
|
+
if event_type and evt_type != event_type:
|
|
265
|
+
continue
|
|
266
|
+
if entity_id and ent_id != entity_id:
|
|
267
|
+
continue
|
|
268
|
+
if ent_id in self._event_listeners[evt_type]:
|
|
269
|
+
if listener_id in self._event_listeners[evt_type][ent_id]:
|
|
270
|
+
del self._event_listeners[evt_type][ent_id][listener_id]
|
|
271
|
+
if not self._event_listeners[evt_type][ent_id]:
|
|
272
|
+
del self._event_listeners[evt_type][ent_id]
|
|
273
|
+
|
|
274
|
+
if event_type is None and entity_id is None:
|
|
275
|
+
# If removing all references to this listener_id
|
|
276
|
+
del self._listener_id_index[listener_id]
|
|
277
|
+
else:
|
|
278
|
+
# Update index to remove only specific references
|
|
279
|
+
self._listener_id_index[listener_id] = [
|
|
280
|
+
(evt_type, ent_id)
|
|
281
|
+
for evt_type, ent_id in self._listener_id_index[listener_id]
|
|
282
|
+
if (event_type and evt_type != event_type) or (entity_id and ent_id != entity_id)
|
|
283
|
+
]
|
|
284
|
+
if not self._listener_id_index[listener_id]:
|
|
285
|
+
del self._listener_id_index[listener_id]
|
|
286
|
+
|
|
287
|
+
elif event_type:
|
|
288
|
+
# Remove by event_type
|
|
289
|
+
if entity_id:
|
|
290
|
+
# Remove specific entity
|
|
291
|
+
if entity_id in self._event_listeners[event_type]:
|
|
292
|
+
for lid in list(self._event_listeners[event_type][entity_id].keys()):
|
|
293
|
+
self.remove_event_listener(event_type, entity_id, lid)
|
|
294
|
+
del self._event_listeners[event_type][entity_id]
|
|
295
|
+
else:
|
|
296
|
+
# Remove entire event_type
|
|
297
|
+
for ent_id in list(self._event_listeners[event_type].keys()):
|
|
298
|
+
for lid in list(self._event_listeners[event_type][ent_id].keys()):
|
|
299
|
+
self.remove_event_listener(event_type, ent_id, lid)
|
|
248
300
|
|
|
249
301
|
def add_haonline_listener(self, target: Callable) -> None:
|
|
250
302
|
"""Add HA Online listener."""
|
|
@@ -194,7 +194,7 @@ class GpioBaseClass:
|
|
|
194
194
|
timestamp=self.last_press_timestamp,
|
|
195
195
|
boneio_input=self.boneio_input,
|
|
196
196
|
)
|
|
197
|
-
await self._event_bus.async_trigger_event(event_type="input", entity_id=self.
|
|
197
|
+
await self._event_bus.async_trigger_event(event_type="input", entity_id=self.id, event=event)
|
|
198
198
|
|
|
199
199
|
def set_actions(self, actions: dict) -> None:
|
|
200
200
|
self._actions = actions
|
|
@@ -222,6 +222,10 @@ class GpioBaseClass:
|
|
|
222
222
|
"""Return configured pin."""
|
|
223
223
|
return self._pin
|
|
224
224
|
|
|
225
|
+
@property
|
|
226
|
+
def id(self) -> str:
|
|
227
|
+
return self._pin
|
|
228
|
+
|
|
225
229
|
@property
|
|
226
230
|
def last_state(self) -> str:
|
|
227
231
|
return self._last_state
|
|
@@ -3,19 +3,19 @@ from boneio.const import (
|
|
|
3
3
|
CLOSED,
|
|
4
4
|
CLOSING,
|
|
5
5
|
COVER,
|
|
6
|
+
DOUBLE,
|
|
6
7
|
INPUT,
|
|
7
8
|
INPUT_SENSOR,
|
|
9
|
+
LONG,
|
|
8
10
|
OFF,
|
|
9
11
|
ON,
|
|
10
12
|
OPEN,
|
|
11
13
|
OPENING,
|
|
12
14
|
RELAY,
|
|
13
15
|
SENSOR,
|
|
16
|
+
SINGLE,
|
|
14
17
|
STATE,
|
|
15
18
|
STOP,
|
|
16
|
-
SINGLE,
|
|
17
|
-
DOUBLE,
|
|
18
|
-
LONG
|
|
19
19
|
)
|
|
20
20
|
from boneio.version import __version__
|
|
21
21
|
|
|
@@ -56,7 +56,10 @@ from boneio.helper import (
|
|
|
56
56
|
ha_sensor_temp_availabilty_message,
|
|
57
57
|
)
|
|
58
58
|
from boneio.helper.events import EventBus
|
|
59
|
-
from boneio.helper.ha_discovery import
|
|
59
|
+
from boneio.helper.ha_discovery import (
|
|
60
|
+
ha_cover_availabilty_message,
|
|
61
|
+
ha_sensor_availabilty_message,
|
|
62
|
+
)
|
|
60
63
|
from boneio.helper.onewire import (
|
|
61
64
|
DS2482,
|
|
62
65
|
DS2482_ADDRESS,
|
|
@@ -67,12 +70,12 @@ from boneio.helper.onewire import (
|
|
|
67
70
|
from boneio.helper.pcf8575 import PCF8575
|
|
68
71
|
from boneio.helper.timeperiod import TimePeriod
|
|
69
72
|
from boneio.input import GpioEventButtonNew, GpioEventButtonOld
|
|
70
|
-
from boneio.models import OutputState
|
|
71
73
|
from boneio.sensor import (
|
|
72
74
|
DallasSensorDS2482,
|
|
73
75
|
GpioInputBinarySensorNew,
|
|
74
76
|
GpioInputBinarySensorOld,
|
|
75
77
|
)
|
|
78
|
+
from boneio.sensor.serial_number import SerialNumberSensor
|
|
76
79
|
from boneio.sensor.temp.dallas import DallasSensorW1
|
|
77
80
|
|
|
78
81
|
# Typing imports that create a circular dependency
|
|
@@ -166,6 +169,27 @@ def create_temp_sensor(
|
|
|
166
169
|
pass
|
|
167
170
|
|
|
168
171
|
|
|
172
|
+
def create_serial_number_sensor(
|
|
173
|
+
manager: Manager,
|
|
174
|
+
topic_prefix: str,
|
|
175
|
+
):
|
|
176
|
+
"""Create Serial number sensor in manager."""
|
|
177
|
+
sensor = SerialNumberSensor(
|
|
178
|
+
id="serial_number",
|
|
179
|
+
name="Serial number",
|
|
180
|
+
manager=manager,
|
|
181
|
+
send_message=manager.send_message,
|
|
182
|
+
topic_prefix=topic_prefix,
|
|
183
|
+
)
|
|
184
|
+
manager.send_ha_autodiscovery(
|
|
185
|
+
id="serial_number",
|
|
186
|
+
name="Serial number",
|
|
187
|
+
ha_type=SENSOR,
|
|
188
|
+
entity_category="diagnostic",
|
|
189
|
+
availability_msg_func=ha_sensor_availabilty_message,
|
|
190
|
+
)
|
|
191
|
+
return sensor
|
|
192
|
+
|
|
169
193
|
expander_class = {MCP: MCP23017, PCA: PCA9685, PCF: PCF8575}
|
|
170
194
|
|
|
171
195
|
|
|
@@ -275,12 +299,11 @@ def configure_relay(
|
|
|
275
299
|
topic_prefix: str,
|
|
276
300
|
relay_id: str,
|
|
277
301
|
name: str,
|
|
278
|
-
relay_callback: Callable,
|
|
279
302
|
config: dict,
|
|
303
|
+
restore_state: bool = False,
|
|
280
304
|
**kwargs,
|
|
281
305
|
) -> Any:
|
|
282
306
|
"""Configure kind of relay. Most common MCP."""
|
|
283
|
-
restore_state = config.pop(RESTORE_STATE, False)
|
|
284
307
|
output_type = config.pop(OUTPUT_TYPE)
|
|
285
308
|
restored_state = (
|
|
286
309
|
state_manager.get(attr_type=RELAY, attr=relay_id, default_value=False)
|
|
@@ -342,13 +365,13 @@ def configure_relay(
|
|
|
342
365
|
)
|
|
343
366
|
return
|
|
344
367
|
|
|
345
|
-
# Create async callback wrapper
|
|
346
|
-
async def relay_callback_wrapper(event: OutputState):
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
368
|
+
# # Create async callback wrapper
|
|
369
|
+
# async def relay_callback_wrapper(event: OutputState):
|
|
370
|
+
# await relay_callback(
|
|
371
|
+
# expander_id=expander_id,
|
|
372
|
+
# event=event,
|
|
373
|
+
# restore_state=False if output_type == NONE else restore_state,
|
|
374
|
+
# )
|
|
352
375
|
|
|
353
376
|
relay = getattr(output, "OutputClass")(
|
|
354
377
|
send_message=manager.send_message,
|
|
@@ -359,7 +382,7 @@ def configure_relay(
|
|
|
359
382
|
**config,
|
|
360
383
|
**kwargs,
|
|
361
384
|
**extra_args,
|
|
362
|
-
callback=relay_callback_wrapper,
|
|
385
|
+
# callback=relay_callback_wrapper,
|
|
363
386
|
)
|
|
364
387
|
manager.grouped_outputs[expander_id][relay_id] = relay
|
|
365
388
|
return relay
|
|
@@ -4,7 +4,6 @@ import asyncio
|
|
|
4
4
|
import logging
|
|
5
5
|
import socket
|
|
6
6
|
import time
|
|
7
|
-
from functools import partial
|
|
8
7
|
from math import floor
|
|
9
8
|
|
|
10
9
|
# Typing imports that create a circular dependency
|
|
@@ -28,7 +27,9 @@ from boneio.const import (
|
|
|
28
27
|
SWAP,
|
|
29
28
|
UPTIME,
|
|
30
29
|
)
|
|
30
|
+
from boneio.helper.events import EventBus
|
|
31
31
|
from boneio.helper.gpio import GpioBaseClass
|
|
32
|
+
from boneio.models import HostSensorState
|
|
32
33
|
|
|
33
34
|
if TYPE_CHECKING:
|
|
34
35
|
from boneio.manager import Manager
|
|
@@ -124,8 +125,8 @@ class HostSensor(AsyncUpdater):
|
|
|
124
125
|
|
|
125
126
|
def __init__(
|
|
126
127
|
self,
|
|
128
|
+
event_bus: EventBus,
|
|
127
129
|
update_function: Callable,
|
|
128
|
-
manager_callback: Callable,
|
|
129
130
|
static_data: dict | None,
|
|
130
131
|
id: str,
|
|
131
132
|
type: str,
|
|
@@ -135,16 +136,21 @@ class HostSensor(AsyncUpdater):
|
|
|
135
136
|
self._static_data = static_data
|
|
136
137
|
self._state = {}
|
|
137
138
|
self._type = type
|
|
138
|
-
self.
|
|
139
|
+
self._event_bus = event_bus
|
|
139
140
|
self._loop = asyncio.get_event_loop()
|
|
140
141
|
self.id = id
|
|
141
142
|
super().__init__(**kwargs)
|
|
143
|
+
self._loop.create_task(self.async_update(time.time()))
|
|
142
144
|
|
|
143
145
|
async def async_update(self, timestamp: float) -> None:
|
|
144
146
|
self._state = self._update_function()
|
|
145
|
-
|
|
146
|
-
|
|
147
|
+
sensor_state = HostSensorState(
|
|
148
|
+
id=self.id,
|
|
149
|
+
name=self._type,
|
|
150
|
+
state="new_state", #doesn't matter here, as we fetch everything in Oled.
|
|
151
|
+
timestamp=timestamp,
|
|
147
152
|
)
|
|
153
|
+
await self._event_bus.async_trigger_event(event_type="host", entity_id=self.id, event=sensor_state)
|
|
148
154
|
|
|
149
155
|
@property
|
|
150
156
|
def state(self) -> dict:
|
|
@@ -160,14 +166,15 @@ class HostData:
|
|
|
160
166
|
self,
|
|
161
167
|
output: dict,
|
|
162
168
|
inputs: dict[str, GpioBaseClass],
|
|
163
|
-
callback: Callable,
|
|
164
169
|
temp_sensor: Callable[[LM75Sensor, MCP9808Sensor], None] | None,
|
|
165
170
|
ina219: INA219Class | None,
|
|
166
171
|
manager: Manager,
|
|
172
|
+
event_bus: EventBus,
|
|
167
173
|
enabled_screens: List[str],
|
|
168
174
|
extra_sensors: List[dict],
|
|
169
175
|
) -> None:
|
|
170
176
|
"""Initialize HostData."""
|
|
177
|
+
self._manager = manager
|
|
171
178
|
self._hostname = socket.gethostname()
|
|
172
179
|
self._temp_sensor = temp_sensor
|
|
173
180
|
host_stats = {
|
|
@@ -293,8 +300,8 @@ class HostData:
|
|
|
293
300
|
self._data[k] = HostSensor(
|
|
294
301
|
update_function=_v["f"],
|
|
295
302
|
static_data=_v.get("static"),
|
|
303
|
+
event_bus=event_bus,
|
|
296
304
|
manager=manager,
|
|
297
|
-
manager_callback=callback,
|
|
298
305
|
id=f"{k}_hoststats",
|
|
299
306
|
type=k,
|
|
300
307
|
update_interval=_v["update_interval"],
|
|
@@ -306,31 +313,44 @@ class HostData:
|
|
|
306
313
|
]
|
|
307
314
|
for i in range((len(inputs) + 24) // 25)
|
|
308
315
|
}
|
|
309
|
-
self._callback = callback
|
|
310
316
|
self._loop = asyncio.get_running_loop()
|
|
311
317
|
|
|
318
|
+
def web_url(self) -> str | None:
|
|
319
|
+
if not self._manager.is_web_on:
|
|
320
|
+
return None
|
|
321
|
+
network_state = self._data[NETWORK].state
|
|
322
|
+
if IP in network_state:
|
|
323
|
+
return f"http://{network_state[IP]}:{self._manager.web_bind_port}"
|
|
324
|
+
return None
|
|
325
|
+
|
|
312
326
|
def get(self, type: str) -> dict:
|
|
313
327
|
"""Get saved stats."""
|
|
314
328
|
if type in self._output:
|
|
315
329
|
return self._get_output(type)
|
|
316
330
|
if type in self._inputs:
|
|
317
331
|
return self._get_input(type)
|
|
332
|
+
if type == "web":
|
|
333
|
+
return self.web_url()
|
|
318
334
|
return self._data[type].state
|
|
319
335
|
|
|
320
336
|
def _get_output(self, type: str) -> dict:
|
|
321
337
|
"""Get stats for output."""
|
|
322
338
|
out = {}
|
|
323
339
|
for output in self._output[type].values():
|
|
324
|
-
out[output.id] =
|
|
340
|
+
out[output.id] = {
|
|
341
|
+
"name": output.name, "state": output.state
|
|
342
|
+
}
|
|
343
|
+
|
|
325
344
|
return out
|
|
326
345
|
|
|
327
346
|
def _get_input(self, type: str) -> dict:
|
|
328
347
|
"""Get stats for input."""
|
|
329
348
|
inputs = {}
|
|
330
349
|
for input in self._inputs[type]:
|
|
331
|
-
inputs[input.
|
|
332
|
-
|
|
333
|
-
|
|
350
|
+
inputs[input.id] = {
|
|
351
|
+
"name": input.name,
|
|
352
|
+
"state": input.last_state[0].upper() if input.last_state and input.last_state != "Unknown" else ""
|
|
353
|
+
}
|
|
334
354
|
return inputs
|
|
335
355
|
|
|
336
356
|
@property
|