├── .gitignore
├── LICENSE.md
├── README-EN.md
├── README.md
├── components
└── aux_ac
│ ├── __init__.py
│ ├── automation.h
│ ├── aux_ac.h
│ └── climate.py
├── docs
├── AC_TESTED.md
├── HARDWARE-EN.md
├── HARDWARE.md
├── HOW_TO_FEATURE_REQUEST-EN.md
└── HOW_TO_FEATURE_REQUEST.md
├── enclosure
├── JST SM connector
│ ├── pin-cap.stl
│ ├── pin-cover.stl
│ └── pin-main.stl
└── case
│ ├── aircon_cap.stl
│ └── aircon_case.stl
├── examples
├── advanced
│ ├── .gitignore
│ ├── ac_common.yaml
│ ├── ac_kitchen.yaml
│ └── ac_livingroom.yaml
└── simple
│ ├── .gitignore
│ └── aux_ac_simple.yaml
├── images
├── DD4012SA.jpg
├── USB-pinout.png
├── assembled.JPG
├── connections.png
├── connector.JPG
├── esp-12e.jpg
├── real-1.JPG
├── real-2.JPG
├── real-3.JPG
└── scheme.png
└── tests
├── .gitignore
├── ac_send_packet_for_engineer.py
├── test-ext-esp32.yaml
├── test-ext-for-engineer.yaml
├── test-ext-power-limit.yaml
├── test-local-airflow-dir.yaml
├── test-local-power-limit.yaml
├── test-local.yaml
└── test-minimal.yaml
/.gitignore:
--------------------------------------------------------------------------------
1 | # Gitignore settings for ESPHome
2 | # This is an example and may include too much for your use-case.
3 | # You can modify this file to suit your needs.
4 | **/.vscode/
5 | **/.esphome/
6 | **/.pioenvs/
7 | **/.piolibdeps/
8 | **/lib/
9 | **/src/
10 | **/platformio.ini
11 | **/secrets.yaml
12 | **/livingroom_ac/
13 | **/kitchen_ac/
14 | /examples/*/*.h
15 | **/tests/test_*
16 | **/__pycache__
17 | **/private/
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # AUX AC component License
2 |
3 | Copyright (c) 2021 GrKoR
4 | https://github.com/GrKoR/
5 |
6 | AUX_AC is published under the GPLv3 license ([EN](https://www.gnu.org/licenses/gpl-3.0.en.html), [RU](https://www.gnu.org/licenses/gpl-3.0.ru.html)).
7 |
--------------------------------------------------------------------------------
/README-EN.md:
--------------------------------------------------------------------------------
1 | # ESPHome AUX air conditioner custom component (aux_ac) #
2 | For communication about this project [please join this telegram chat](https://t.me/aux_ac).
3 |
4 | For issues or feature requests, please go to [the issue section](https://github.com/GrKoR/esphome_aux_ac_component/issues). It will be perfect if you attach log to your issue. Log you can collect with [this python script](https://github.com/GrKoR/ac_python_logger). It helps you to save all data frames from the UART bus to a csv-file. This log combined with the detailed situation description will significantly speed up bug correction.
5 | There is also a [detailed instruction describing how to properly request a feature](docs/HOW_TO_FEATURE_REQUEST-EN.md).
6 |
7 | ## DISCLAIMER ##
8 | 1. All data of this project (software, firmware, schemes, 3d-models etc.) are provided **'AS IS'**. Everything you do with your devices, you are doing at your own risk. If you don't strongly understand what you are doing, just buy Wi-Fi module from your air conditioner manufacturer.
9 | 2. I am not a programmer. So source code is certainly not optimal and badly decorated (but there are a lot of comments in it; sorry, a significant part of it is in Russian). Also, code may be written unsafe. I tried to test all parts of the code, but I'm sure I missed a lot of things. So treat it with suspicion, expect a trick from it, and if you discover something wrong write an issue here.
10 | 3. Russian and English readme files are substantially identical in meaning. But in case of differences, the [Russian](https://github.com/GrKoR/esphome_aux_ac_component#readme) version is more significant.
11 |
12 | ## Short description ##
13 | This custom component allows you to control your air conditioner through Wi-Fi if it is made in the AUX factory.
14 | Component tested with ESPHome 1.18.0 and Rovex ALS1 air conditioner. It looks like many other air conditioners can be controlled by `aux_ac`, but this possibility isn't tested. See list of tested ACs below for more details.
15 |
16 |
17 | ## Supported air conditioners ##
18 | AUX is one of the OEM air conditioner manufacturers. AUX produce ACs for many brands.
19 | There is the following list of AUX-based air conditioner on the internet: AUX, Abion, AC ELECTRIC, Almacom, Ballu, Centek, Climer, DAX, Energolux, ERISSON, Green Energy, Hyundai, IGC, Kentatsu (some series only), Klimaire, KOMANCHI, LANZKRAFT, LEBERG, LGen, Monroe, Neoclima, NEOLINE, One Air, Pioneer (until 2016), Roda, Rovex, Royal Clima, SAKATA, Samurai, SATURN, Scarlett, SmartWay, Soling, Subtropic, SUBTROPIC, Supra, Timberk, Vertex, Zanussi. There are doubts about its completeness and reliability, but nothing better could be found.
20 |
21 | ### List of compatible ACs (tested) ###
22 | [The list of tested ACs](docs/AC_TESTED.md) is placed in a separate file and includes tested by the author or by users ACs. This list is permanently updated, mainly based on feedback from users in [Telegram chat](https://t.me/aux_ac).
23 |
24 | ### If your AC is not in the list ###
25 | 1. If your AC is listed above, you should take a closer look at `aux_ac`.
26 | 2. If something about AUX is written on the nameplate of the air conditioner in the manufacturer line.
27 | 3. If the User Manual of your HVAC describes connection to Wi-Fi with mobile app ACFreedom it seems you may go deeper with `aux_ac`. But try all soft and hardware for your own risk. You must clearly understand what you are doing.
28 | 4. If the manufacturer of your AC offers a CTTM-40X24-WIFI-AKS Wi-Fi module (left) or the one in the photo on the right for control. Moreover, the right module can be either with a USB connector or with a 5-pin connector.
29 |
30 |
31 | If you are unsure, it is better to wait while other users will test your model of AC (maybe never). Or please [go to telegram-chat](https://t.me/aux_ac) with your questions. Maybe you will get help there.
32 | If you have tested your air conditioner and `aux_ac` works with it, please let me know about it. I'll add this info to the list of tested ACs above.
33 | The best way to report about your test results is writing a message in the [telegram](https://t.me/aux_ac) or [in the issue section](https://github.com/GrKoR/esphome_aux_ac_component/issues).
34 |
35 | ## How to use it ##
36 | For correct component operation, you need hardware and firmware. The hardware description is located [in a separate file](docs/HARDWARE-EN.md).
37 |
38 | ### Firmware: Integration aux_ac to your configuration ###
39 | You need [ESPHome](https://esphome.io) v.1.18.0 or above. `External_components` have appeared in this version. But it is better to use ESPHome v.1.20.4 or above, cause there were a lot of `external_components` errors corrected before this version.
40 |
41 | ## Installing ##
42 | 1. Declare external component. Read [the manual](https://esphome.io/components/external_components.html?highlight=external) for details.
43 | ```yaml
44 | external_components:
45 | - source:
46 | type: git
47 | url: https://github.com/GrKoR/esphome_aux_ac_component
48 | ```
49 | In case you need a specific version of the component, you can use the component declaration from the example below. The example uses version 0.2.14 of the component. You can find a list of available versions [on the GitHub tags page](https://github.com/GrKoR/esphome_aux_ac_component/tags).
50 | ```yaml
51 | external_components:
52 | - source:
53 | type: git
54 | url: https://github.com/GrKoR/esphome_aux_ac_component
55 | ref: v.0.2.14
56 | ```
57 | 2. Configure UART to communicate with air conditioner:
58 | ```yaml
59 | uart:
60 | id: ac_uart_bus
61 | # ATTENTION! For TX and RX use GPIO4 (D2) and GPIO5 (D1) for NodeMCU-like boards!
62 | # See docs for details: https://github.com/GrKoR/esphome_aux_ac_component/blob/master/docs/HARDWARE-EN.md
63 | tx_pin: GPIO1
64 | rx_pin: GPIO3
65 | baud_rate: 4800
66 | data_bits: 8
67 | parity: EVEN
68 | stop_bits: 1
69 | ```
70 | 3. **ATTENTION!** You need to disable the ESPHome logger so that it does not send its data to the air conditioner. Disabling the logger from the UART bus will not affect the logger output to the console or web server in any way.
71 | ```yaml
72 | logger:
73 | baud_rate: 0
74 | ```
75 | If for some reason you need the logger output to the UART, you can switch it to another UART. ESP8266 has two hardware UARTs: UART0 and UART1. Only UART0 suits for `aux_ac` cause only it has both TX and RX. UART1 has TX only, and it can be used by logger for output:
76 | ```yaml
77 | logger:
78 | level: DEBUG
79 | hardware_uart: UART1
80 | ```
81 |
82 | ## AUX_AC Configuration ##
83 | Minimal configuration:
84 | ```yaml
85 | climate:
86 | - platform: aux_ac
87 | name: "AC Name"
88 | ```
89 |
90 | Full configuration:
91 | ```yaml
92 | climate:
93 | - platform: aux_ac
94 | name: "AC Name"
95 | id: aux_id
96 | uart_id: ac_uart_bus
97 | period: 7s
98 | show_action: true
99 | display_inverted: false
100 | timeout: 150
101 | optimistic: true
102 | indoor_temperature:
103 | name: AC Indoor Temperature
104 | id: ac_indoor_temp
105 | accuracy_decimals: 1
106 | internal: false
107 | outdoor_temperature:
108 | name: AC Outdoor Temperature
109 | id: ac_outdoor_temp
110 | internal: false
111 | outbound_temperature:
112 | name: AC Coolant Outbound Temperature
113 | id: ac_outbound_temp
114 | internal: false
115 | inbound_temperature:
116 | name: AC Coolant Inbound Temperature
117 | id: ac_inbound_temp
118 | internal: false
119 | compressor_temperature:
120 | name: AC Compressor Temperature
121 | id: ac_strange_temp
122 | internal: false
123 | display_state:
124 | name: AC Display State
125 | id: ac_display_state
126 | internal: false
127 | defrost_state:
128 | name: AC Defrost State
129 | id: ac_defrost_state
130 | internal: false
131 | inverter_power:
132 | name: AC Inverter Power
133 | id: ac_inverter_power
134 | internal: false
135 | inverter_power_limit_value:
136 | name: AC Inverter Power Limit Value
137 | id: ac_inverter_power_limit_value
138 | internal: false
139 | inverter_power_limit_state:
140 | name: AC Inverter Power Limit State
141 | id: ac_inverter_power_limit_state
142 | internal: false
143 | preset_reporter:
144 | name: AC Preset Reporter
145 | id: ac_preset_reporter
146 | internal: false
147 | vlouver_state:
148 | name: AC Vertical Louvers State
149 | id: ac_vlouver_state
150 | internal: false
151 | visual:
152 | min_temperature: 16
153 | max_temperature: 32
154 | temperature_step: 1
155 | supported_modes:
156 | - HEAT_COOL
157 | - COOL
158 | - HEAT
159 | - DRY
160 | - FAN_ONLY
161 | custom_fan_modes:
162 | - MUTE
163 | - TURBO
164 | supported_presets:
165 | - SLEEP
166 | custom_presets:
167 | - CLEAN
168 | - HEALTH
169 | - ANTIFUNGUS
170 | supported_swing_modes:
171 | - VERTICAL
172 | - HORIZONTAL
173 | - BOTH
174 | ```
175 |
176 | ## Configuration variables: ##
177 |
178 | - **name** (**Required**, string): The name of the climate device. At least one of `id` or `name` is required!
179 |
180 | - **id** (*Optional*, [ID](https://esphome.io/guides/configuration-types.html#config-id)): Manually specify the ID used for code generation. At least one of `id` or `name` is required!
181 |
182 | - **uart_id** (*Optional*, [ID](https://esphome.io/guides/configuration-types.html#config-id)): Manually specify the ID of the [UART Bus](https://esphome.io/components/uart.html) if you want to use multiple UART buses.
183 |
184 | - **period** (*Optional*, [time](https://esphome.io/guides/configuration-types.html#config-time), default ``7s``): Period between status requests to the AC. `Aux_ac` will receive the new air conditioner status only after a regular request, even if you change the settings of AC using IR-remote.
185 |
186 | - **show_action** (*Optional*, boolean, default ``true``): Whether to show current action of the device (experimental). For example, in the HEAT_COOL mode, AC hardware may be in one of the following actions:
187 | - HEATING: AC is heating the air in the room;
188 | - IDLE: AC is working in the FAN mode, cause the target temperature is reached;
189 | - COOLING: AC is cooling the air.
190 | The same thing will be in HEAT or COOL modes, with the only difference of the list of actions (IDLE + HEATING or IDLE + COOLING).
191 |
192 | - **display_inverted** (*Optional*, boolean, default ``false``): It configures display driver logic level. As it turned out in the issue [#31](https://github.com/GrKoR/esphome_aux_ac_component/issues/31), different models of conditioners manage display different way. Rovex ACs powers off display by bit `1` in command packet and power it on by bit `0`. Many other conditioners do this vice versa.
193 |
194 | - **timeout** (*Optional*, unsigned integer, default ``150``): Packet timeout for `aux_ac` data receiver.
195 | In the most common use of `aux_ac`, it isn't necessary to change this value. This keyword is optional, so you may omit it.
196 | The only situation when you can play with timeout is heavily loaded ESP. When you are using your ESP for many hard tasks, it is possible that `aux_ac` does not have enough time to receive AC responses. In this case, you can slightly raise the timeout value. But the best solution would be to remove some of the tasks from the ESP.
197 | The timeout is limited to a range from `150` to `600` milliseconds. Other values are possible only with source code modification. But I don't recommend that.
198 |
199 | - **optimistic** (*Optional*, boolean, default ``true``): Whether entity states should be updated immediately after receiving a command from Home Assistant/ESPHome.
200 |
201 | - **indoor_temperature** (*Optional*): Parameters of the room air temperature sensor.
202 | - **name** (**Required**, string): The name for the temperature sensor.
203 | - **id** (*Optional*, [ID](https://esphome.io/guides/configuration-types.html#config-id)): Set the ID of this sensor for use in lambdas.
204 | - **internal** (*Optional*, boolean): Mark this component as internal. Internal components will not be exposed to the frontend (like Home Assistant). As opposed to default [Sensor](https://esphome.io/components/sensor/index.html#base-sensor-configuration) behaviour, this variable is **always true** except in cases where the user has set it directly.
205 | - All other options from [Sensor](https://esphome.io/components/sensor/index.html#base-sensor-configuration).
206 |
207 | - **outdoor_temperature** (*Optional*): Parameters of the outdoor temperature sensor. They are the same as the **indoor_temperature** (see description above).
208 | > **Attention!** When the air conditioner is turned off, the outdoor temperature is updated rarely (every 6-7 hours). This isn't a bug of the component, but a feature of the air conditioner hardware. The only way to get changes more often is to create a template sensor, the temperature of which can be changed manually. When the air conditioner is working, the value of this sensor can be copied from the **outdoor_temperature**. When the air conditioner is turned off, the temperature value should be recalculated according to the dynamics of the **outbound_temperature** sensor (it changes frequently and shows values close to the air temperature when the air conditioner is turned off). You can't copy the value of **outbound_temperature** without changes to the template sensor in AC off mode, because these temperatures are not identical.
209 |
210 | - **inbound_temperature** (*Optional*): Parameters of the coolant inbound temperature sensor. They are the same as the **indoor_temperature** (see description above).
211 |
212 | - **outbound_temperature** (*Optional*): Parameters of the coolant outbound temperature sensor. They are the same as the **indoor_temperature** (see description above).
213 |
214 | - **compressor_temperature** (*Optional*): Parameters of the compressor temperature sensor. They are the same as the **indoor_temperature** (see description above).
215 |
216 | - **display_state** (*Optional*): The information for the HVAC display state sensor (is display ON or OFF)
217 | - **name** (**Required**, string): The name for the display state sensor.
218 | - **id** (*Optional*, [ID](https://esphome.io/guides/configuration-types.html#config-id)): Set the ID of this sensor for use in lambdas.
219 | - **internal** (*Optional*, boolean): Mark this component as internal. Internal components will not be exposed to the frontend (like Home Assistant). As opposed to default [Binary Sensor](https://esphome.io/components/binary_sensor/index.html#base-binary-sensor-configuration) behavior, this variable is **always true** except in cases where the user has set it directly.
220 | - All other options from [Binary Sensor](https://esphome.io/components/binary_sensor/index.html#base-binary-sensor-configuration).
221 |
222 | - **defrost_state** (*Optional*): The information for the HVAC defrost function state sensor (is it ON or OFF). All settings are the same as for the **display_state** (see description above).
223 |
224 | - **inverter_power** (*Optional*): The information for the inverter power sensor. All settings are the same as for the **indoor_temperature** (see description above).
225 | > **ATTENTION!** The parameter name was changed in v.0.2.9 due to incorrect spelling.
226 |
227 | - **inverter_power_limit_state** (*Optional*): Configuration of the power limit state sensor. It displays the state of the power limitation function for the inverter HVAC (is it ON or OFF). All settings are the same as for the **display_state** (see description above).
228 |
229 | - **inverter_power_limit_value** (*Optional*): Configuration of the power limit value sensor. All settings are the same as for the **indoor_temperature** (see description above).
230 | It reports the current value of the power limitation function for the inverter HVAC. This sensor represents the value only after the HVAC confirms the power limitation. The value is always in the range from 30% to 100%. This is the hardware limitation.
231 |
232 | - **preset_reporter** (*Optional*): Parameters of text sensor with current preset. All settings are the same as for the **display_state** (see description above).
233 | ESPHome Climate devices are not reporting their active presets (from **supported_presets** and **custom_presets** lists) to MQTT. This behavior has been noticed at least in version 1.20.0. In case you are using MQTT and want to receive information about active preset, you should declare this sensor in your yaml.
234 |
235 | - **vlouver_state** (*Optional*): Parameters of vertical louvers state sensor. All settings are the same as for the **display_state** (see description above). The state of the vertical louvers is encoded by the integer value (see [aux_ac.vlouver_set action](#aux_ac_._vlouver_set) below).
236 |
237 | - **supported_modes** (*Optional*, list): List of supported modes. Possible values are: ``HEAT_COOL``, ``COOL``, ``HEAT``, ``DRY``, ``FAN_ONLY``. Please note: some manufacturers call AUTO mode instead of HEAT_COOL. Defaults to ``FAN_ONLY``.
238 |
239 | - **custom_fan_modes** (*Optional*, list): List of supported custom fan modes. Possible values are: ``MUTE``, ``TURBO``. No custom fan modes by default.
240 |
241 | - **supported_presets** (*Optional*, list): List of supported presets. Possible values are: ``SLEEP``. No presets by default.
242 |
243 | - **custom_presets** (*Optional*, list): List of supported custom presets. Possible values are: ``CLEAN``, ``HEALTH``, ``ANTIFUNGUS``. No custom presets by default.
244 |
245 | - **supported_swing_modes** (*Optional*, list): List of supported swing modes. Possible values are: ``VERTICAL``, ``HORIZONTAL``, ``BOTH``. No swing modes by default.
246 |
247 | - All other options from [Climate](https://esphome.io/components/climate/index.html#base-climate-configuration).
248 |
249 |
250 | ## Actions: ##
251 | ### ``aux_ac.display_on`` ###
252 | This action turns a HVAC temperature display on when executed.
253 |
254 | ```yaml
255 | on_...:
256 | then:
257 | - aux_ac.display_on: aux_id
258 | ```
259 | - **aux_id** (**Requared**, string): ID of `aux_ac` component.
260 |
261 | ### ``aux_ac.display_off`` ###
262 | This action turns a HVAC temperature display off when executed.
263 |
264 | ```yaml
265 | on_...:
266 | then:
267 | - aux_ac.display_off: aux_id
268 | ```
269 | - **aux_id** (**Requared**, string): ID of `aux_ac` component.
270 |
271 | ### ``aux_ac.vlouver_set`` ###
272 | This action moves HVAC vertical louvers to the specified position.
273 |
274 | The position is encoded by the following values:
275 | - `0`: the vertical louvers are in `SWING` mode (they are moving up and down);
276 | - `1`: the louvers are stopped in a user position;
277 | - `2`: the louvers are in the topmost position;
278 | - `3`: the louvers are in one step above middle position;
279 | - `4`: the louvers are in the middle position;
280 | - `5`: the louvers are in one step below middle position;
281 | - `6`: the louvers are in the lowest position.
282 |
283 | ```yaml
284 | on_...:
285 | then:
286 | - aux_ac.vlouver_set:
287 | id: aux_id
288 | position: 3 # moves the louvers to the middle position
289 | ```
290 | - **aux_id** (**Required**, string): ID of `aux_ac` component.
291 | - **position** (**Required**, integer): position of the vertical louvers.
292 |
293 | ### ``aux_ac.vlouver_stop`` ###
294 | This action stops vertical swing of louvers.
295 |
296 | ```yaml
297 | on_...:
298 | then:
299 | - aux_ac.vlouver_stop: aux_id
300 | ```
301 | - **aux_id** (**Required**, string): ID of `aux_ac` component.
302 |
303 | ### ``aux_ac.vlouver_swing`` ###
304 | This action starts the vertical swing of louvers.
305 |
306 | ```yaml
307 | on_...:
308 | then:
309 | - aux_ac.vlouver_swing: aux_id
310 | ```
311 | - **aux_id** (**Required**, string): ID of `aux_ac` component.
312 |
313 | ### ``aux_ac.vlouver_top`` ###
314 | This action moves HVAC louvers to the topmost position.
315 |
316 | ```yaml
317 | on_...:
318 | then:
319 | - aux_ac.vlouver_top: aux_id
320 | ```
321 | - **aux_id** (**Required**, string): ID of `aux_ac` component.
322 |
323 | ### ``aux_ac.vlouver_middle_above`` ###
324 | This action moves HVAC louvers to the position one step under the topmost.
325 |
326 | ```yaml
327 | on_...:
328 | then:
329 | - aux_ac.vlouver_middle_above: aux_id
330 | ```
331 | - **aux_id** (**Required**, string): ID of `aux_ac` component.
332 |
333 | ### ``aux_ac.vlouver_middle`` ###
334 | This action moves HVAC louvers to the middle position.
335 |
336 | ```yaml
337 | on_...:
338 | then:
339 | - aux_ac.vlouver_middle: aux_id
340 | ```
341 | - **aux_id** (**Required**, string): ID of `aux_ac` component.
342 |
343 | ### ``aux_ac.vlouver_middle_below`` ###
344 | This action moves HVAC louvers to the position one step under the middle position.
345 |
346 | ```yaml
347 | on_...:
348 | then:
349 | - aux_ac.vlouver_middle_below: aux_id
350 | ```
351 | - **aux_id** (**Required**, string): ID of `aux_ac` component.
352 |
353 | ### ``aux_ac.vlouver_bottom`` ###
354 | This action moves HVAC louvers to the lowest position.
355 |
356 | ```yaml
357 | on_...:
358 | then:
359 | - aux_ac.vlouver_bottom: aux_id
360 | ```
361 | - **aux_id** (**Required**, string): ID of `aux_ac` component.
362 |
363 | ### ``aux_ac.aux_ac.power_limit_off`` ###
364 | This action disables inverter HVAC power limitation.
365 |
366 | ```yaml
367 | on_...:
368 | then:
369 | - aux_ac.power_limit_off: aux_id
370 | ```
371 | - **aux_id** (**Required**, string): ID of `aux_ac` component.
372 |
373 | ### ``aux_ac.power_limit_on`` ###
374 | This action enables inverter HVAC power limitation and sets this limit value.
375 |
376 | ```yaml
377 | on_...:
378 | then:
379 | - aux_ac.power_limit_on:
380 | id: aux_id
381 | limit: 46 # limits the maximum power of the inverter HVAC at 46%
382 | ```
383 | - **aux_id** (**Required**, string): ID of `aux_ac` component.
384 | - **limit** (**Optional**, integer): the maximum power of the inverter HVAC. If the power limitation is enabled, the inverter HVAC will limits its power.
385 | > **Notice**, that power limitation will affect the efficiency of your HVAC. For example, a low power limit may block the possibility of the conditioner to reach user-specified room temperature, because HVAC will not have enough power for it. Keep this in mind when you are using this function.
386 |
387 | Due to hardware limitation this value should be in the range from `30%` to `100%`. The default value for `limit` is `30%` (it will be used if `limit` is omitted in configuration).
388 |
389 |
390 |
391 | ## Simple example ##
392 | The source code of this example is located in the [aux_ac_simple.yaml](https://github.com/GrKoR/esphome_aux_ac_component/blob/master/examples/simple/aux_ac_simple.yaml) file.
393 |
394 | All settings in it is trivial. Just copy the file to your local folder, specify your Wi-Fi settings and compile YAML with ESPHome.
395 |
396 |
397 | ## Advanced example ##
398 | All sources are located [in advanced example folder](https://github.com/GrKoR/esphome_aux_ac_component/tree/master/examples/advanced).
399 |
400 | This time we'll configure two relative identical air conditioners with `aux_ac` custom component.
401 | Let's imagine we have ACs in a kitchen and in a living room. Air conditioners can be of the same brand or different brands - the main thing is that they are compatible with `aux_ac` and can be controlled using `aux_ac`.
402 | Because we are lazy, we'll define all common configuration parts for two air conditioners in one `ac_common.yaml` file.
403 | All specific parts of configuration are located in the `ac_kitchen.yaml` and `ac_livingroom.yaml`. Here we set `devicename` and `upper_devicename` for correct sensors and component naming. And here we specify the correct IP address of the device from `secrets.yaml`.
404 | **Don't forget** to specify `wifi_ip_kitchen`, `wifi_ota_ip_kitchen`, `wifi_ip_livingroom` and `wifi_ota_ip_livingroom` in the `secrets.yaml` along with the other sensitive information, such as passwords, tokens etc.
405 |
406 | If you try to compile `ac_common.yaml` it will raise errors. You need to compile `ac_kitchen.yaml` or `ac_livingroom.yaml` instead.
407 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Кастомный компонент для ESPHome для управления кондиционером по Wi-Fi
2 |
3 | English readme [is here](README-EN.md#esphome-aux-air-conditioner-custom-component-aux_ac).
4 |
5 | Управляет кондиционерами на базе AUX по Wi-Fi.
6 | По тексту ниже для компонента используется сокращение `aux_ac`.
7 |
8 | Обсудить проект можно [в чате Телеграм](https://t.me/aux_ac).
9 | Отзывы о багах и ошибках, а так же запросы на дополнительный функционал оставляйте [в соответствующем разделе](https://github.com/GrKoR/esphome_aux_ac_component/issues).
10 | Будет просто отлично, если к своему сообщению вы добавите лог и подробное описание. Для сбора логов есть [специальный скрипт на Python](https://github.com/GrKoR/ac_python_logger). С его помощью вы сможете сохранить в csv-файл все пакеты, которыми обменивается Wi-Fi модуль и сплит-система. Если такой лог дополнить описанием, в какое время и что именно вы пытались включить, то это сильно ускорит исправление багов.
11 | Также есть [подробная инструкция, описывающая как правильно запросить фичу](docs/HOW_TO_FEATURE_REQUEST.md).
12 |
13 |
14 | ## ДИСКЛЭЙМЕР (ОТМАЗКИ) ##
15 | 1. Все материалы этого проекта (программы, прошивки, схемы, 3D модели и т.п.) предоставляются "КАК ЕСТЬ". Всё, что вы делаете с вашим оборудованием, вы делаете на свой страх и риск. Автор не несет ответственности за результат и ничего не гарантирует. Если вы с абсолютной четкостью не понимаете, что именно вы делаете и для чего, лучше просто купите Wi-Fi модуль у производителя вашего кондиционера.
16 | 2. Я ~~не настоящий сварщик~~ не программер. Поэтому код наверняка не оптимален и плохо оформлен (зато комментариев по коду я разместил от души), местами может быть написан небезопасно. И хоть я и старался протестировать всё, но уверен, что какие-то моменты упустил. Так что отнеситесь к коду с подозрением, ожидайте от него подвоха и если что-то увидели - [пишите в багрепорт](https://github.com/GrKoR/esphome_aux_ac_component/issues).
17 |
18 |
19 | ## Поддерживаемые кондиционеры ##
20 | AUX - это один из нескольких OEM-производителей кондиционеров. AUX производят кондиционеры как под собственным брендом, так и для внешних заказчиков. Поэтому есть шанс, что произведенный на их фабрике кондиционер неизвестного бренда с `aux_ac` так же заработает.
21 | В интернете есть такой перечень производившихся на фабриках AUX брендов: AUX, Abion, AC ELECTRIC, Almacom, Ballu , Centek, Climer, DAX, Energolux, ERISSON, Green Energy, Hyundai, IGC, Kentatsu (некоторые серии), Klimaire, KOMANCHI, LANZKRAFT, LEBERG, LGen, Monroe, Neoclima, NEOLINE, One Air, Pioneer (до 2016 года), Roda, Rovex, Royal Clima, SAKATA, Samurai, SATURN, Scarlett, SmartWay, Soling, Subtropic, SUBTROPIC, Supra, Timberk, Vertex, Zanussi. В его полноте и достоверности есть сомнения, но ничего лучше найти не удалось.
22 |
23 |
24 | ### Список совместимых (протестированных) кондиционеров ###
25 | [Список протестированных кондиционеров](docs/AC_TESTED.md) размещен в отдельном файле и включает те модели, на которых `aux_ac` был запущен автором компонента или пользователями. Этот список постоянно пополняется, преимущественно по обратной связи от пользователей [в чате Телеграм](https://t.me/aux_ac).
26 |
27 | ### Если кондиционер в списке отсутствует ###
28 | Если ваш кондиционер отсутствует в списке протестированных, то это еще не значит, что его не получится подключить к Wi-Fi. Вот основные "звоночки", которые могут говорить о высоких шансах на успех:
29 | 1. Если производитель вашего кондиционера есть в списке протестированных выше, но модели нет.
30 | 2. Если на шильдике кондиционера в строке производитель написано что-то про AUX или Аукс.
31 | 3. Если в инструкции пользователя вашего кондиционера что-то написано про возможность управления по Wi-Fi с помощью мобильного приложения ACFreedom.
32 | 4. Если производитель вашего кондиционера предлагает для управления Wi-Fi модуль CTTM-40X24-WIFI-AKS (слева) или такой, как на фото справа. Причем правый модуль может быть как с USB-разъемом, так и с 5-контактным разъемом.
33 |
34 |
35 |
36 | Но будьте осмотрительны: ваш кондиционер никем не тестировался и важно четко понимать, что вы делаете. Иначе можете наломать дров.
37 | Если вы не уверены в своих силах, лучше дождитесь, пока другие более опытные пользователи протестируют вашу модель кондиционера (правда, это может не случиться никогда). Или приходите с вопросами [в телеграм-чат](https://t.me/aux_ac). Возможно, там вам помогут.
38 |
39 | Если вы протестировали ваш кондиционер и он работает, напишите мне, пожалуйста. Я внесу вашу модель в список протестированных. Возможно, это упростит кому-то жизнь =)
40 | Лучший способ сообщить о протестированном кондиционере - написать [в телеграм](https://t.me/aux_ac) или [в разделе багрепортов и заказа фич](https://github.com/GrKoR/esphome_aux_ac_component/issues).
41 |
42 | ## Как использовать компонент ##
43 | Для работы с кондиционером понадобится "железо" и прошивка. Описание электроники вынесено [в отдельный файл](docs/HARDWARE.md).
44 |
45 | ### Прошивка: интеграция aux_ac в вашу конфигурацию ESPHome ###
46 | Для использования требуется [ESPHome](https://esphome.io) версией не ниже 1.18.0. Именно в этой версии появились `external_components`. Но лучше использовать версию 1.20.4 или старше, так как до этой версии массированно исправлялись ошибки в механизме подключения внешних компонентов.
47 |
48 | ## Установка ##
49 | 1. Подключите компонент.
50 | За подробностями можно заглянуть в [официальную документацию ESPHome](https://esphome.io/components/external_components.html?highlight=external).
51 | ```yaml
52 | external_components:
53 | - source:
54 | type: git
55 | url: https://github.com/GrKoR/esphome_aux_ac_component
56 | ```
57 | Если требуется прошить определенную версию компонента, используйте синтаксис из примера ниже. Здесь прошивается версия 0.2.14. Список версий смотрите [в тегах на гитхаб](https://github.com/GrKoR/esphome_aux_ac_component/tags).
58 | ```yaml
59 | external_components:
60 | - source:
61 | type: git
62 | url: https://github.com/GrKoR/esphome_aux_ac_component
63 | ref: v.0.2.14
64 | ```
65 | 2. Настройте UART для коммуникации с вашим кондиционером:
66 | ```yaml
67 | uart:
68 | id: ac_uart_bus
69 | # ВНИМАНИЕ! Для TX и RX на платах типа NodeMCU используйте GPIO4 (D2) и GPIO5 (D1)!
70 | # подробнее см. в документации: https://github.com/GrKoR/esphome_aux_ac_component/blob/master/docs/HARDWARE.md
71 | tx_pin: GPIO1
72 | rx_pin: GPIO3
73 | baud_rate: 4800
74 | data_bits: 8
75 | parity: EVEN
76 | stop_bits: 1
77 | ```
78 | 3. **ВАЖНО!** Нужно отключить логгер ESPHome, чтобы он не отправлял в кондиционер свои данные.
79 | Отключение логгера от UART никак не затронет вывод в лог консоли или web-сервера.
80 | ```yaml
81 | logger:
82 | baud_rate: 0
83 | ```
84 | Если по каким-то причинам вам нужен вывод логгера в UART, можно переключить его на другой UART чипа. Например, у ESP8266 два аппаратных UART: UART0 и UART1. `Aux_ac` подходит только UART0, поскольку только он у esp8266 имеет и TX и RX. Логгеру достаточно только TX. Такой функционал в чипе esp8266 у UART1:
85 | ```yaml
86 | logger:
87 | level: DEBUG
88 | hardware_uart: UART1
89 | ```
90 |
91 | ## Настройка компонента ##
92 | Минимальная конфигурация:
93 | ```yaml
94 | climate:
95 | - platform: aux_ac
96 | name: "AC Name"
97 | ```
98 |
99 | Полная конфигурация:
100 | ```yaml
101 | climate:
102 | - platform: aux_ac
103 | name: "AC Name"
104 | id: aux_id
105 | uart_id: ac_uart_bus
106 | period: 7s
107 | show_action: true
108 | display_inverted: false
109 | timeout: 150
110 | indoor_temperature:
111 | name: AC Indoor Temperature
112 | id: ac_indoor_temp
113 | accuracy_decimals: 1
114 | internal: false
115 | outdoor_temperature:
116 | name: AC Outdoor Temperature
117 | id: ac_outdoor_temp
118 | internal: false
119 | outbound_temperature:
120 | name: AC Coolant Outbound Temperature
121 | id: ac_outbound_temp
122 | internal: false
123 | inbound_temperature:
124 | name: AC Coolant Inbound Temperature
125 | id: ac_inbound_temp
126 | internal: false
127 | compressor_temperature:
128 | name: AC Compressor Temperature
129 | id: ac_strange_temp
130 | internal: false
131 | display_state:
132 | name: AC Display State
133 | id: ac_display_state
134 | internal: false
135 | defrost_state:
136 | name: AC Defrost State
137 | id: ac_defrost_state
138 | internal: false
139 | inverter_power:
140 | name: AC Inverter Power
141 | id: ac_inverter_power
142 | internal: false
143 | inverter_power_limit_value:
144 | name: AC Inverter Power Limit Value
145 | id: ac_inverter_power_limit_value
146 | internal: false
147 | inverter_power_limit_state:
148 | name: AC Inverter Power Limit State
149 | id: ac_inverter_power_limit_state
150 | internal: false
151 | preset_reporter:
152 | name: AC Preset Reporter
153 | id: ac_preset_reporter
154 | internal: false
155 | vlouver_state:
156 | name: AC Vertical Louvers State
157 | id: ac_vlouver_state
158 | internal: false
159 | visual:
160 | min_temperature: 16
161 | max_temperature: 32
162 | temperature_step: 1
163 | supported_modes:
164 | - HEAT_COOL
165 | - COOL
166 | - HEAT
167 | - DRY
168 | - FAN_ONLY
169 | custom_fan_modes:
170 | - MUTE
171 | - TURBO
172 | supported_presets:
173 | - SLEEP
174 | custom_presets:
175 | - CLEAN
176 | - HEALTH
177 | - ANTIFUNGUS
178 | supported_swing_modes:
179 | - VERTICAL
180 | - HORIZONTAL
181 | - BOTH
182 | ```
183 |
184 | ## Параметры компонента: ##
185 |
186 | - **name** (**Обязательный**, строка): Имя кондиционера. Как минимум один из параметров `id` или `name` должен быть указан!
187 |
188 | - **id** (*Опциональный*, [ID](https://esphome.io/guides/configuration-types.html#config-id)): Укажите идентификатор кондиционера чтобы обращаться к нему из кода. Как минимум один из параметров `id` или `name` должен быть указан!
189 |
190 | - **uart_id** (*Опциональный*, [ID](https://esphome.io/guides/configuration-types.html#config-id)): Укажите ID [шины UART](https://esphome.io/components/uart.html), к которой подключен кондиционер. Если сконфигурирована одна шина, то компонент подключит её автоматически. Если шин несколько, то лучше указать вручную.
191 |
192 | - **period** (*Опциональный*, [время](https://esphome.io/guides/configuration-types.html#config-time), по умолчанию ``7s``): Период между запросами статуса кондиционера. `Aux_ac` получает новое состояние кондиционера только после регулярного запроса, потому что сам кондиционер об изменении параметров своей работы не уведомляет. Поэтому нужно запрашивать его, вдруг пользователь установил иной режим работы с помощью ИК-пульта.
193 |
194 | - **show_action** (*Опциональный*, логическое, по умолчанию ``true``): Показывать ли текущую задачу кондиционера (экспериментальная функция). Например, в режиме HEAT_COOL кондиционер может выполнять одну из следующих задач:
195 | - НАГРЕВ: нагревает воздух в комнате;
196 | - ПРОСТОЙ: кондиционер работает в режиме вентилятора для перемешивания воздуха в комнате, поскольку целевая температура уже достигнута;
197 | - ОХЛАЖДЕНИЕ: кондиционер охлаждает воздух в комнате.
198 | Аналогично будут отображаться действия кондиционера и для режимов ОТОПЛЕНИЕ и ОХЛАЖДЕНИЕ. Единственная разница будет в количестве действий: ПРОСТОЙ+НАГРЕВ для режима отопления и ПРОСТОЙ+ОХЛАЖДЕНИЕ для режима охлаждения комнаты.
199 |
200 | - **display_inverted** (*Опциональный*, логическое, по умолчанию ``false``): Настраивает способ управления дисплеем. Как выяснилось (issue [#31](https://github.com/GrKoR/esphome_aux_ac_component/issues/31)), включение-выключение дисплея обрабатывается кондиционерами по разному. Кондиционеры Rovex включают дисплей по `0` в соответствующем бите команды и выключают по биту `1`. Многие другие модели кондиционеров поступают наоборот.
201 |
202 | - **timeout** (*Опциональный*, неотрицательное целое, по умолчанию ``150``): Таймаут получения пакета для ресивера данных `aux_ac`.
203 | Чаще всего вам это значение никогда не понадобится. Поскольку этот параметр опционален, то его можно смело пропустить, если нет необходимости менять таймауты.
204 | Единственная ситуация, когда вам может пригодиться этот параметр, - это сильно загруженная ESP. Если по какой-то неподдающейся логике причине вы кроме `aux_ac` нагрузили свою ESP кучей дополнительных ресурсоемких задач, то у компонента может просто не хватать времени для оперативного приёма ответов от кондиционера. В этом в логе будут сообщения о том, что последовательность команд была прервана по таймауту. Чтобы это исправить, лучше, конечно, немного разгрузить ESP. Если это вам не подходит, тогда можно увеличить таймаут.
205 | Значение таймаута в прошивке ограничено диапазоном от `150` до `600` миллисекунд. Устанавливать значения выше можно только отредактировав исходные коды компонента. Но сильно задирать таймаут не стоит. Кондиционер периодически рассылает пакеты без запроса со стороны `aux_ac` и это приводит к сбою в отправке команды.
206 |
207 | - **optimistic** (*Опциональный*, логическое, по умолчанию ``true``) В «оптимистичном» режиме компонент не ждёт от кондиционера изменения параметров работы, а сразу после отправки команды в кондиционер сообщает в Home Assistant о новом состоянии. Если кондиционер команду не принял, то спустя несколько секунд eps получит текущее состояние всех систем и отправит в умный дом реальное состояние кондиционера. В итоге, если подавать в кондиционер неподдерживаемые команды, они будут записываться в историю Home Assistant и спустя время сбрасываться сбрасываться.
208 | В «пессимистичном» режиме esp отправляет команду в кондиционер, но об изменении состояний не сообщает до тех пор, пока не получит информацию о фактическом режиме работы кондиционера.
209 | В большинстве случаев разница между этими режимами будет практически незаметна.
210 |
211 | - **indoor_temperature** (*Опциональный*): Параметры создаваемого датчика температуры воздуха, если такой датчик нужен
212 | - **name** (**Обязательный**, строка): Имя датчика температуры.
213 | - **id** (*Опциональный*, [ID](https://esphome.io/guides/configuration-types.html#config-id)): Можно указать свой ID для датчика для использования в лямбдах.
214 | - **internal** (*Опциональный*, логическое): Пометить данный датчик как внутренний. Внутренний датчик не будет передаваться во фронтэнд (такой как Home Assistant). В противоположность стандартному поведению [сенсоров](https://esphome.io/components/sensor/index.html#base-sensor-configuration) этот параметр для датчика в кондиционере **всегда выставлен в true** за исключением случаев, когда пользователь не установил его в `false`. То есть по умолчанию значение сенсора не будет передаваться во фронтенд даже если указано `name` для сенсора.
215 | - Все остальные параметры [сенсора](https://esphome.io/components/sensor/index.html#base-sensor-configuration) ESPHome.
216 |
217 | - **outdoor_temperature** (*Опциональный*): Параметры создаваемого датчика уличной температуры воздуха, если такой датчик нужен. Параметры аналогичны датчику внутренней температуры **indoor_temperature** (см. выше).
218 | > **ВНИМАНИЕ!** Когда кондиционер выключен, температура наружного воздуха обновляется редко (раз в 6-7 часов). Это не баг компонента, а особенность работы железа кондиционера. Единственный способ получать изменения чаще - создать шаблонный сенсор, температуру которого изменять вручную. Когда кондиционер работает, значение такого сенсора можно копировать из **outdoor_temperature**. Когда кондиционер выключен, значение температуры пересчитывать по динамике сенсора **outbound_temperature** (он изменяется часто и при выключенном кондее показывает значения близкие к температуре воздуха). Заморочки с пересчетом нужны потому, что показания сенсоров не идентичны и на графике значений шаблонного сенсора могут быть ступеньки при переходе с **outdoor_temperature** на **outbound_temperature** и обратно.
219 |
220 | - **inbound_temperature** (*Опциональный*): Параметры создаваемого датчика температуры на подаче теплоносителя, если такой датчик нужен. Параметры аналогичны датчику внутренней температуры **indoor_temperature** (см. выше).
221 |
222 | - **outbound_temperature** (*Опциональный*): Параметры создаваемого датчика температуры на обратке теплоносителя, если такой датчик нужен. Параметры аналогичны датчику внутренней температуры **indoor_temperature** (см. выше).
223 |
224 | - **compressor_temperature** (*Опциональный*): Параметры создаваемого датчика температуры компрессора, если такой датчик нужен. Параметры аналогичны датчику внутренней температуры **indoor_temperature** (см. выше).
225 |
226 | - **display_state** (*Опциональный*): Параметры создаваемого датчика дисплея (включен или выключен), если такой датчик нужен.
227 | - **name** (**Обязательный**, строка): Имя датчика дисплея.
228 | - **id** (*Опциональный*, [ID](https://esphome.io/guides/configuration-types.html#config-id)): Можно указать свой ID для датчика для использования в лямбдах.
229 | - **internal** (*Опциональный*, логическое): Пометить данный датчик как внутренний. Внутренний датчик не будет передаваться во фронтэнд (такой как Home Assistant). В противоположность стандартному поведению [бинарных сенсоров](https://esphome.io/components/binary_sensor/index.html#base-binary-sensor-configuration) этот параметр для датчика в кондиционере **всегда выставлен в true** за исключением случаев, когда пользователь не установил его в `false`. То есть по умолчанию значение сенсора не будет передаваться во фронтенд даже если указано `name` для сенсора.
230 | - Все остальные параметры [бинарного сенсора](https://esphome.io/components/binary_sensor/index.html#base-binary-sensor-configuration) ESPHome.
231 |
232 | - **defrost_state** (*Опциональный*): Параметры создаваемого датчика состояния разморозки (включена или выключена), если такой датчик нужен. Параметры аналогичны датчику дисплея **display_state**.
233 |
234 | - **inverter_power** (*Опциональный*): Параметры создаваемого датчика мощности инвертора, если такой датчик нужен. Параметры аналогичны датчику дисплея **indoor_temperature**.
235 | > **ВНИМАНИЕ!** Название параметра было изменено в версии v.0.2.9 в рамках борьбы с безграмотностью.
236 |
237 | - **inverter_power_limit_state** (*Опциональный*): Параметры создаваемого датчика состояния функции ограничения мощности. Показывает, включена данная функция в настоящий момент или нет. По очевидным причинам актуально только для инверторных кондиционеров, для "старт-стоп" кондиционеров всегда будет "выключен". Параметры аналогичны датчику дисплея **display_state**.
238 |
239 | - **inverter_power_limit_value** (*Опциональный*): Параметры создаваемого датчика текущего ограничения мощности, если такой датчик нужен. Параметры аналогичны датчику внутренней температуры **indoor_temperature** (см. выше).
240 | Сенсор отображает текущее значение ограничения максимальной мощности для инверторного кондиционера. Значение в процентах. С кондиционерами "старт-стоп" по очевидным причинам не работает, всегда показывая значение `0%`. Заданное пользователем значения лимита будет отображено только после того, как кондиционер подтвердит полученное значение и начнет с ним работать.
241 | В силу ограничений на уровне железа лимит мощности может быть задан только в пределах от `30%` до `100%`.
242 |
243 | - **preset_reporter** (*Опциональный*): Параметры создаваемого текстового датчика текущего активного пресета. Параметры аналогичны датчику дисплея **display_state**.
244 | Климатические устройства ESPHome не отправляют по MQTT активный пресет (см. **supported_presets** и **custom_presets**), в котором работает устройство. Если вы используете MQTT и хотите получать информацию о пресетах, то пропишите этот датчик в конфигурации.
245 |
246 | - **vlouver_state** (*Опциональный*): Параметры создаваемого сенсора состояния вертикальных жалюзи. Параметры аналогичны датчику дисплея **display_state**. Состояние жалюзи кодируется целочисленными значениями (подробнее смотри [aux_ac.vlouver_set action](#aux_ac_._vlouver_set) ниже).
247 |
248 | - **supported_modes** (*Опциональный*, список): Список поддерживаемых режимов работы. Возможные значения: ``HEAT_COOL``, ``COOL``, ``HEAT``, ``DRY``, ``FAN_ONLY``. Обратите внимание: некоторые производители кондиционеров указывают на пульте режим AUTO, хотя по факту этот режим не работает по расписанию и только лишь поддерживает целевую температуру. Такой режим в ESPHome называется HEAT_COOL. По умолчанию список содержит только значение ``FAN_ONLY``.
249 |
250 | - **custom_fan_modes** (*Опциональный*, список): Список поддерживаемых дополнительных режимов вентилятора. Возможные значения: ``MUTE``, ``TURBO``. По умолчанию никакие дополнительные режимы не установлены.
251 |
252 | - **supported_presets** (*Опциональный*, список): Список поддерживаемых базовых функций кондиционера. Возможные значения: ``SLEEP``. По умолчанию никакие базовые функции не установлены.
253 |
254 | - **custom_presets** (*Опциональный*, список): Список поддерживаемых дополнительных функций кондиционера. Возможные значения: ``CLEAN``, ``HEALTH``, ``ANTIFUNGUS``. По умолчанию никакие дополнительные функции не установлены.
255 |
256 | - **supported_swing_modes** (*Опциональный*, список): Список поддерживаемых режимов качания шторки. Возможные значения: ``VERTICAL``, ``HORIZONTAL``, ``BOTH``. По умолчанию устанавливается, что качание шторки кондиционером не поддерживается.
257 |
258 | - Все остальные параметры [климатического устройства](https://esphome.io/components/climate/index.html#base-climate-configuration) ESPHome.
259 |
260 | ## Действия: ##
261 | ### ``aux_ac.display_on`` ###
262 | Включение экрана температуры на лицевой панели кондиционера.
263 |
264 | ```yaml
265 | on_...:
266 | then:
267 | - aux_ac.display_on: aux_id
268 | ```
269 | - **aux_id** (**Обязательный**, строка): ID компонента `aux_ac`.
270 |
271 | ### ``aux_ac.display_off`` ###
272 | Выключение экрана температуры на лицевой панели кондиционера.
273 |
274 | ```yaml
275 | on_...:
276 | then:
277 | - aux_ac.display_off: aux_id
278 | ```
279 | - **aux_id** (**Обязательный**, строка): ID компонента `aux_ac`.
280 |
281 | ### ``aux_ac.vlouver_set`` ###
282 | Переводит жалюзи в указанное состояние.
283 |
284 | Состояние кодируется следующими целочисленными значениями:
285 | - `0`: жалюзи находятся в состоянии `SWING` (качаются вверх-вниз);
286 | - `1`: жалюзи остановлены в каком-то пользовательском положении;
287 | - `2`: жалюзи установлены в верхнее положение;
288 | - `3`: жалюзи установлены в положение на шаг выше среднего;
289 | - `4`: жалюзи установлены в среднее положение;
290 | - `5`: жалюзи установлены в положение на шаг ниже среднего;
291 | - `6`: жалюзи установлены в нижнее положение.
292 |
293 | ```yaml
294 | on_...:
295 | then:
296 | - aux_ac.vlouver_set:
297 | id: aux_id
298 | position: 3 # устанавливаем жалюзи в среднее положение
299 | ```
300 | - **aux_id** (**Обязательный**, строка): ID компонента `aux_ac`.
301 | - **position** (**Обязательный**, целое число): состояние вертикальных жалюзи.
302 |
303 | ### ``aux_ac.vlouver_stop`` ###
304 | Остановка вертикального движения жалюзи кондиционера. Если жалюзи качались в вертикальном направлении, то можно их остановить в нужном положении.
305 |
306 | ```yaml
307 | on_...:
308 | then:
309 | - aux_ac.vlouver_stop: aux_id
310 | ```
311 | - **aux_id** (**Обязательный**, строка): ID компонента `aux_ac`.
312 |
313 | ### ``aux_ac.vlouver_swing`` ###
314 | Включение вертикального качания жалюзи кондиционера.
315 |
316 | ```yaml
317 | on_...:
318 | then:
319 | - aux_ac.vlouver_swing: aux_id
320 | ```
321 | - **aux_id** (**Обязательный**, строка): ID компонента `aux_ac`.
322 |
323 | ### ``aux_ac.vlouver_top`` ###
324 | Установка жалюзи в самое верхнее положение.
325 |
326 | ```yaml
327 | on_...:
328 | then:
329 | - aux_ac.vlouver_top: aux_id
330 | ```
331 | - **aux_id** (**Обязательный**, строка): ID компонента `aux_ac`.
332 |
333 | ### ``aux_ac.vlouver_middle_above`` ###
334 | Установка жалюзи во второе сверху положение. Это положение между верхним и средним.
335 |
336 | ```yaml
337 | on_...:
338 | then:
339 | - aux_ac.vlouver_middle_above: aux_id
340 | ```
341 | - **aux_id** (**Обязательный**, строка): ID компонента `aux_ac`.
342 |
343 | ### ``aux_ac.vlouver_middle`` ###
344 | Установка жалюзи в среднее положение.
345 |
346 | ```yaml
347 | on_...:
348 | then:
349 | - aux_ac.vlouver_middle: aux_id
350 | ```
351 | - **aux_id** (**Обязательный**, строка): ID компонента `aux_ac`.
352 |
353 | ### ``aux_ac.vlouver_middle_below`` ###
354 | Установка жалюзи в положение ниже среднего.
355 |
356 | ```yaml
357 | on_...:
358 | then:
359 | - aux_ac.vlouver_middle_below: aux_id
360 | ```
361 | - **aux_id** (**Обязательный**, строка): ID компонента `aux_ac`.
362 |
363 | ### ``aux_ac.vlouver_bottom`` ###
364 | Установка жалюзи в самое нижнее положение.
365 |
366 | ```yaml
367 | on_...:
368 | then:
369 | - aux_ac.vlouver_bottom: aux_id
370 | ```
371 | - **aux_id** (**Обязательный**, строка): ID компонента `aux_ac`.
372 |
373 | ### ``aux_ac.power_limit_off`` ###
374 | Отключает лимит мощности инверторного кондиционера, если такой лимит был установлен.
375 |
376 | ```yaml
377 | on_...:
378 | then:
379 | - aux_ac.power_limit_off: aux_id
380 | ```
381 | - **aux_id** (**Обязательный**, строка): ID компонента `aux_ac`.
382 |
383 | ### ``aux_ac.power_limit_on`` ###
384 | Включает ограничение мощности для инверторного кондиционера, а также может задавать предельное значение мощности. Для кондиционеров "старт-стоп" не работает, вызов игнорируется.
385 |
386 | ```yaml
387 | on_...:
388 | then:
389 | - aux_ac.power_limit_on:
390 | id: aux_id
391 | limit: 46 # ограничивает максимальную мощность инверторного кондиционера на уровне 46%
392 | ```
393 | - **aux_id** (**Обязательный**, строка): ID компонента `aux_ac`.
394 | - **limit** (**Опциональный**, целое число): задаваемое пользователем максимальное значение мощности инверторного кондиционера.
395 | При установленном лимите кондиционер не будет превышать это значение в работе.
396 | > **Обратите внимание**, что задание лимита повлияет на эффективность работы сплит-системы. Например, при низком значении лимита кондиционеру может не хватать мощности, чтобы охладить или нагреть комнату до заданной пользователем температуры. Либо время, затраченное кондиционером на нагрев или охлаждение, может вырасти. Имейте это ввиду при установке ограничений.
397 |
398 | В силу ограничений на уровне железа, лимит мощности должен быть в пределах от `30%` до `100%`. Некорректные значения будут приведены к диапазону.
399 | В случае, если включение лимита вызывается без указания параметра `limit`, то будет использовано значение по умолчанию `30%`.
400 |
401 |
402 | ## Простейший пример ##
403 | Исходный код простейшего примера можно найти в файле [aux_ac_simple.yaml](https://github.com/GrKoR/esphome_aux_ac_component/blob/master/examples/simple/aux_ac_simple.yaml).
404 |
405 | Все настройки в нем тривиальны и подробно описаны [в официальной документации на ESPHome](https://esphome.io/index.html) и дополнены в разделе о настройке компонента выше.
406 | Просто скопируйте yaml-файл примера в локальную папку у себя на компьютере, пропишите настройки вашей сети Wi-Fi и откомпилируйте YAML с использованием ESPHome.
407 |
408 |
409 | ## Продвинутый пример ##
410 | Все исходники продвинутого примера лежат [в соответствующей папке](https://github.com/GrKoR/esphome_aux_ac_component/tree/master/examples/advanced).
411 |
412 | В этом примере мы конфигурируем два относительно одинаковых кондиционера на работу с `aux_ac`.
413 | Вводные: представим, что у нас есть два кондея, расположенных в кухне и в гостиной. Эти кондиционеры могут и не быть одного бренда. Главное, чтобы они были совместимы с `aux_ac`.
414 | Поскольку мы ленивы, мы пропишем все общие настройки обоих кондиционеров в общем конфигурационном файле `ac_common.yaml`.
415 | А все параметры, специфичные для каждого конкретного устройства, вынесем в отдельные файлы. Это файлы `ac_kitchen.yaml` и `ac_livingroom.yaml`. В них мы установим значения для подстановок `devicename` и `upper_devicename`, чтобы у устройств в сети были корректные имена самого компонента и его сенсоров. И здесь же мы указываем уникальные для каждого устройства IP-адреса, спрятанные в `secrets.yaml`.
416 | Кстати да! **Не забудьте** присвоить корректные значения `wifi_ip_kitchen`, `wifi_ota_ip_kitchen`, `wifi_ip_livingroom` и `wifi_ota_ip_livingroom` в файле `secrets.yaml` наряду с остальной "секретной" информацией (например пароли, токены и т.п.). Файл `secrets.yaml` по понятным причинам на гитхаб не выложен.
417 |
418 | Если попытаться компилировать файл `ac_common.yaml`, то ESPHome выдаст ошибку. Для корректной прошивки необходимо компилировать `ac_kitchen.yaml` или `ac_livingroom.yaml`.
419 |
--------------------------------------------------------------------------------
/components/aux_ac/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GrKoR/esphome_aux_ac_component/7a252e5955f075b66460de25deffc8c2ed266569/components/aux_ac/__init__.py
--------------------------------------------------------------------------------
/components/aux_ac/automation.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "aux_ac.h"
4 | #include "esphome/core/automation.h"
5 | #include "esphome/core/component.h"
6 |
7 | namespace esphome {
8 | namespace aux_ac {
9 |
10 | // **************************************** DISPLAY ACTIONS ****************************************
11 | template
12 | class AirConDisplayOffAction : public Action {
13 | public:
14 | explicit AirConDisplayOffAction(AirCon *ac) : ac_(ac) {}
15 |
16 | void play(Ts... x) override { this->ac_->displayOffSequence(); }
17 |
18 | protected:
19 | AirCon *ac_;
20 | };
21 |
22 | template
23 | class AirConDisplayOnAction : public Action {
24 | public:
25 | explicit AirConDisplayOnAction(AirCon *ac) : ac_(ac) {}
26 |
27 | void play(Ts... x) override { this->ac_->displayOnSequence(); }
28 |
29 | protected:
30 | AirCon *ac_;
31 | };
32 |
33 | // **************************************** VERTICAL LOUVER ACTIONS ****************************************
34 | template
35 | class AirConVLouverSwingAction : public Action {
36 | public:
37 | explicit AirConVLouverSwingAction(AirCon *ac) : ac_(ac) {}
38 |
39 | void play(Ts... x) override { this->ac_->setVLouverSwingSequence(); }
40 |
41 | protected:
42 | AirCon *ac_;
43 | };
44 |
45 | template
46 | class AirConVLouverStopAction : public Action {
47 | public:
48 | explicit AirConVLouverStopAction(AirCon *ac) : ac_(ac) {}
49 |
50 | void play(Ts... x) override { this->ac_->setVLouverStopSequence(); }
51 |
52 | protected:
53 | AirCon *ac_;
54 | };
55 |
56 | template
57 | class AirConVLouverTopAction : public Action {
58 | public:
59 | explicit AirConVLouverTopAction(AirCon *ac) : ac_(ac) {}
60 |
61 | void play(Ts... x) override { this->ac_->setVLouverTopSequence(); }
62 |
63 | protected:
64 | AirCon *ac_;
65 | };
66 |
67 | template
68 | class AirConVLouverMiddleAboveAction : public Action {
69 | public:
70 | explicit AirConVLouverMiddleAboveAction(AirCon *ac) : ac_(ac) {}
71 |
72 | void play(Ts... x) override { this->ac_->setVLouverMiddleAboveSequence(); }
73 |
74 | protected:
75 | AirCon *ac_;
76 | };
77 |
78 | template
79 | class AirConVLouverMiddleAction : public Action {
80 | public:
81 | explicit AirConVLouverMiddleAction(AirCon *ac) : ac_(ac) {}
82 |
83 | void play(Ts... x) override { this->ac_->setVLouverMiddleSequence(); }
84 |
85 | protected:
86 | AirCon *ac_;
87 | };
88 |
89 | template
90 | class AirConVLouverMiddleBelowAction : public Action {
91 | public:
92 | explicit AirConVLouverMiddleBelowAction(AirCon *ac) : ac_(ac) {}
93 |
94 | void play(Ts... x) override { this->ac_->setVLouverMiddleBelowSequence(); }
95 |
96 | protected:
97 | AirCon *ac_;
98 | };
99 |
100 | template
101 | class AirConVLouverBottomAction : public Action {
102 | public:
103 | explicit AirConVLouverBottomAction(AirCon *ac) : ac_(ac) {}
104 |
105 | void play(Ts... x) override { this->ac_->setVLouverBottomSequence(); }
106 |
107 | protected:
108 | AirCon *ac_;
109 | };
110 |
111 | template
112 | class AirConVLouverSetAction : public Action {
113 | public:
114 | AirConVLouverSetAction(AirCon *ac) : ac_(ac) {}
115 | TEMPLATABLE_VALUE(uint8_t, value);
116 |
117 | void play(Ts... x) {
118 | vlpos_ = this->value_.value(x...);
119 | this->ac_->setVLouverFrontendSequence((ac_vlouver_frontend)vlpos_);
120 | }
121 |
122 | protected:
123 | AirCon *ac_;
124 | uint8_t vlpos_;
125 | };
126 |
127 | // **************************************** SEND TEST PACKET ACTION ****************************************
128 | template
129 | class AirConSendTestPacketAction : public Action {
130 | public:
131 | explicit AirConSendTestPacketAction(AirCon *ac) : ac_(ac) {}
132 | void set_data_template(std::function(Ts...)> func) {
133 | this->data_func_ = func;
134 | this->static_ = false;
135 | }
136 | void set_data_static(const std::vector &data) {
137 | this->data_static_ = data;
138 | this->static_ = true;
139 | }
140 |
141 | void play(Ts... x) override {
142 | if (this->static_) {
143 | this->ac_->sendTestPacket(this->data_static_);
144 | } else {
145 | auto val = this->data_func_(x...);
146 | this->ac_->sendTestPacket(val);
147 | }
148 | }
149 |
150 | protected:
151 | AirCon *ac_;
152 | bool static_{false};
153 | std::function(Ts...)> data_func_{};
154 | std::vector data_static_{};
155 | };
156 |
157 | // **************************************** POWER LIMITATION ACTIONS ****************************************
158 | template
159 | class AirConPowerLimitationOffAction : public Action {
160 | public:
161 | explicit AirConPowerLimitationOffAction(AirCon *ac) : ac_(ac) {}
162 |
163 | void play(Ts... x) override { this->ac_->powerLimitationOffSequence(); }
164 |
165 | protected:
166 | AirCon *ac_;
167 | };
168 |
169 | template
170 | class AirConPowerLimitationOnAction : public Action {
171 | public:
172 | AirConPowerLimitationOnAction(AirCon *ac) : ac_(ac) {}
173 | TEMPLATABLE_VALUE(uint8_t, value);
174 |
175 | void play(Ts... x) {
176 | this->pwr_lim_ = this->value_.value(x...);
177 | this->ac_->powerLimitationOnSequence(this->pwr_lim_);
178 | }
179 |
180 | protected:
181 | AirCon *ac_;
182 | uint8_t pwr_lim_;
183 | };
184 |
185 | } // namespace aux_ac
186 | } // namespace esphome
--------------------------------------------------------------------------------
/components/aux_ac/climate.py:
--------------------------------------------------------------------------------
1 | import logging
2 | from esphome.core import CORE, Define
3 | import esphome.config_validation as cv
4 | import esphome.codegen as cg
5 | from esphome.components import climate, uart, sensor, binary_sensor, text_sensor
6 | from esphome import automation
7 | from esphome.automation import maybe_simple_id
8 | from esphome.const import (
9 | CONF_CUSTOM_FAN_MODES,
10 | CONF_CUSTOM_PRESETS,
11 | CONF_DATA,
12 | CONF_ID,
13 | CONF_INTERNAL,
14 | CONF_OPTIMISTIC,
15 | CONF_PERIOD,
16 | CONF_POSITION,
17 | CONF_SUPPORTED_MODES,
18 | CONF_SUPPORTED_SWING_MODES,
19 | CONF_SUPPORTED_PRESETS,
20 | CONF_TIMEOUT,
21 | CONF_UART_ID,
22 | UNIT_CELSIUS,
23 | UNIT_PERCENT,
24 | ICON_POWER,
25 | ICON_THERMOMETER,
26 | DEVICE_CLASS_TEMPERATURE,
27 | DEVICE_CLASS_POWER_FACTOR,
28 | STATE_CLASS_MEASUREMENT,
29 | )
30 | from esphome.components.climate import (
31 | ClimateMode,
32 | ClimatePreset,
33 | ClimateSwingMode,
34 | )
35 |
36 | AUX_AC_FIRMWARE_VERSION = '0.2.15'
37 | AC_PACKET_TIMEOUT_MIN = 150
38 | AC_PACKET_TIMEOUT_MAX = 600
39 | AC_POWER_LIMIT_MIN = 30
40 | AC_POWER_LIMIT_MAX = 100
41 |
42 | _LOGGER = logging.getLogger(__name__)
43 |
44 | CODEOWNERS = ["@GrKoR"]
45 | DEPENDENCIES = ["climate", "uart"]
46 | AUTO_LOAD = ["sensor", "binary_sensor", "text_sensor"]
47 |
48 | CONF_SHOW_ACTION = "show_action"
49 |
50 | CONF_INDOOR_TEMPERATURE = "indoor_temperature"
51 | CONF_OUTDOOR_TEMPERATURE = "outdoor_temperature"
52 | ICON_OUTDOOR_TEMPERATURE = "mdi:home-thermometer-outline"
53 |
54 | CONF_INBOUND_TEMPERATURE = "inbound_temperature"
55 | ICON_INBOUND_TEMPERATURE = "mdi:thermometer-plus"
56 |
57 | CONF_OUTBOUND_TEMPERATURE = "outbound_temperature"
58 | ICON_OUTBOUND_TEMPERATURE = "mdi:thermometer-minus"
59 |
60 | CONF_COMPRESSOR_TEMPERATURE = "compressor_temperature"
61 | ICON_COMPRESSOR_TEMPERATURE = "mdi:thermometer-lines"
62 |
63 | CONF_DISPLAY_STATE = "display_state"
64 | CONF_INVERTER_POWER = "inverter_power"
65 | CONF_INVERTER_POWER_DEPRICATED = "invertor_power"
66 |
67 | CONF_DEFROST_STATE = "defrost_state"
68 | ICON_DEFROST = "mdi:snowflake-melt"
69 |
70 | CONF_DISPLAY_INVERTED = "display_inverted"
71 | ICON_DISPLAY = "mdi:clock-digital"
72 |
73 | CONF_PRESET_REPORTER = "preset_reporter"
74 | ICON_PRESET_REPORTER = "mdi:format-list-group"
75 |
76 | CONF_VLOUVER_STATE = "vlouver_state"
77 | ICON_VLOUVER_STATE = "mdi:compare-vertical"
78 |
79 | CONF_LIMIT = "limit"
80 | CONF_INVERTER_POWER_LIMIT_VALUE = "inverter_power_limit_value"
81 | ICON_INVERTER_POWER_LIMIT_VALUE = "mdi:meter-electric-outline"
82 | CONF_INVERTER_POWER_LIMIT_STATE = "inverter_power_limit_state"
83 | ICON_INVERTER_POWER_LIMIT_STATE = "mdi:meter-electric-outline"
84 |
85 |
86 | aux_ac_ns = cg.esphome_ns.namespace("aux_ac")
87 | AirCon = aux_ac_ns.class_("AirCon", climate.Climate, cg.Component)
88 | Capabilities = aux_ac_ns.namespace("Constants")
89 |
90 | # Display actions
91 | AirConDisplayOffAction = aux_ac_ns.class_("AirConDisplayOffAction", automation.Action)
92 | AirConDisplayOnAction = aux_ac_ns.class_("AirConDisplayOnAction", automation.Action)
93 |
94 | # test packet action
95 | AirConSendTestPacketAction = aux_ac_ns.class_(
96 | "AirConSendTestPacketAction", automation.Action
97 | )
98 |
99 | # vertical louvers actions
100 | AirConVLouverSwingAction = aux_ac_ns.class_(
101 | "AirConVLouverSwingAction", automation.Action
102 | )
103 | AirConVLouverStopAction = aux_ac_ns.class_("AirConVLouverStopAction", automation.Action)
104 | AirConVLouverTopAction = aux_ac_ns.class_("AirConVLouverTopAction", automation.Action)
105 | AirConVLouverMiddleAboveAction = aux_ac_ns.class_(
106 | "AirConVLouverMiddleAboveAction", automation.Action
107 | )
108 | AirConVLouverMiddleAction = aux_ac_ns.class_(
109 | "AirConVLouverMiddleAction", automation.Action
110 | )
111 | AirConVLouverMiddleBelowAction = aux_ac_ns.class_(
112 | "AirConVLouverMiddleBelowAction", automation.Action
113 | )
114 | AirConVLouverBottomAction = aux_ac_ns.class_(
115 | "AirConVLouverBottomAction", automation.Action
116 | )
117 | AirConVLouverSetAction = aux_ac_ns.class_(
118 | "AirConVLouverSetAction", automation.Action
119 | )
120 |
121 | # power limitation actions
122 | AirConPowerLimitationOffAction = aux_ac_ns.class_(
123 | "AirConPowerLimitationOffAction", automation.Action
124 | )
125 | AirConPowerLimitationOnAction = aux_ac_ns.class_(
126 | "AirConPowerLimitationOnAction", automation.Action
127 | )
128 |
129 |
130 | def validate_packet_timeout(value):
131 | minV = AC_PACKET_TIMEOUT_MIN
132 | maxV = AC_PACKET_TIMEOUT_MAX
133 | if value in range(minV, maxV+1):
134 | return cv.Schema(cv.uint32_t)(value)
135 | raise cv.Invalid(f"Timeout should be in range: {minV}..{maxV}.")
136 |
137 |
138 | def validate_power_limit_range(value):
139 | minV = AC_POWER_LIMIT_MIN
140 | maxV = AC_POWER_LIMIT_MAX
141 | if value in range(minV, maxV+1):
142 | return cv.Schema(cv.uint32_t)(value)
143 | raise cv.Invalid(f"Power limit should be in range: {minV}..{maxV}")
144 |
145 |
146 | ALLOWED_CLIMATE_MODES = {
147 | "HEAT_COOL": ClimateMode.CLIMATE_MODE_HEAT_COOL,
148 | "COOL": ClimateMode.CLIMATE_MODE_COOL,
149 | "HEAT": ClimateMode.CLIMATE_MODE_HEAT,
150 | "DRY": ClimateMode.CLIMATE_MODE_DRY,
151 | "FAN_ONLY": ClimateMode.CLIMATE_MODE_FAN_ONLY,
152 | }
153 | validate_modes = cv.enum(ALLOWED_CLIMATE_MODES, upper=True)
154 |
155 | ALLOWED_CLIMATE_PRESETS = {
156 | "SLEEP": ClimatePreset.CLIMATE_PRESET_SLEEP,
157 | }
158 | validate_presets = cv.enum(ALLOWED_CLIMATE_PRESETS, upper=True)
159 |
160 | ALLOWED_CLIMATE_SWING_MODES = {
161 | "BOTH": ClimateSwingMode.CLIMATE_SWING_BOTH,
162 | "VERTICAL": ClimateSwingMode.CLIMATE_SWING_VERTICAL,
163 | "HORIZONTAL": ClimateSwingMode.CLIMATE_SWING_HORIZONTAL,
164 | }
165 | validate_swing_modes = cv.enum(ALLOWED_CLIMATE_SWING_MODES, upper=True)
166 |
167 | CUSTOM_FAN_MODES = {
168 | "MUTE": Capabilities.MUTE,
169 | "TURBO": Capabilities.TURBO,
170 | }
171 | validate_custom_fan_modes = cv.enum(CUSTOM_FAN_MODES, upper=True)
172 |
173 | CUSTOM_PRESETS = {
174 | "CLEAN": Capabilities.CLEAN,
175 | "HEALTH": Capabilities.HEALTH,
176 | "ANTIFUNGUS": Capabilities.ANTIFUNGUS,
177 | }
178 | validate_custom_presets = cv.enum(CUSTOM_PRESETS, upper=True)
179 |
180 |
181 | def validate_raw_data(value):
182 | if isinstance(value, list):
183 | return cv.Schema([cv.hex_uint8_t])(value)
184 | raise cv.Invalid("data must be a list of bytes")
185 |
186 |
187 | def output_info(config):
188 | _LOGGER.info("AUX_AC firmware version: %s", AUX_AC_FIRMWARE_VERSION)
189 | return config
190 |
191 |
192 | CONFIG_SCHEMA = cv.All(
193 | climate.CLIMATE_SCHEMA.extend(
194 | {
195 | cv.GenerateID(): cv.declare_id(AirCon),
196 | cv.Optional(CONF_PERIOD, default="7s"): cv.time_period,
197 | cv.Optional(CONF_SHOW_ACTION, default="true"): cv.boolean,
198 | cv.Optional(CONF_DISPLAY_INVERTED, default="false"): cv.boolean,
199 | cv.Optional(CONF_TIMEOUT, default=AC_PACKET_TIMEOUT_MIN): validate_packet_timeout,
200 | cv.Optional(CONF_OPTIMISTIC, default="true"): cv.boolean,
201 | cv.Optional(CONF_INVERTER_POWER_DEPRICATED): cv.invalid(
202 | "The name of sensor was changed in v.0.2.9 from 'invertor_power' to 'inverter_power'. Update your config please."
203 | ),
204 | cv.Optional(CONF_INVERTER_POWER): sensor.sensor_schema(
205 | unit_of_measurement=UNIT_PERCENT,
206 | icon=ICON_POWER,
207 | accuracy_decimals=0,
208 | device_class=DEVICE_CLASS_POWER_FACTOR,
209 | state_class=STATE_CLASS_MEASUREMENT,
210 | ).extend(
211 | {
212 | cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
213 | }
214 | ),
215 |
216 | cv.Optional(CONF_INDOOR_TEMPERATURE): sensor.sensor_schema(
217 | unit_of_measurement=UNIT_CELSIUS,
218 | icon=ICON_THERMOMETER,
219 | accuracy_decimals=1,
220 | device_class=DEVICE_CLASS_TEMPERATURE,
221 | state_class=STATE_CLASS_MEASUREMENT,
222 | ).extend(
223 | {
224 | cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
225 | }
226 | ),
227 | cv.Optional(CONF_OUTDOOR_TEMPERATURE): sensor.sensor_schema(
228 | unit_of_measurement=UNIT_CELSIUS,
229 | icon=ICON_OUTDOOR_TEMPERATURE,
230 | accuracy_decimals=0,
231 | device_class=DEVICE_CLASS_TEMPERATURE,
232 | state_class=STATE_CLASS_MEASUREMENT,
233 | ).extend(
234 | {
235 | cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
236 | }
237 | ),
238 | cv.Optional(CONF_INBOUND_TEMPERATURE): sensor.sensor_schema(
239 | unit_of_measurement=UNIT_CELSIUS,
240 | icon=ICON_INBOUND_TEMPERATURE,
241 | accuracy_decimals=0,
242 | device_class=DEVICE_CLASS_TEMPERATURE,
243 | state_class=STATE_CLASS_MEASUREMENT,
244 | ).extend(
245 | {
246 | cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
247 | }
248 | ),
249 | cv.Optional(CONF_OUTBOUND_TEMPERATURE): sensor.sensor_schema(
250 | unit_of_measurement=UNIT_CELSIUS,
251 | icon=ICON_OUTBOUND_TEMPERATURE,
252 | accuracy_decimals=0,
253 | device_class=DEVICE_CLASS_TEMPERATURE,
254 | state_class=STATE_CLASS_MEASUREMENT,
255 | ).extend(
256 | {
257 | cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
258 | }
259 | ),
260 | cv.Optional(CONF_COMPRESSOR_TEMPERATURE): sensor.sensor_schema(
261 | unit_of_measurement=UNIT_CELSIUS,
262 | icon=ICON_COMPRESSOR_TEMPERATURE,
263 | accuracy_decimals=0,
264 | device_class=DEVICE_CLASS_TEMPERATURE,
265 | state_class=STATE_CLASS_MEASUREMENT,
266 | ).extend(
267 | {
268 | cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
269 | }
270 | ),
271 | cv.Optional(CONF_VLOUVER_STATE): sensor.sensor_schema(
272 | icon=ICON_VLOUVER_STATE,
273 | accuracy_decimals=0,
274 | ).extend(
275 | {
276 | cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
277 | }
278 | ),
279 | cv.Optional(CONF_DISPLAY_STATE): binary_sensor.binary_sensor_schema(
280 | icon=ICON_DISPLAY,
281 | ).extend(
282 | {
283 | cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
284 | }
285 | ),
286 | cv.Optional(CONF_DEFROST_STATE): binary_sensor.binary_sensor_schema(
287 | icon=ICON_DEFROST,
288 | ).extend(
289 | {
290 | cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
291 | }
292 | ),
293 | cv.Optional(CONF_PRESET_REPORTER): text_sensor.text_sensor_schema(
294 | icon=ICON_PRESET_REPORTER,
295 | ).extend(
296 | {
297 | cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
298 | }
299 | ),
300 | cv.Optional(CONF_INVERTER_POWER_LIMIT_VALUE): sensor.sensor_schema(
301 | unit_of_measurement=UNIT_PERCENT,
302 | icon=ICON_INVERTER_POWER_LIMIT_VALUE,
303 | accuracy_decimals=0,
304 | device_class=DEVICE_CLASS_POWER_FACTOR,
305 | state_class=STATE_CLASS_MEASUREMENT,
306 | ).extend(
307 | {
308 | cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
309 | }
310 | ),
311 | cv.Optional(CONF_INVERTER_POWER_LIMIT_STATE): binary_sensor.binary_sensor_schema(
312 | icon=ICON_INVERTER_POWER_LIMIT_STATE,
313 | ).extend(
314 | {
315 | cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
316 | }
317 | ),
318 | cv.Optional(CONF_SUPPORTED_MODES): cv.ensure_list(validate_modes),
319 | cv.Optional(CONF_SUPPORTED_SWING_MODES): cv.ensure_list(
320 | validate_swing_modes
321 | ),
322 | cv.Optional(CONF_SUPPORTED_PRESETS): cv.ensure_list(validate_presets),
323 | cv.Optional(CONF_CUSTOM_PRESETS): cv.ensure_list(validate_custom_presets),
324 | cv.Optional(CONF_CUSTOM_FAN_MODES): cv.ensure_list(
325 | validate_custom_fan_modes
326 | ),
327 | }
328 | )
329 | .extend(uart.UART_DEVICE_SCHEMA)
330 | .extend(cv.COMPONENT_SCHEMA),
331 | output_info,
332 | )
333 |
334 |
335 | async def to_code(config):
336 | CORE.add_define(
337 | Define("AUX_AC_FIRMWARE_VERSION", '"'+AUX_AC_FIRMWARE_VERSION+'"')
338 | )
339 | CORE.add_define(
340 | Define("AUX_AC_PACKET_TIMEOUT_MIN", AC_PACKET_TIMEOUT_MIN)
341 | )
342 | CORE.add_define(
343 | Define("AUX_AC_PACKET_TIMEOUT_MAX", AC_PACKET_TIMEOUT_MAX)
344 | )
345 | CORE.add_define(
346 | Define("AUX_AC_MIN_INVERTER_POWER_LIMIT", AC_POWER_LIMIT_MIN)
347 | )
348 | CORE.add_define(
349 | Define("AUX_AC_MAX_INVERTER_POWER_LIMIT", AC_POWER_LIMIT_MAX)
350 | )
351 | var = cg.new_Pvariable(config[CONF_ID])
352 | await cg.register_component(var, config)
353 | await climate.register_climate(var, config)
354 |
355 | parent = await cg.get_variable(config[CONF_UART_ID])
356 | cg.add(var.initAC(parent))
357 |
358 | if CONF_INDOOR_TEMPERATURE in config:
359 | conf = config[CONF_INDOOR_TEMPERATURE]
360 | sens = await sensor.new_sensor(conf)
361 | cg.add(var.set_indoor_temperature_sensor(sens))
362 |
363 | if CONF_OUTDOOR_TEMPERATURE in config:
364 | conf = config[CONF_OUTDOOR_TEMPERATURE]
365 | sens = await sensor.new_sensor(conf)
366 | cg.add(var.set_outdoor_temperature_sensor(sens))
367 |
368 | if CONF_OUTBOUND_TEMPERATURE in config:
369 | conf = config[CONF_OUTBOUND_TEMPERATURE]
370 | sens = await sensor.new_sensor(conf)
371 | cg.add(var.set_outbound_temperature_sensor(sens))
372 |
373 | if CONF_INBOUND_TEMPERATURE in config:
374 | conf = config[CONF_INBOUND_TEMPERATURE]
375 | sens = await sensor.new_sensor(conf)
376 | cg.add(var.set_inbound_temperature_sensor(sens))
377 |
378 | if CONF_COMPRESSOR_TEMPERATURE in config:
379 | conf = config[CONF_COMPRESSOR_TEMPERATURE]
380 | sens = await sensor.new_sensor(conf)
381 | cg.add(var.set_compressor_temperature_sensor(sens))
382 |
383 | if CONF_VLOUVER_STATE in config:
384 | conf = config[CONF_VLOUVER_STATE]
385 | sens = await sensor.new_sensor(conf)
386 | cg.add(var.set_vlouver_state_sensor(sens))
387 |
388 | if CONF_DISPLAY_STATE in config:
389 | conf = config[CONF_DISPLAY_STATE]
390 | sens = await binary_sensor.new_binary_sensor(conf)
391 | cg.add(var.set_display_sensor(sens))
392 |
393 | if CONF_DEFROST_STATE in config:
394 | conf = config[CONF_DEFROST_STATE]
395 | sens = await binary_sensor.new_binary_sensor(conf)
396 | cg.add(var.set_defrost_state(sens))
397 |
398 | if CONF_INVERTER_POWER in config:
399 | conf = config[CONF_INVERTER_POWER]
400 | sens = await sensor.new_sensor(conf)
401 | cg.add(var.set_inverter_power_sensor(sens))
402 |
403 | if CONF_PRESET_REPORTER in config:
404 | conf = config[CONF_PRESET_REPORTER]
405 | sens = await text_sensor.new_text_sensor(conf)
406 | cg.add(var.set_preset_reporter_sensor(sens))
407 |
408 | if CONF_INVERTER_POWER_LIMIT_VALUE in config:
409 | conf = config[CONF_INVERTER_POWER_LIMIT_VALUE]
410 | sens = await sensor.new_sensor(conf)
411 | cg.add(var.set_inverter_power_limit_value_sensor(sens))
412 |
413 | if CONF_INVERTER_POWER_LIMIT_STATE in config:
414 | conf = config[CONF_INVERTER_POWER_LIMIT_STATE]
415 | sens = await binary_sensor.new_binary_sensor(conf)
416 | cg.add(var.set_inverter_power_limit_state_sensor(sens))
417 |
418 | cg.add(var.set_period(config[CONF_PERIOD].total_milliseconds))
419 | cg.add(var.set_show_action(config[CONF_SHOW_ACTION]))
420 | cg.add(var.set_display_inverted(config[CONF_DISPLAY_INVERTED]))
421 | cg.add(var.set_packet_timeout(config[CONF_TIMEOUT]))
422 | cg.add(var.set_optimistic(config[CONF_OPTIMISTIC]))
423 | if CONF_SUPPORTED_MODES in config:
424 | cg.add(var.set_supported_modes(config[CONF_SUPPORTED_MODES]))
425 | if CONF_SUPPORTED_SWING_MODES in config:
426 | cg.add(var.set_supported_swing_modes(config[CONF_SUPPORTED_SWING_MODES]))
427 | if CONF_SUPPORTED_PRESETS in config:
428 | cg.add(var.set_supported_presets(config[CONF_SUPPORTED_PRESETS]))
429 | if CONF_CUSTOM_PRESETS in config:
430 | cg.add(var.set_custom_presets(config[CONF_CUSTOM_PRESETS]))
431 | if CONF_CUSTOM_FAN_MODES in config:
432 | cg.add(var.set_custom_fan_modes(config[CONF_CUSTOM_FAN_MODES]))
433 |
434 |
435 | DISPLAY_ACTION_SCHEMA = maybe_simple_id(
436 | {
437 | cv.Required(CONF_ID): cv.use_id(AirCon),
438 | }
439 | )
440 |
441 |
442 | @automation.register_action(
443 | "aux_ac.display_off", AirConDisplayOffAction, DISPLAY_ACTION_SCHEMA
444 | )
445 | async def display_off_to_code(config, action_id, template_arg, args):
446 | paren = await cg.get_variable(config[CONF_ID])
447 | return cg.new_Pvariable(action_id, template_arg, paren)
448 |
449 |
450 | @automation.register_action(
451 | "aux_ac.display_on", AirConDisplayOnAction, DISPLAY_ACTION_SCHEMA
452 | )
453 | async def display_on_to_code(config, action_id, template_arg, args):
454 | paren = await cg.get_variable(config[CONF_ID])
455 | return cg.new_Pvariable(action_id, template_arg, paren)
456 |
457 |
458 | VLOUVER_ACTION_SCHEMA = maybe_simple_id(
459 | {
460 | cv.Required(CONF_ID): cv.use_id(AirCon),
461 | }
462 | )
463 |
464 |
465 | @automation.register_action(
466 | "aux_ac.vlouver_stop", AirConVLouverStopAction, VLOUVER_ACTION_SCHEMA
467 | )
468 | async def vlouver_stop_to_code(config, action_id, template_arg, args):
469 | paren = await cg.get_variable(config[CONF_ID])
470 | return cg.new_Pvariable(action_id, template_arg, paren)
471 |
472 |
473 | @automation.register_action(
474 | "aux_ac.vlouver_swing", AirConVLouverSwingAction, VLOUVER_ACTION_SCHEMA
475 | )
476 | async def vlouver_swing_to_code(config, action_id, template_arg, args):
477 | paren = await cg.get_variable(config[CONF_ID])
478 | return cg.new_Pvariable(action_id, template_arg, paren)
479 |
480 |
481 | @automation.register_action(
482 | "aux_ac.vlouver_top", AirConVLouverTopAction, VLOUVER_ACTION_SCHEMA
483 | )
484 | async def vlouver_top_to_code(config, action_id, template_arg, args):
485 | paren = await cg.get_variable(config[CONF_ID])
486 | return cg.new_Pvariable(action_id, template_arg, paren)
487 |
488 |
489 | @automation.register_action(
490 | "aux_ac.vlouver_middle_above", AirConVLouverMiddleAboveAction, VLOUVER_ACTION_SCHEMA
491 | )
492 | async def vlouver_middle_above_to_code(config, action_id, template_arg, args):
493 | paren = await cg.get_variable(config[CONF_ID])
494 | return cg.new_Pvariable(action_id, template_arg, paren)
495 |
496 |
497 | @automation.register_action(
498 | "aux_ac.vlouver_middle", AirConVLouverMiddleAction, VLOUVER_ACTION_SCHEMA
499 | )
500 | async def vlouver_middle_to_code(config, action_id, template_arg, args):
501 | paren = await cg.get_variable(config[CONF_ID])
502 | return cg.new_Pvariable(action_id, template_arg, paren)
503 |
504 |
505 | @automation.register_action(
506 | "aux_ac.vlouver_middle_below", AirConVLouverMiddleBelowAction, VLOUVER_ACTION_SCHEMA
507 | )
508 | async def vlouver_middle_below_to_code(config, action_id, template_arg, args):
509 | paren = await cg.get_variable(config[CONF_ID])
510 | return cg.new_Pvariable(action_id, template_arg, paren)
511 |
512 |
513 | @automation.register_action(
514 | "aux_ac.vlouver_bottom", AirConVLouverBottomAction, VLOUVER_ACTION_SCHEMA
515 | )
516 | async def vlouver_bottom_to_code(config, action_id, template_arg, args):
517 | paren = await cg.get_variable(config[CONF_ID])
518 | return cg.new_Pvariable(action_id, template_arg, paren)
519 |
520 |
521 | VLOUVER_SET_ACTION_SCHEMA = cv.Schema(
522 | {
523 | cv.Required(CONF_ID): cv.use_id(AirCon),
524 | cv.Required(CONF_POSITION): cv.templatable(cv.int_range(0, 6)),
525 | }
526 | )
527 |
528 |
529 | @automation.register_action(
530 | "aux_ac.vlouver_set", AirConVLouverSetAction, VLOUVER_SET_ACTION_SCHEMA
531 | )
532 | async def vlouver_set_to_code(config, action_id, template_arg, args):
533 | paren = await cg.get_variable(config[CONF_ID])
534 | var = cg.new_Pvariable(action_id, template_arg, paren)
535 | template_ = await cg.templatable(config[CONF_POSITION], args, int)
536 | cg.add(var.set_value(template_))
537 | return var
538 |
539 |
540 | POWER_LIMITATION_OFF_ACTION_SCHEMA = maybe_simple_id(
541 | {
542 | cv.Required(CONF_ID): cv.use_id(AirCon),
543 | }
544 | )
545 |
546 |
547 | @automation.register_action(
548 | "aux_ac.power_limit_off", AirConPowerLimitationOffAction, POWER_LIMITATION_OFF_ACTION_SCHEMA
549 | )
550 | async def power_limit_off_to_code(config, action_id, template_arg, args):
551 | paren = await cg.get_variable(config[CONF_ID])
552 | return cg.new_Pvariable(action_id, template_arg, paren)
553 |
554 |
555 | POWER_LIMITATION_ON_ACTION_SCHEMA = cv.Schema(
556 | {
557 | cv.Required(CONF_ID): cv.use_id(AirCon),
558 | cv.Optional(CONF_LIMIT, default=AC_POWER_LIMIT_MIN): validate_power_limit_range,
559 | }
560 | )
561 |
562 |
563 | @automation.register_action(
564 | "aux_ac.power_limit_on", AirConPowerLimitationOnAction, POWER_LIMITATION_ON_ACTION_SCHEMA
565 | )
566 | async def power_limit_on_to_code(config, action_id, template_arg, args):
567 | paren = await cg.get_variable(config[CONF_ID])
568 | var = cg.new_Pvariable(action_id, template_arg, paren)
569 | template_ = await cg.templatable(config[CONF_LIMIT], args, int)
570 | cg.add(var.set_value(template_))
571 | return var
572 |
573 |
574 | # *********************************************************************************************************
575 | # ВАЖНО! Только для инженеров!
576 | # Вызывайте метод aux_ac.send_packet только если понимаете, что делаете! Он не проверяет данные, а передаёт
577 | # кондиционеру всё как есть. Какой эффект получится от передачи кондиционеру рандомных байт, никто не знает.
578 | # Вы действуете на свой страх и риск.
579 | # *********************************************************************************************************
580 | SEND_TEST_PACKET_ACTION_SCHEMA = maybe_simple_id(
581 | {
582 | cv.Required(CONF_ID): cv.use_id(AirCon),
583 | cv.Required(CONF_DATA): cv.templatable(validate_raw_data),
584 | }
585 | )
586 |
587 |
588 | @automation.register_action(
589 | "aux_ac.send_packet", AirConSendTestPacketAction, SEND_TEST_PACKET_ACTION_SCHEMA
590 | )
591 | async def send_packet_to_code(config, action_id, template_arg, args):
592 | paren = await cg.get_variable(config[CONF_ID])
593 | var = cg.new_Pvariable(action_id, template_arg, paren)
594 |
595 | data = config[CONF_DATA]
596 | if isinstance(data, bytes):
597 | data = list(data)
598 |
599 | if cg.is_template(data):
600 | templ = await cg.templatable(data, args, cg.std_vector.template(cg.uint8))
601 | cg.add(var.set_data_template(templ))
602 | else:
603 | cg.add(var.set_data_static(data))
604 |
605 | return var
606 |
--------------------------------------------------------------------------------
/docs/AC_TESTED.md:
--------------------------------------------------------------------------------
1 | ## Tested and compatible air conditioners ##
2 | `Aux_ac` has been tested and works successfully with the air conditioners from the list below.
3 | Кондиционеры из списка ниже протестированы и точно совместимы с `aux_ac`.
4 |
5 | + ANDE (models: AND-12/FA+)
6 | + Argo (models: Greenstyle 9000, Greenstyle 12000, Greenstyle 18000)
7 | + AUX (models: ALMD-H48/5DR2 / AL-H48/5DR2(U), AMWM-H07/4R1 multisplit, AMWM-H07/4R2(J) multisplit, AMWM-H12/4R2(J) multisplit, AMWM-H12/4R3 multisplit, ASM-H12LL, ASM-H24LD, ASW-H07A4/DE-R1DI, ASW-H07A4/FP-R1DI, ASW-H07A4/JD-R1, ASW-H09A4/FP-R1DI, ASW-H09A4/LK-700R1, ASW-H09A4/LK-700R1DI, ASW-H09B4/LK-700R1, ASW-H09B7A4, ASW-H12A4/FAR1, ASW-H12A4/HA-R2DI, ASW-H12A4/JD-R2DI, ASW-H12B4/JD-R2DI, ASW-H12C5C4/JER3DI-B8-2, ASW-H12C5C4/JOR3DI-B8, ASW-H12U3/JIR1DI-US, ASW-H18A4/QH-R1DI / AS-H18A4/QH-R1DI, AUX-07JO/I / AUX-M3-21LCLH multisplit, AUX-12JO/I / AUX-M3-21LCLHmultisplit, AUX-18QC/I / AUX-18QC/O, AWM-09G1V4-X, HA-18000BTU, KFR-26GW/BpHRB+3, KFR-26GW/BpQYA2+2R3, KFR-26GW/BpQYD2+2R3, KFR-26GW/BpR3QYA1+1, KFR-26GW/BpR3QYD1+1, KFR-26GW/BpR3QYQ1+1, KFR-26GW/BpR3QYQ2+2, KFR-35GW/BpQYA1+1R3, KFR-35GW/BpQYA2+2R3, KFR-35GW/BpQYD1+1R3, KFR-35GW/BpQYD2+2R3, KFR-35GW/BpR3QYQ1+1, KFR-35GW/BpR3QYQ2+2 (see [issue #71](https://github.com/GrKoR/esphome_aux_ac_component/issues/71) for detais of `Aegean Sea`[爱琴海] AUX family AC connection)
8 | + Ballu (models: BLC_CF/in-60HN1 / BLC_O/out-60HN1, BSUI/in-09HN8 / BSUI/out-09HN8, BSUI/in-12HN8 / BSUI/out-12HN8, BSUI/in-18HN8 / BSUI/out-18HN8, BSW/in-09HN1 / BSW/out-09HN1, BSW/in-12HN1 / BSW/out-12HN1)
9 | + Baymak (models: Elegant Plus 12)
10 | + Centek (models: CT-65A09, CT-65A12, CT-65EDC07, CT-65F09, CT-65F12, CT-65FDC09, CT-65J09, CT-65J12, CT-65K07, CT-65Q09, CT-65Q12, CT-65RDC07, CT-65RDC09, CT-65RDC12, CT-65SDC07, CT-65SDC09, CT-65SDC18, CT-65U13, CT-65U18, CT-65V12, CT-65V24, CT-65X12, CT-65Z10, CT-65Z18)
11 | + Dimstal (model: SMND-QC-12-J-Smart ECO)
12 | + Elgin (models: HWFI09B2IA/ HWFE09B2NA)
13 | + Energolux (models: SAS07L2-A, SAS07L4-A, SAS07M2-AI, SAS09B3-A, SAS09L4-A, SAS09Z4-AI, SAS12BN1-AI, SAS09Z4-AI, SAS18Z4-AI)
14 | + Hyundai (models: H-AR16-07H, H-AR21-07H, H-AR21-09H)
15 | + iClima (models: ICI-09A/IUI-09A)
16 | + Idea (models: ISR-12HR-SA7-DN1 ION)
17 | + IGC (models: RAK-07NH multysplit, RAS-07AX/RAC-07AX, RAS-V09N2X/RAC-V09N2X)
18 | + IKON (models: ASW-H12C5C4/HCR3DI-B8)
19 | + Ishimatsu (models: AVK-09I)
20 | + Loriot (models: LAC-09AS)
21 | + Mirage (models: EWC121E - CWC121E)
22 | + Osaka (models: STVP-12HH3)
23 | + RCool (models: GRA12B0-KSZKLM641)
24 | + Rinnai (models: RINV25RC)
25 | + Roda (models: RS-AL09F, RS-AL24F)
26 | + Rovex (models: RS-07ALS1, RS-09ALS1, RS-12ALS1)
27 | + Royal Clima (models: CO-D 18HNI/CO-E 18HNI, RC-VNR29HN, RCI-SA30HN)
28 | + RVX (models: RS-12ALS)
29 | + Samurai (models: SMA-07HRN1 ION, SMA-09HRN1 ION)
30 | + Subtropic (models: SUB/in-07HN1 / SUB/out-07HN1, SUB/in-09HN1 / SUB/out-09HN1, SUB/in-12HN1 / SUB/out-12HN1)
31 | + Tesla (models: TA35FFML-12410M)
32 | + Tornado (models: ISKA-INV-12 X WIFI EU)
33 | + TOYOTOMI (models: SONZAI THN/THG-A35SZ)
34 | + Vertex (models: Falcon-18A)
35 | + VOX (models: IJO09-SC4D, IVA5-12JR1)
36 | + Xigma (models: XG-SJ56RHA-IDU)
37 | + Zephir (models: ZEL 12000BTU)
38 | + Бирюса (models: B-07DPR/B-07DPQ, B-09FIR/B-09FIQ)
39 |
40 | ## Tested and INCOMPATIBLE air conditioners ##
41 | ACs from the list below are **INCOMPATIBLE** with `aux_ac`.
42 | Кондиционеры из списка ниже протестированы и оказались **НЕСОВМЕСТИМЫ** с компонентом `aux_ac`.
43 |
44 | + Kentatsu (models: KSGMA26HFAN1)
45 | + Royal Clima (models: RCI-PF40HN)
46 |
--------------------------------------------------------------------------------
/docs/HARDWARE-EN.md:
--------------------------------------------------------------------------------
1 | ## Hardware ##
2 | I tested it with an esp8266 chip (esp-12e). Minimal scheme:
3 | 
4 |
5 | At the first time in addition to scheme above IO0 (GPIO0) must be pulled down to GND at the boot and ESPHome can be uploaded through UART0. If your ESPHome configuration contains OTA you can pull up IO0 or leave it floating. All further updates can be uploaded over-the-air.
6 | I leave GPIO0 in air cause I don't see any reason to solder additional components for single use.
7 |
8 | ESP-12E before DC-DC and air conditioner connected:
9 | 
10 |
11 | Air conditioner internal block has a 5-wire or a 4-wire (pseudo-USB) connection to the wifi-module. There are another types of connection too. For example AUX Aegean Sea ( 爱琴海 ), check [issue #71](https://github.com/GrKoR/esphome_aux_ac_component/issues/71) for details.
12 |
13 | ## 5-wire connection
14 | It use [JST SM](https://www.jst-mfg.com/product/pdf/eng/eSM.pdf) connector for 5-wire connection.
15 |
16 | ### Pinout ###
17 | 1. Yellow: +12V..+14V DC. Measured +14.70V max and +13.70V min. Service manual declares up to +16V.
18 | 2. Black: ground.
19 | 3. White: +5V DC (max: +5.63V; min: +4.43V) Enable signal for the 3V3 buck regulator on the OEM module. It goes directly to the air conditioner microcontroller through resistor 1kOhm. It's non used with the EPS module.
20 | 4. Blue: TX of air conditioner. High is +5V.
21 | 5. Red: RX of air conditioner. High is +5V.
22 |
23 | You should feed your ESP **from +12V..+14V line only**! It is prohibited to use +5V line for this purpose.
24 | +5V line is digital signal line and directly goes to conditioner's controller. It can't provide enough power. In worst scenario you probably can burn down your air conditioner controller.
25 |
26 | ## 4-wire connection (pseudo-USB)
27 | For 4-wire connection it is used USB-like connector. It is only physical USB but its pinout is UART with +12V..+14V power line.
28 |
29 | **ATTENTION!** It is incompatible with normal USB devices! Ordinary USB device like USB flash drive will be damaged if it will be plugged in air conditioner USB connector.
30 |
31 | **ATTENTION #2!** Manufacturer was changed power circuit and connector pinout in 2022-2023: power rail has +8.5V DC and TX/RX pins are swapped.
32 |
33 | ### Pinout ###
34 |
35 |
36 | 1. +12V..+14V DC before 2022-2023, possible +8.5V DC after 2022-2023. Service manual declares up to +16V.
37 | 2. RX of the air conditioner for models manufactured before about Jul.2022, TX of the air conditioner for later modifications. High level is +5V.
38 | 3. TX of the air conditioner for models manufactured before about Jul.2022, RX of the air conditioner for later modifications. High level is +5V.
39 | 4. GND - ground.
40 |
41 | Big thanks to [@diabl0](https://github.com/diabl0) for this pinout in [issue #70](https://github.com/GrKoR/esphome_aux_ac_component/issues/70).
42 |
43 | If you are not sure, on which USB-pins do you have RX and TX lines, than don't afraid to connect it randomly. Neither air conditioner nor ESP will be damaged in this situation, just `aux_ac` can't receive data from the air conditioner. Swap TX and RX and your device will probably work.
44 |
45 | ## Power supply
46 |
47 | For power supply it is possible to use any kind of suitable modules. I use this:
48 | .
49 |
50 | ## Connections ##
51 | Black wire of AC's connector goes to the middle pin of the power module and to the GND pin of esp-12e.
52 | Yellow wire is connected to the Vin pin of the power module.
53 | Blue wire is connected to the RXD pin of esp-12e.
54 | Red wire is connected to the TXD pin of esp-12e.
55 |
56 | **ATTENTION!** In case you are using board like NodeMCU instead of clean esp8266/esp32 module, you shouldn't connect RX & TX wires of air conditioner to TX & RX pins of board! *(TXD1/RXD1, TXD2/RXD2 are also most likely not suitable.)* Use any other digital pins for UART connection. It doesn't matter if your board will use hardware or software UART. All UART types are working well.
57 | The usage of alternate pins for NodeMCU-like boards is necessary cause RX & TX lines of this boards are often have additional components like resistors or USB-TTL converters connected. This components are violate esp-to-ac UART connection.
58 |
59 | Here is it:
60 | 
61 |
62 | All connections in custom 3d-printed case looks like this:
63 | 
64 |
65 | Since I didn't have JST SM connectors, I made my own:
66 | .
67 |
68 | It is made of standard 2.54mm pins and 3D-printed case.
69 | All models for 3D-printing are available too: [STL-files for connector](https://github.com/GrKoR/esphome_aux_ac_component/tree/master/enclosure/JST%20SM%20connector), [models of case parts](https://github.com/GrKoR/esphome_aux_ac_component/tree/master/enclosure/case).
70 |
71 | ## The result ##
72 | 
73 | 
74 | 
75 |
--------------------------------------------------------------------------------
/docs/HARDWARE.md:
--------------------------------------------------------------------------------
1 | ## Электроника, необходимая для управления кондиционером по wifi ##
2 | Я тестировал проект на esp8266 (esp-12e). Минимальная обвязка традиционна и выглядит так:
3 | 
4 |
5 | Для прошивки esp8266 в первый раз нужно, в дополнение к обвязке, показанной на схеме выше, притянуть к земле пин IO0 (GPIO0). После этого ESPHome может быть загружена в esp8266 по UART0. Если при этом вы указали OTA в конфигурации ESPHome, то в дальнейшем пин IO0 можно подтянуть к питанию или оставить висеть в воздухе. Он никак не будет влиять на загрузку новых прошивок, потому что все апдейты можно будет делать "по воздуху" (то есть по Wi-Fi). Я никуда IO0 не подтягивал и ничего к нему не паял, потому что не вижу смысла это делать ради одного раза. Первую прошивку делал в самодельном переходнике на макетке.
6 |
7 | Плата esp-12e перед подключением кондиционера и модуля питания:
8 | 
9 |
10 | Внутренний блок сплит-системы может иметь 5-проводное или 4-проводное подключение (псевдо-USB) к модулю Wi-Fi. Встречаются и другие виды подключения. Например, AUX Aegean Sea ( 爱琴海 ), за подробностями подключения сюда: [issue #71](https://github.com/GrKoR/esphome_aux_ac_component/issues/71).
11 |
12 | ## 5-проводное подключение
13 | Для 5-проводного подключения используется коннектор [JST SM](https://www.jst-mfg.com/product/pdf/eng/eSM.pdf).
14 |
15 | ### Распиновка ###
16 | 1. Желтый: +12В..+14В постоянного тока. Осциллограф показал от +13.70В до +14.70В. В сервисном мануале встречалось, что питание возможно до +16В.
17 | 2. Черный: земля.
18 | 3. Белый: +5В постоянного тока (измерено от +4.43В до +5.63В). По информации от пользователей, это сигнальная линия, включающая по DC-DC конвертор на wifi-модуле по команде с кондиционера. Линия идет напрямую на ножку контроллера в сплите через резистор 1 кОм. Эксперименты с родным Wi-Fi модулем сплит-системы показали, что эта линия в работе Wi-Fi не участвует и имеет всегда высокий уровень. В работе компонента и самодельного wifi-модуля эта линия не используется.
19 | 4. Синий: TX кондиционера. Высокий уровень +5В.
20 | 5. Red: RX кондиционера. Высокий уровень +5В.
21 |
22 | Питание ESP подключать **ТОЛЬКО** к линии +12В..+14В! Имеющийся в 5-проводном подключении контакт с +5В для питания ESP использоваться не должен. Он является сигнальным, подключен через резистор непосредственно на ногу контроллера на материнской плате кондиционера и способен выдавать лишь мизерный ток. При неудачном стечении обстоятельств, повесив питание ESP на эту линию, можно сжечь мозги кондиционеру.
23 |
24 | ## 4-проводное подключение (псевдо-USB)
25 | Для 4-проводного подключения используется USB-коннектор. От настоящего USB здесь только коннектор. По пинам в этом разъеме UART и +12В..+14В питание.
26 |
27 | **ВНИМАНИЕ!** С устройствами c настоящим USB этот интерфейс не совместим! Если вставить в разъём обычную USB-флешку или другое устройство, скорее всего оно просто сгорит.
28 |
29 | **ВНИМАНИЕ №2!** В 2022-2023 производитель поменял распиновку и схему питания. Теперь кондиционеры на USB-коннектор выдают +8.5В. А пины RX и TX поменялись местами.
30 |
31 | ### Распиновка ###
32 |
33 |
34 | 1. +12В..+14В постоянного тока для кондиционеров до 2023 года, возможно +8.5В для кондиционеров 2022-2023 годов и моложе. В сервисном мануале на кондиционеры до 2022 года встречалось, что питание возможно до +16В.
35 | 2. RX кондиционера для моделей, произведенных примерно до 07.2022, TX кондиционера для более поздних модификаций. Высокий уровень +5В.
36 | 3. TX кондиционера для моделей, произведенных примерно до 07.2022, RX кондиционера для более поздних модификаций. Высокий уровень +5В.
37 | 4. земля.
38 |
39 | Большое спасибо [@diabl0](https://github.com/diabl0) за эту распиновку ([issue #70](https://github.com/GrKoR/esphome_aux_ac_component/issues/70)).
40 |
41 | Если вы не знаете, на каких именно пинах USB-разъема в вашем случае расположены TX и RX, то не бойтесь подключить наугад. Ни кондиционер, ни ESP не пострадают, если вы перепутаете линии TX и RX. Просто компонент не увидит кондиционер, о чем будут сообщения в логе. В таком случае просто попробуйте поменять TX и RX местами.
42 |
43 | ## Питание
44 |
45 | Для питания ESP8266 можно использовать любой подходящий DC-DC преобразователь. Я использовал такой:
46 | .
47 |
48 | ## Подключение ##
49 | Черный провод (земля) подключается к земле DC-DC преобразователя и к пину GND модуля ESP8266.
50 | Желтый провод подключается ко входу DC-DC преобразователя (в моём случае контакт Vin).
51 | Синий провод подключается к пину RXD модуля esp-12e.
52 | Красный провод подключается к пину TXD модуля esp-12e.
53 |
54 | **ВНИМАНИЕ!** Если вы используете не голый модуль esp32/esp8266, а плату типа NodeMCU, то не подключайте провода TX и RX кондиционера к пинам TX и RX платы! *(TXD1/RXD1, TXD2/RXD2 также скорее всего не подойдут.)* Используйте любые другие свободные пины для UART. При этом для ESP8266 UART будет программный, но это не страшно. Ресурсов ESP8266 хватит для работы.
55 | Использовать альтернативные пины для плат типа NodeMCU необходимо потому, что часто на линиях RX и TX этих плат установлены резисторы, а также на этих пинах висит USB-TTL конвертер (если он есть на плате). Эти компоненты мешают ESP наладить соединение с кондиционером.
56 |
57 |
58 | Вот схема всех соединений:
59 | 
60 |
61 | Вот так это выглядит внутри самодельного корпуса:
62 | 
63 |
64 | Поскольку у меня не было под рукой коннекторов JST SM, а ехать искать их не хотелось, я сделал свой собственный из стандартных пинов с шагом 2,54 мм и нескольких напечатанных на 3D-принтере деталей:
65 | .
66 |
67 | Все относящиеся к проекту модели для 3D-принтера также доступны: [STL-файлы коннектора](https://github.com/GrKoR/esphome_aux_ac_component/tree/master/enclosure/JST%20SM%20connector), [модельки частей корпуса](https://github.com/GrKoR/esphome_aux_ac_component/tree/master/enclosure/case).
68 |
69 | ## Конечный результат ##
70 | 
71 | 
72 | 
73 |
--------------------------------------------------------------------------------
/docs/HOW_TO_FEATURE_REQUEST-EN.md:
--------------------------------------------------------------------------------
1 | # How to request a feature for a component #
2 |
3 | With any functions, the alignment is such that they simply cannot be written down by name.
4 | We need a log from someone who has air conditioner with such functions. If you are such a person, then you can help yourself and the community.
5 |
6 | To capture the log you need to do the following steps:
7 | 1. Run a specially written [tool](https://github.com/GrKoR/ac_python_logger) to collect logs.
8 | 2. Turn on the AC.
9 | 3. Wait 10+ seconds. (During this time, the ESP will receive all packets from AC).
10 | 4. Turn on the desired function using AC's IR remote.
11 | 5. Wait 10+ seconds ones more. While you are waiting, you can write down what you have done.
12 | 6. Turn off the desired function.
13 | 7. Wait 10+ seconds again and write down what you've done.
14 | 8. Repeat steps 4..7 for all other functions you interested in.
15 | 9. Stop the log recording with a script.
16 | 10. Send collected log and your notes (explanations to the log) to [issues](https://github.com/GrKoR/esphome_aux_ac_component/issues) or to [telegram chat](https://t.me/aux_ac).
17 |
18 | Instead of a Python script from the step #1, you can simply save the logs from the esphome web-interface with copy-paste or from the command line, but there is a lot of extra stuff there. And it's easy to miss something. But in principle, it is also quite a working option.
--------------------------------------------------------------------------------
/docs/HOW_TO_FEATURE_REQUEST.md:
--------------------------------------------------------------------------------
1 | # Как запросить расширение функционала компонента #
2 |
3 | С любыми новыми функциями кондиционера ситуация такая, что просто по названию из инструкции или с пульта их не сделать. Нужен лог от владельца кондиционера, у кого такие функции есть. Если вы такой владелей, то можете помочь себе и сообществу.
4 |
5 | Последовательность действий такая:
6 | 1. Запускате специально написанную [тулзу](https://github.com/GrKoR/ac_python_logger) для сбора логов.
7 | 2. Включете кондиционер.
8 | 3. Ждёте 10+ секунд, чтобы все возможные типы пакетов прошли по UART на ESP.
9 | 4. Включаете нужную функцию с помощью ИК-пульта.
10 | 5. Опять ждёте 10+ секунд. Во время ожидания можно записать в отдельный текстовый файл или на бумажку, что именно сделано.
11 | 6. Выключаете нужную функцию.
12 | 7. Опять ждёте 10+ секунд, не забывая записывать комментарии по сделанному.
13 | 8. Повторяете шаги 4..7 для всех других функций, которые хочется иметь в компоненте `aux_ac`.
14 | 9. Останавливаете запись лога.
15 | 10. Отправляете собранный лог и свои заметки (пояснения к логу) в [issues](https://github.com/GrKoR/esphome_aux_ac_component/issues) или в [телеграм](https://t.me/aux_ac).
16 |
17 | Вместо использования Python-скрипта можно логи из веб-интерфейса esphome сохранять копипастом или из командной строки. Но там много лишнего шлётся и легко что-то пропустить. Но в принципе это тоже вполне рабочий вариант.
--------------------------------------------------------------------------------
/enclosure/JST SM connector/pin-cap.stl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GrKoR/esphome_aux_ac_component/7a252e5955f075b66460de25deffc8c2ed266569/enclosure/JST SM connector/pin-cap.stl
--------------------------------------------------------------------------------
/enclosure/JST SM connector/pin-cover.stl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GrKoR/esphome_aux_ac_component/7a252e5955f075b66460de25deffc8c2ed266569/enclosure/JST SM connector/pin-cover.stl
--------------------------------------------------------------------------------
/enclosure/JST SM connector/pin-main.stl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GrKoR/esphome_aux_ac_component/7a252e5955f075b66460de25deffc8c2ed266569/enclosure/JST SM connector/pin-main.stl
--------------------------------------------------------------------------------
/enclosure/case/aircon_cap.stl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GrKoR/esphome_aux_ac_component/7a252e5955f075b66460de25deffc8c2ed266569/enclosure/case/aircon_cap.stl
--------------------------------------------------------------------------------
/enclosure/case/aircon_case.stl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GrKoR/esphome_aux_ac_component/7a252e5955f075b66460de25deffc8c2ed266569/enclosure/case/aircon_case.stl
--------------------------------------------------------------------------------
/examples/advanced/.gitignore:
--------------------------------------------------------------------------------
1 | # Gitignore settings for ESPHome
2 | # This is an example and may include too much for your use-case.
3 | # You can modify this file to suit your needs.
4 | /.esphome/
5 | **/.pioenvs/
6 | **/.piolibdeps/
7 | **/lib/
8 | **/src/
9 | **/platformio.ini
10 | /secrets.yaml
11 |
--------------------------------------------------------------------------------
/examples/advanced/ac_common.yaml:
--------------------------------------------------------------------------------
1 | # DON'T COMPILE THIS FILE
2 | # This file contains common settings for all air conditioners of your house
3 | external_components:
4 | - source: github://GrKoR/esphome_aux_ac_component
5 | components: [ aux_ac ]
6 | refresh: 0s
7 |
8 | esphome:
9 | name: $devicename
10 | platform: ESP8266
11 | board: esp12e
12 |
13 | wifi:
14 | ssid: !secret wifi_ssid
15 | password: !secret wifi_pass
16 | manual_ip:
17 | static_ip: ${wifi_ip}
18 | gateway: !secret wifi_gateway
19 | subnet: !secret wifi_subnet
20 | ap:
21 | ssid: ${upper_devicename} Hotspot
22 | password: !secret wifi_ap_pass
23 | use_address: ${wifi_ota_ip}
24 |
25 | captive_portal:
26 | debug:
27 |
28 | logger:
29 | level: DEBUG
30 | baud_rate: 0
31 | # set hardware_uart to UART1 and comment out baud_rate above in case of boot crashes
32 | # it is suitable if you need hardware loggin
33 | # hardware_uart: UART1
34 |
35 | api:
36 | password: !secret api_pass
37 |
38 | ota:
39 | - platform: esphome
40 | password: !secret ota_pass
41 |
42 | web_server:
43 | port: 80
44 | auth:
45 | username: !secret web_server_user
46 | password: !secret web_server_password
47 |
48 | # UART0 configuration for AUX air conditioner communication
49 | uart:
50 | id: ac_uart_bus
51 | # ATTENTION! Use GPIO4 (D2) and GPIO5 (D1) as the TX and RX for NodeMCU-like boards!
52 | tx_pin: GPIO1
53 | rx_pin: GPIO3
54 | baud_rate: 4800
55 | data_bits: 8
56 | parity: EVEN
57 | stop_bits: 1
58 |
59 |
60 |
61 | climate:
62 | - platform: aux_ac
63 | name: ${upper_devicename}
64 | id: aux_id
65 | uart_id: ac_uart_bus
66 | period: 7s
67 | show_action: true
68 | display_inverted: true
69 | optimistic: true
70 | indoor_temperature:
71 | name: ${upper_devicename} Indoor Temperature
72 | id: ${devicename}_indoor_temp
73 | internal: false
74 | display_state:
75 | name: ${upper_devicename} Display State
76 | id: ${devicename}_display_state
77 | internal: false
78 | outdoor_temperature:
79 | name: ${upper_devicename} Outdoor Temperature
80 | id: ${devicename}_outdoor_temp
81 | internal: false
82 | outbound_temperature:
83 | name: ${upper_devicename} Coolant Outbound Temperature
84 | id: ${devicename}_outbound_temp
85 | internal: false
86 | inbound_temperature:
87 | name: ${upper_devicename} Coolant Inbound Temperature
88 | id: ${devicename}_inbound_temp
89 | internal: false
90 | compressor_temperature:
91 | name: ${upper_devicename} Compressor Temperature
92 | id: ${devicename}_strange_temp
93 | internal: false
94 | defrost_state:
95 | name: ${upper_devicename} Defrost State
96 | id: ${devicename}_defrost_state
97 | internal: false
98 | inverter_power:
99 | name: ${upper_devicename} Invertor Power
100 | id: ${devicename}_inverter_power
101 | internal: false
102 | preset_reporter:
103 | name: ${upper_devicename} Preset Reporter
104 | id: ${devicename}_preset_reporter
105 | internal: false
106 | vlouver_state:
107 | name: ${upper_devicename} VLouvers State
108 | id: ${devicename}_vlouver_state
109 | internal: false
110 | visual:
111 | min_temperature: 16
112 | max_temperature: 32
113 | temperature_step: 0.5
114 | supported_modes:
115 | - HEAT_COOL
116 | - COOL
117 | - HEAT
118 | - DRY
119 | - FAN_ONLY
120 | custom_fan_modes:
121 | - MUTE
122 | - TURBO
123 | supported_presets:
124 | - SLEEP
125 | custom_presets:
126 | - CLEAN
127 | - HEALTH
128 | - ANTIFUNGUS
129 | supported_swing_modes:
130 | - VERTICAL
131 | - HORIZONTAL
132 | - BOTH
133 |
134 |
135 | sensor:
136 | # just wifi signal strength for debug purpose only
137 | - platform: wifi_signal
138 | name: ${upper_devicename} WiFi Signal
139 | update_interval: 30s
140 | unit_of_measurement: "dBa"
141 | accuracy_decimals: 0
142 |
143 | - platform: uptime
144 | name: ${upper_devicename} Uptime Sensor
145 |
146 | switch:
147 | - platform: template
148 | name: ${upper_devicename} Display
149 | lambda: |-
150 | if (id(${devicename}_display_state).state) {
151 | return true;
152 | } else {
153 | return false;
154 | }
155 | turn_on_action:
156 | - aux_ac.display_on: aux_id
157 | turn_off_action:
158 | - aux_ac.display_off: aux_id
159 |
160 | button:
161 | - platform: template
162 | name: ${upper_devicename} VLouver Stop
163 | icon: "mdi:circle-small"
164 | on_press:
165 | - aux_ac.vlouver_stop: aux_id
166 |
167 | - platform: template
168 | name: ${upper_devicename} VLouver Swing
169 | icon: "mdi:pan-vertical"
170 | on_press:
171 | - aux_ac.vlouver_swing: aux_id
172 |
173 | - platform: template
174 | name: ${upper_devicename} VLouver Top
175 | icon: "mdi:pan-up"
176 | on_press:
177 | - aux_ac.vlouver_top: aux_id
178 |
179 | - platform: template
180 | name: ${upper_devicename} VLouver Middle Above
181 | icon: "mdi:pan-top-left"
182 | on_press:
183 | - aux_ac.vlouver_middle_above: aux_id
184 |
185 | - platform: template
186 | name: ${upper_devicename} VLouver Middle
187 | icon: "mdi:pan-left"
188 | on_press:
189 | - aux_ac.vlouver_middle: aux_id
190 |
191 | - platform: template
192 | name: ${upper_devicename} VLouver Middle Below
193 | icon: "mdi:pan-bottom-left"
194 | on_press:
195 | - aux_ac.vlouver_middle_below: aux_id
196 |
197 | - platform: template
198 | name: ${upper_devicename} VLouver Bottom
199 | icon: "mdi:pan-down"
200 | on_press:
201 | - aux_ac.vlouver_bottom: aux_id
202 |
203 |
204 | number:
205 | - platform: template
206 | name: ${upper_devicename} Vertical Louvers
207 | id: ${devicename}_vlouver
208 | icon: "mdi:circle-small"
209 | mode: "slider"
210 | min_value: 0
211 | max_value: 6
212 | step: 1
213 | update_interval: 2s
214 | lambda: |-
215 | return id(${devicename}_vlouver_state).state;
216 | set_action:
217 | then:
218 | - aux_ac.vlouver_set:
219 | id: aux_id
220 | position: !lambda "return x;"
221 |
222 | - platform: template
223 | name: ${upper_devicename} Power Limit
224 | id: ${devicename}_power_limit
225 | icon: "mdi:battery-unknown"
226 | mode: "slider"
227 | min_value: 30
228 | max_value: 100
229 | step: 1
230 | set_action:
231 | then:
232 | - lambda: !lambda "id(aux_id).powerLimitationOnSequence( x );"
233 |
--------------------------------------------------------------------------------
/examples/advanced/ac_kitchen.yaml:
--------------------------------------------------------------------------------
1 | # compile this file with ESPHome
2 | # This file contains unique settings for specific air conditioner
3 |
4 | #===================================================================================
5 | # KITCHEN AIR CONDITIONER
6 | #===================================================================================
7 |
8 | substitutions:
9 | devicename: kitchen_ac
10 | upper_devicename: Kitchen AC
11 |
12 | # use different wifi_ip and wifi_ota_ip in case of esp ip-address change
13 | # if ip haven't changed wifi_ip and wifi_ota_ip should be the same
14 | wifi_ip: !secret wifi_ip_kitchen
15 | wifi_ota_ip: !secret wifi_ota_ip_kitchen
16 |
17 | <<: !include ac_common.yaml
--------------------------------------------------------------------------------
/examples/advanced/ac_livingroom.yaml:
--------------------------------------------------------------------------------
1 | # compile this file with ESPHome
2 | # This file contains unique settings for specific air conditioner
3 |
4 | #===================================================================================
5 | # LIVINGROOM AIR CONDITIONER
6 | #===================================================================================
7 |
8 | substitutions:
9 | devicename: livingroom_ac
10 | upper_devicename: Livingroom AC
11 |
12 | # use different wifi_ip and wifi_ota_ip in case of esp ip-address change
13 | # if ip haven't changed wifi_ip and wifi_ota_ip should be the same
14 | wifi_ip: !secret wifi_ip_livingroom
15 | wifi_ota_ip: !secret wifi_ota_ip_livingroom
16 |
17 | <<: !include ac_common.yaml
--------------------------------------------------------------------------------
/examples/simple/.gitignore:
--------------------------------------------------------------------------------
1 | # Gitignore settings for ESPHome
2 | # This is an example and may include too much for your use-case.
3 | # You can modify this file to suit your needs.
4 | /.esphome/
5 | **/.pioenvs/
6 | **/.piolibdeps/
7 | **/lib/
8 | **/src/
9 | **/platformio.ini
10 | /secrets.yaml
11 |
--------------------------------------------------------------------------------
/examples/simple/aux_ac_simple.yaml:
--------------------------------------------------------------------------------
1 | external_components:
2 | - source: github://GrKoR/esphome_aux_ac_component
3 | components: [ aux_ac ]
4 | refresh: 0s
5 |
6 | esphome:
7 | name: aux_air_conditioner
8 | platform: ESP8266
9 | board: esp12e
10 |
11 | # don't forget to set your's wifi settings!
12 | wifi:
13 | ssid: "WIFI SSID"
14 | password: "seCRETpassWORD"
15 | manual_ip:
16 | static_ip: 192.168.0.2
17 | gateway: 192.168.0.1
18 | subnet: 255.255.255.0
19 | ap:
20 | ssid: AUX Hotspot
21 | password: "seCREThotSPOTpassWORD"
22 |
23 | captive_portal:
24 | debug:
25 |
26 | logger:
27 | level: DEBUG
28 | baud_rate: 0
29 |
30 | api:
31 |
32 | ota:
33 | - platform: esphome
34 |
35 | # UART0 configuration for AUX air conditioner communication
36 | uart:
37 | id: ac_uart_bus
38 | # ATTENTION! Use GPIO4 (D2) and GPIO5 (D1) as the TX and RX for NodeMCU-like boards!
39 | tx_pin: GPIO1
40 | rx_pin: GPIO3
41 | baud_rate: 4800
42 | data_bits: 8
43 | parity: EVEN
44 | stop_bits: 1
45 |
46 | climate:
47 | - platform: aux_ac
48 | name: "AC Name"
--------------------------------------------------------------------------------
/images/DD4012SA.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GrKoR/esphome_aux_ac_component/7a252e5955f075b66460de25deffc8c2ed266569/images/DD4012SA.jpg
--------------------------------------------------------------------------------
/images/USB-pinout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GrKoR/esphome_aux_ac_component/7a252e5955f075b66460de25deffc8c2ed266569/images/USB-pinout.png
--------------------------------------------------------------------------------
/images/assembled.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GrKoR/esphome_aux_ac_component/7a252e5955f075b66460de25deffc8c2ed266569/images/assembled.JPG
--------------------------------------------------------------------------------
/images/connections.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GrKoR/esphome_aux_ac_component/7a252e5955f075b66460de25deffc8c2ed266569/images/connections.png
--------------------------------------------------------------------------------
/images/connector.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GrKoR/esphome_aux_ac_component/7a252e5955f075b66460de25deffc8c2ed266569/images/connector.JPG
--------------------------------------------------------------------------------
/images/esp-12e.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GrKoR/esphome_aux_ac_component/7a252e5955f075b66460de25deffc8c2ed266569/images/esp-12e.jpg
--------------------------------------------------------------------------------
/images/real-1.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GrKoR/esphome_aux_ac_component/7a252e5955f075b66460de25deffc8c2ed266569/images/real-1.JPG
--------------------------------------------------------------------------------
/images/real-2.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GrKoR/esphome_aux_ac_component/7a252e5955f075b66460de25deffc8c2ed266569/images/real-2.JPG
--------------------------------------------------------------------------------
/images/real-3.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GrKoR/esphome_aux_ac_component/7a252e5955f075b66460de25deffc8c2ed266569/images/real-3.JPG
--------------------------------------------------------------------------------
/images/scheme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GrKoR/esphome_aux_ac_component/7a252e5955f075b66460de25deffc8c2ed266569/images/scheme.png
--------------------------------------------------------------------------------
/tests/.gitignore:
--------------------------------------------------------------------------------
1 | # Gitignore settings for ESPHome
2 | # This is an example and may include too much for your use-case.
3 | # You can modify this file to suit your needs.
4 | /.esphome/
5 | **/.pioenvs/
6 | **/.piolibdeps/
7 | **/lib/
8 | **/src/
9 | **/platformio.ini
10 | /secrets.yaml
11 |
--------------------------------------------------------------------------------
/tests/ac_send_packet_for_engineer.py:
--------------------------------------------------------------------------------
1 | import time
2 | import aioesphomeapi
3 | import asyncio
4 | import re
5 | import sys
6 | import argparse
7 | from aioesphomeapi.api_pb2 import (LOG_LEVEL_NONE,
8 | LOG_LEVEL_ERROR,
9 | LOG_LEVEL_WARN,
10 | LOG_LEVEL_INFO,
11 | LOG_LEVEL_DEBUG,
12 | LOG_LEVEL_VERBOSE,
13 | LOG_LEVEL_VERY_VERBOSE)
14 |
15 | def createParser ():
16 | parser = argparse.ArgumentParser(
17 | description='''This script is used for collecting logs from ac_aux ESPHome component.
18 | For more info, see https://github.com/GrKoR/ac_python_logger''',
19 | add_help = False)
20 | parent_group = parser.add_argument_group (title='Params')
21 | parent_group.add_argument ('--help', '-h', action='help', help='show this help message and exit')
22 | parent_group.add_argument ('-i', '--ip', nargs=1, required=True, help='IP address of the esphome device')
23 | parent_group.add_argument ('-p', '--pwd', nargs=1, required=True, help='native API password for the esphome device')
24 | return parser
25 |
26 | async def main():
27 | """Connect to an ESPHome device and wait for state changes."""
28 | api = aioesphomeapi.APIClient(namespace.ip[0], 6053, namespace.pwd[0])
29 |
30 | try:
31 | await api.connect(login=True)
32 | except aioesphomeapi.InvalidAuthAPIError as e:
33 | return print(e)
34 |
35 | print(api.api_version)
36 |
37 | async def display_off():
38 | await api.execute_service(
39 | service,
40 | data={
41 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
42 | "data_buf": [0xBB, 0x00, 0x06, 0x80, 0x01, 0x00, 0x0F, 0x00, 0x01, 0x01, 0x97, 0xE0, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x00],
43 | }
44 | )
45 |
46 | async def display_on():
47 | await api.execute_service(
48 | service,
49 | data={
50 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
51 | "data_buf": [0xBB, 0x00, 0x06, 0x80, 0x01, 0x00, 0x0F, 0x00, 0x01, 0x01, 0x97, 0xE0, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00],
52 | }
53 | )
54 |
55 | async def ac_enable():
56 | await api.execute_service(
57 | service,
58 | data={
59 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
60 | "data_buf": [0xBB, 0x00, 0x06, 0x80, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x00, 0x87, 0xE0, 0x2F, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00],
61 | }
62 | )
63 |
64 | async def ac_disable():
65 | await api.execute_service(
66 | service,
67 | data={
68 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
69 | "data_buf": [0xBB, 0x00, 0x06, 0x80, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x00, 0x87, 0xE0, 0x2F, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
70 | }
71 | )
72 |
73 | async def ac_get11_01():
74 | await api.execute_service(
75 | service,
76 | data={
77 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
78 | "data_buf": [0xBB, 0x00, 0x06, 0x80, 0x00, 0x00, 0x02, 0x00, 0x11, 0x01],
79 | }
80 | )
81 |
82 | async def ac_get11_00():
83 | await api.execute_service(
84 | service,
85 | data={
86 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
87 | "data_buf": [0xBB, 0x00, 0x06, 0x80, 0x00, 0x00, 0x02, 0x00, 0x11, 0x00],
88 | }
89 | )
90 |
91 | async def ac_set_vlouver(lvr):
92 | await api.execute_service(
93 | service,
94 | data={
95 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
96 | "data_buf": [0xBB, 0x00, 0x06, 0x80, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x01, lvr, 0xE0, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00],
97 | }
98 | )
99 |
100 | async def ac_set_hlouver(lvr):
101 | await api.execute_service(
102 | service,
103 | data={
104 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
105 | "data_buf": [0xBB, 0x00, 0x06, 0x80, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x01, 0x97, lvr, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00],
106 | }
107 | )
108 |
109 | # key надо искать в выводе list_entities_services
110 | service = aioesphomeapi.UserService(
111 | name="send_data",
112 | key=311254518,
113 | args=[
114 | aioesphomeapi.UserServiceArg(name="data_buf", type=aioesphomeapi.UserServiceArgType.INT_ARRAY),
115 | ],
116 | )
117 |
118 | time.sleep(7)
119 | await ac_get11_00()
120 | time.sleep(7)
121 | await ac_get11_01()
122 |
123 | #await ac_set_vlouver( 0b10010000 ) # swing on
124 | #await ac_set_vlouver( 0b10010111 ) # swing off
125 | #await ac_set_vlouver( 0b10010001 ) # 1
126 | #await ac_set_vlouver( 0b10010010 ) # 2
127 | #await ac_set_vlouver( 0b10010011 ) # 3
128 | #await ac_set_vlouver( 0b10010100 ) # 4
129 | #await ac_set_vlouver( 0b10010101 ) # 5
130 | #await ac_set_vlouver( 0b10010110 ) # не работает, сбрасывает на swing on
131 | #time.sleep(5)
132 |
133 | #await ac_set_hlouver( 0b00000000 ) # swing on
134 | #await ac_set_hlouver( 0b11100000 ) # swing off
135 | #await ac_set_hlouver( 0b00100000 ) # не работает, сбрасывает в swing off
136 | #await ac_set_hlouver( 0b01000000 ) # не работает, сбрасывает в swing off
137 | #await ac_set_hlouver( 0b01100000 ) # не работает, сбрасывает в swing off
138 | #await ac_set_hlouver( 0b10000000 ) # не работает, сбрасывает в swing off
139 | #await ac_set_hlouver( 0b10100000 ) # не работает, сбрасывает в swing off
140 | #await ac_set_hlouver( 0b11000000 ) # не работает, сбрасывает в swing off
141 | #time.sleep(5)
142 |
143 | async def test_byte(bt):
144 | await api.execute_service(
145 | service,
146 | data={
147 | #display on
148 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
149 | #"data_buf": [0xBB, 0x00, 0x06, 0x80, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x01, 0x97, 0xE0, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00],
150 | #display off
151 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
152 | "data_buf": [0xBB, 0x00, 0x06, 0x80, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x01, 0x97, 0xE0, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x00],
153 | # swing on
154 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
155 | #"data_buf": [0xBB, 0x00, 0x06, 0x80, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x01, 0x90, 0xE0, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00],
156 | # swing off
157 | # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
158 | #"data_buf": [0xBB, 0x00, 0x06, 0x80, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x01, 0x97, 0xE0, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00],
159 | }
160 | )
161 | '''
162 | не проходит команда, если байт 1 или 7 не 0x00
163 | не проходит команда, если байт 3 не 0x80
164 |
165 | проходит и не меняется, если меняю байт 4 или 5
166 | '''
167 |
168 | #await test_byte(0b10000110)
169 | #await test_byte(0b01000110)
170 | #await test_byte(0b00100110)
171 | #await test_byte(0b00010110)
172 | time.sleep(2)
173 |
174 |
175 | parser = createParser()
176 | namespace = parser.parse_args()
177 | print("IP: ", namespace.ip[0])
178 |
179 |
180 | loop = asyncio.get_event_loop()
181 | try:
182 | #asyncio.ensure_future(main())
183 | #loop.run_forever()
184 | loop.run_until_complete(main())
185 | except aioesphomeapi.InvalidAuthAPIError as e:
186 | print(e)
187 | except KeyboardInterrupt:
188 | pass
189 | finally:
190 | loop.close()
191 | pass
--------------------------------------------------------------------------------
/tests/test-ext-esp32.yaml:
--------------------------------------------------------------------------------
1 | external_components:
2 | - source: github://GrKoR/esphome_aux_ac_component@dev
3 | components: [ aux_ac ]
4 | refresh: 0s
5 |
6 | substitutions:
7 | devicename: test_aux_ac_ext_esp32
8 | upper_devicename: Test AUX
9 |
10 | esphome:
11 | name: $devicename
12 | platform: ESP32
13 | board: nodemcu-32s
14 |
15 | wifi:
16 | ssid: !secret wifi_ssid
17 | password: !secret wifi_pass
18 | manual_ip:
19 | static_ip: 192.168.0.151 # Для примера
20 | gateway: !secret wifi_gateway
21 | subnet: !secret wifi_subnet
22 | dns1: 8.8.8.8
23 | dns2: 1.1.1.1
24 | reboot_timeout: 0s
25 | ap:
26 | ssid: Test AUX Fallback Hotspot
27 | password: !secret wifi_ap_pass
28 |
29 | logger:
30 | level: DEBUG
31 | baud_rate: 0
32 |
33 | api:
34 | password: !secret api_pass
35 | reboot_timeout: 0s
36 |
37 | ota:
38 | - platform: esphome
39 | password: !secret ota_pass
40 |
41 | uart:
42 | id: ac_uart_bus
43 | #tx_pin: GPIO1
44 | #rx_pin: GPIO3
45 | tx_pin: TX
46 | rx_pin: RX
47 | baud_rate: 4800
48 | data_bits: 8
49 | parity: EVEN
50 | stop_bits: 1
51 |
52 | sensor:
53 | - platform: uptime
54 | name: Uptime Sensor
55 |
56 | climate:
57 | - platform: aux_ac
58 | name: $upper_devicename
59 | id: aux_id
60 | uart_id: ac_uart_bus
61 | period: 7s
62 | show_action: true
63 | display_inverted: true
64 | indoor_temperature:
65 | name: $upper_devicename Indoor Temperature
66 | id: ${devicename}_indoor_temp
67 | internal: false
68 | display_state:
69 | name: $upper_devicename Display State
70 | id: ${devicename}_display_state
71 | internal: false
72 | outdoor_temperature:
73 | name: $upper_devicename Outdoor Temperature
74 | id: ${devicename}_outdoor_temp
75 | internal: false
76 | outbound_temperature:
77 | name: $upper_devicename Coolant Outbound Temperature
78 | id: ${devicename}_outbound_temp
79 | internal: false
80 | inbound_temperature:
81 | name: $upper_devicename Coolant Inbound Temperature
82 | id: ${devicename}_inbound_temp
83 | internal: false
84 | compressor_temperature:
85 | name: $upper_devicename Compressor Temperature
86 | id: ${devicename}_strange_temp
87 | internal: false
88 | defrost_state:
89 | name: $upper_devicename Defrost State
90 | id: ${devicename}_defrost_state
91 | internal: false
92 | inverter_power:
93 | name: $upper_devicename Invertor Power
94 | id: ${devicename}_invertor_power
95 | internal: false
96 | preset_reporter:
97 | name: $upper_devicename Preset Reporter
98 | id: ${devicename}_preset_reporter
99 | internal: false
100 | visual:
101 | min_temperature: 16
102 | max_temperature: 32
103 | temperature_step: 0.5
104 | supported_modes:
105 | - HEAT_COOL
106 | - COOL
107 | - HEAT
108 | - DRY
109 | - FAN_ONLY
110 | custom_fan_modes:
111 | - MUTE
112 | - TURBO
113 | supported_presets:
114 | - SLEEP
115 | custom_presets:
116 | - CLEAN
117 | - HEALTH
118 | - ANTIFUNGUS
119 | supported_swing_modes:
120 | - VERTICAL
121 | - HORIZONTAL
122 | - BOTH
123 |
--------------------------------------------------------------------------------
/tests/test-ext-for-engineer.yaml:
--------------------------------------------------------------------------------
1 | external_components:
2 | - source: github://GrKoR/esphome_aux_ac_component@dev
3 | components: [ aux_ac ]
4 | refresh: 0s
5 |
6 | substitutions:
7 | devicename: test_aux_ac_ext_engeneer
8 | upper_devicename: Test AUX
9 |
10 | esphome:
11 | name: $devicename
12 | platform: ESP8266
13 | board: esp12e
14 |
15 | wifi:
16 | ssid: !secret wifi_ssid
17 | password: !secret wifi_pass
18 | manual_ip:
19 | static_ip: !secret wifi_ip
20 | gateway: !secret wifi_gateway
21 | subnet: !secret wifi_subnet
22 | dns1: 8.8.8.8
23 | dns2: 1.1.1.1
24 | reboot_timeout: 0s
25 | ap:
26 | ssid: Test AUX Fallback Hotspot
27 | password: !secret wifi_ap_pass
28 |
29 | logger:
30 | level: DEBUG
31 | baud_rate: 0
32 |
33 | api:
34 | password: !secret api_pass
35 | reboot_timeout: 0s
36 | services:
37 | # этот сервис можно вызвать из Home Assistant или Python. Он отправляет полученные байты в кондиционер
38 | - service: send_data
39 | variables:
40 | data_buf: int[]
41 | then:
42 | # ВАЖНО! Только для инженеров!
43 | # Вызывайте метод aux_ac.send_packet только если понимаете, что делаете! Он не проверяет данные, а передаёт
44 | # кондиционеру всё как есть. Какой эффект получится от передачи кондиционеру рандомных байт, никто не знает.
45 | # Вы действуете на свой страх и риск.
46 | - aux_ac.send_packet:
47 | id: aux_id
48 | data: !lambda |-
49 | std::vector data{};
50 | for (int n : data_buf) {
51 | data.push_back( (uint8_t) n );
52 | }
53 | return data;
54 |
55 | ota:
56 | - platform: esphome
57 | password: !secret ota_pass
58 |
59 | web_server:
60 | port: 80
61 |
62 | uart:
63 | id: ac_uart_bus
64 | tx_pin: GPIO1
65 | rx_pin: GPIO3
66 | baud_rate: 4800
67 | data_bits: 8
68 | parity: EVEN
69 | stop_bits: 1
70 |
71 | sensor:
72 | - platform: uptime
73 | name: Uptime Sensor
74 |
75 | climate:
76 | - platform: aux_ac
77 | name: $upper_devicename
78 | id: aux_id
79 | uart_id: ac_uart_bus
80 | period: 7s
81 | show_action: true
82 | display_inverted: true
83 | optimistic: true
84 | indoor_temperature:
85 | name: $upper_devicename Indoor Temperature
86 | id: ${devicename}_indoor_temp
87 | internal: false
88 | display_state:
89 | name: $upper_devicename Display State
90 | id: ${devicename}_display_state
91 | internal: false
92 | outdoor_temperature:
93 | name: $upper_devicename Outdoor Temperature
94 | id: ${devicename}_outdoor_temp
95 | internal: false
96 | outbound_temperature:
97 | name: $upper_devicename Coolant Outbound Temperature
98 | id: ${devicename}_outbound_temp
99 | internal: false
100 | inbound_temperature:
101 | name: $upper_devicename Coolant Inbound Temperature
102 | id: ${devicename}_inbound_temp
103 | internal: false
104 | compressor_temperature:
105 | name: $upper_devicename Compressor Temperature
106 | id: ${devicename}_strange_temp
107 | internal: false
108 | defrost_state:
109 | name: $upper_devicename Defrost State
110 | id: ${devicename}_defrost_state
111 | internal: false
112 | inverter_power:
113 | name: $upper_devicename Invertor Power
114 | id: ${devicename}_invertor_power
115 | internal: false
116 | preset_reporter:
117 | name: $upper_devicename Preset Reporter
118 | id: ${devicename}_preset_reporter
119 | internal: false
120 | visual:
121 | min_temperature: 16
122 | max_temperature: 32
123 | temperature_step: 0.5
124 | supported_modes:
125 | - HEAT_COOL
126 | - COOL
127 | - HEAT
128 | - DRY
129 | - FAN_ONLY
130 | custom_fan_modes:
131 | - MUTE
132 | - TURBO
133 | supported_presets:
134 | - SLEEP
135 | custom_presets:
136 | - CLEAN
137 | - HEALTH
138 | - ANTIFUNGUS
139 | supported_swing_modes:
140 | - VERTICAL
141 | - HORIZONTAL
142 | - BOTH
143 |
144 |
145 | switch:
146 | - platform: template
147 | name: AC Display
148 | lambda: |-
149 | if (id(${devicename}_display_state).state) {
150 | return true;
151 | } else {
152 | return false;
153 | }
154 | turn_on_action:
155 | - aux_ac.display_on: aux_id
156 | turn_off_action:
157 | - aux_ac.display_off: aux_id
--------------------------------------------------------------------------------
/tests/test-ext-power-limit.yaml:
--------------------------------------------------------------------------------
1 | external_components:
2 | - source: github://GrKoR/esphome_aux_ac_component@dev
3 | components: [ aux_ac ]
4 | refresh: 0s
5 |
6 | substitutions:
7 | devicename: test_ext_power_limitations
8 | upper_devicename: Test AUX
9 |
10 | esphome:
11 | name: $devicename
12 | platform: ESP8266
13 | board: esp12e
14 |
15 | wifi:
16 | ssid: !secret wifi_ssid
17 | password: !secret wifi_pass
18 | manual_ip:
19 | static_ip: !secret wifi_ip
20 | gateway: !secret wifi_gateway
21 | subnet: !secret wifi_subnet
22 | dns1: 8.8.8.8
23 | dns2: 1.1.1.1
24 | reboot_timeout: 0s
25 | ap:
26 | ssid: Test AUX Fallback Hotspot
27 | password: !secret wifi_ap_pass
28 |
29 | logger:
30 | level: DEBUG
31 | baud_rate: 0
32 |
33 | api:
34 | password: !secret api_pass
35 | reboot_timeout: 0s
36 |
37 | ota:
38 | - platform: esphome
39 | password: !secret ota_pass
40 |
41 | web_server:
42 | port: 80
43 |
44 | uart:
45 | id: ac_uart_bus
46 | tx_pin: GPIO1
47 | rx_pin: GPIO3
48 | baud_rate: 4800
49 | data_bits: 8
50 | parity: EVEN
51 | stop_bits: 1
52 |
53 | sensor:
54 | - platform: uptime
55 | name: Uptime Sensor
56 |
57 | climate:
58 | - platform: aux_ac
59 | name: $upper_devicename
60 | id: aux_id
61 | uart_id: ac_uart_bus
62 | period: 7s
63 | show_action: true
64 | display_inverted: true
65 | timeout: 150
66 | indoor_temperature:
67 | name: $upper_devicename Indoor Temperature
68 | id: ${devicename}_indoor_temp
69 | internal: false
70 | display_state:
71 | name: $upper_devicename Display State
72 | id: ${devicename}_display_state
73 | internal: false
74 | outdoor_temperature:
75 | name: $upper_devicename Outdoor Temperature
76 | id: ${devicename}_outdoor_temp
77 | internal: false
78 | outbound_temperature:
79 | name: $upper_devicename Coolant Outbound Temperature
80 | id: ${devicename}_outbound_temp
81 | internal: false
82 | inbound_temperature:
83 | name: $upper_devicename Coolant Inbound Temperature
84 | id: ${devicename}_inbound_temp
85 | internal: false
86 | compressor_temperature:
87 | name: $upper_devicename Compressor Temperature
88 | id: ${devicename}_strange_temp
89 | internal: false
90 | defrost_state:
91 | name: $upper_devicename Defrost State
92 | id: ${devicename}_defrost_state
93 | internal: false
94 | inverter_power:
95 | name: $upper_devicename Inverter Power
96 | id: ${devicename}_invertor_power
97 | internal: false
98 | preset_reporter:
99 | name: $upper_devicename Preset Reporter
100 | id: ${devicename}_preset_reporter
101 | internal: false
102 | inverter_power_limit_value:
103 | name: $upper_devicename Inverter Power Limit Value
104 | id: ${devicename}_inverter_power_limit_value
105 | internal: false
106 | inverter_power_limit_state:
107 | name: $upper_devicename Inverter Power Limit State
108 | id: ${devicename}_inverter_power_limit_state
109 | internal: false
110 | visual:
111 | min_temperature: 16
112 | max_temperature: 32
113 | temperature_step: 0.5
114 | supported_modes:
115 | - HEAT_COOL
116 | - COOL
117 | - HEAT
118 | - DRY
119 | - FAN_ONLY
120 | custom_fan_modes:
121 | - MUTE
122 | - TURBO
123 | supported_presets:
124 | - SLEEP
125 | custom_presets:
126 | - CLEAN
127 | - HEALTH
128 | - ANTIFUNGUS
129 | supported_swing_modes:
130 | - VERTICAL
131 | - HORIZONTAL
132 | - BOTH
133 |
134 |
135 | button:
136 | - platform: template
137 | name: ${upper_devicename} IPower Limit Off
138 | icon: "mdi:power-plug-off-outline"
139 | on_press:
140 | - aux_ac.power_limit_off: aux_id
141 |
142 | - platform: template
143 | name: ${upper_devicename} IPower Limit On Half
144 | icon: "mdi:fraction-one-half"
145 | on_press:
146 | - aux_ac.power_limit_on:
147 | id: aux_id
148 | limit: 50
149 |
150 | number:
151 | - platform: template
152 | name: ${upper_devicename} IPower Limit Value
153 | id: ${devicename}_ipower_limit_value
154 | icon: "mdi:battery-unknown"
155 | mode: "slider"
156 | min_value: 30
157 | max_value: 100
158 | step: 1
159 | set_action:
160 | then:
161 | - lambda: !lambda |-
162 | id(aux_id).powerLimitationOnSequence( x );
163 |
164 |
--------------------------------------------------------------------------------
/tests/test-local-airflow-dir.yaml:
--------------------------------------------------------------------------------
1 | external_components:
2 | - source:
3 | type: local
4 | path: ../components
5 |
6 | substitutions:
7 | devicename: test_local_airflow_dir
8 | upper_devicename: Test AUX
9 |
10 | esphome:
11 | name: $devicename
12 | platform: ESP8266
13 | board: esp12e
14 |
15 | wifi:
16 | ssid: !secret wifi_ssid
17 | password: !secret wifi_pass
18 | manual_ip:
19 | static_ip: !secret wifi_ip
20 | gateway: !secret wifi_gateway
21 | subnet: !secret wifi_subnet
22 | dns1: 8.8.8.8
23 | dns2: 1.1.1.1
24 | reboot_timeout: 0s
25 | ap:
26 | ssid: $upper_devicename Fallback Hotspot
27 | password: !secret wifi_ap_pass
28 |
29 | logger:
30 | level: DEBUG
31 | baud_rate: 0
32 |
33 | api:
34 | password: !secret api_pass
35 | reboot_timeout: 0s
36 |
37 | ota:
38 | - platform: esphome
39 | password: !secret ota_pass
40 |
41 | web_server:
42 | port: 80
43 |
44 | uart:
45 | id: ac_uart_bus
46 | tx_pin: GPIO1
47 | rx_pin: GPIO3
48 | baud_rate: 4800
49 | data_bits: 8
50 | parity: EVEN
51 | stop_bits: 1
52 |
53 |
54 | sensor:
55 | - platform: uptime
56 | name: Uptime Sensor
57 |
58 |
59 | climate:
60 | - platform: aux_ac
61 | name: $upper_devicename
62 | id: aux_id
63 | uart_id: ac_uart_bus
64 | period: 7s
65 | show_action: true
66 | display_inverted: true
67 |
68 |
69 | button:
70 | - platform: template
71 | name: ${upper_devicename} VLouver Stop
72 | icon: "mdi:circle-small"
73 | on_press:
74 | - aux_ac.vlouver_stop: aux_id
75 |
76 | - platform: template
77 | name: ${upper_devicename} VLouver Swing
78 | icon: "mdi:pan-vertical"
79 | on_press:
80 | - aux_ac.vlouver_swing: aux_id
81 |
82 | - platform: template
83 | name: ${upper_devicename} VLouver Top
84 | icon: "mdi:pan-up"
85 | on_press:
86 | - aux_ac.vlouver_top: aux_id
87 |
88 | - platform: template
89 | name: ${upper_devicename} VLouver Middle Above
90 | icon: "mdi:pan-top-left"
91 | on_press:
92 | - aux_ac.vlouver_middle_above: aux_id
93 |
94 | - platform: template
95 | name: ${upper_devicename} VLouver Middle
96 | icon: "mdi:pan-left"
97 | on_press:
98 | - aux_ac.vlouver_middle: aux_id
99 |
100 | - platform: template
101 | name: ${upper_devicename} VLouver Middle Below
102 | icon: "mdi:pan-bottom-left"
103 | on_press:
104 | - aux_ac.vlouver_middle_below: aux_id
105 |
106 | - platform: template
107 | name: ${upper_devicename} VLouver Bottom
108 | icon: "mdi:pan-down"
109 | on_press:
110 | - aux_ac.vlouver_bottom: aux_id
111 |
112 |
113 | number:
114 | - platform: template
115 | name: ${upper_devicename} Vertical Louver
116 | id: ${devicename}_vlouver
117 | icon: "mdi:circle-small"
118 | mode: "slider"
119 | min_value: 0
120 | max_value: 6
121 | step: 1
122 | set_action:
123 | then:
124 | - lambda: !lambda |-
125 | if (x == 6) x = 7; // делаем так, чтобы выключение отрабатывать корректно
126 | id(aux_id).setVLouverSequence( static_cast(x) );
127 |
--------------------------------------------------------------------------------
/tests/test-local-power-limit.yaml:
--------------------------------------------------------------------------------
1 | external_components:
2 | - source:
3 | type: local
4 | path: ../components
5 |
6 | substitutions:
7 | devicename: test_local_power_limitations
8 | upper_devicename: Test AUX
9 |
10 | esphome:
11 | name: $devicename
12 | platform: ESP8266
13 | board: esp12e
14 |
15 | wifi:
16 | ssid: !secret wifi_ssid
17 | password: !secret wifi_pass
18 | manual_ip:
19 | static_ip: !secret wifi_ip
20 | gateway: !secret wifi_gateway
21 | subnet: !secret wifi_subnet
22 | dns1: 8.8.8.8
23 | dns2: 1.1.1.1
24 | reboot_timeout: 0s
25 | ap:
26 | ssid: Test AUX Fallback Hotspot
27 | password: !secret wifi_ap_pass
28 |
29 | logger:
30 | level: DEBUG
31 | baud_rate: 0
32 |
33 | api:
34 | password: !secret api_pass
35 | reboot_timeout: 0s
36 |
37 | ota:
38 | - platform: esphome
39 | password: !secret ota_pass
40 |
41 | web_server:
42 | port: 80
43 |
44 | uart:
45 | id: ac_uart_bus
46 | tx_pin: GPIO1
47 | rx_pin: GPIO3
48 | baud_rate: 4800
49 | data_bits: 8
50 | parity: EVEN
51 | stop_bits: 1
52 |
53 | sensor:
54 | - platform: uptime
55 | name: Uptime Sensor
56 |
57 | climate:
58 | - platform: aux_ac
59 | name: $upper_devicename
60 | id: aux_id
61 | uart_id: ac_uart_bus
62 | period: 7s
63 | show_action: true
64 | display_inverted: true
65 | timeout: 150
66 | indoor_temperature:
67 | name: $upper_devicename Indoor Temperature
68 | id: ${devicename}_indoor_temp
69 | internal: false
70 | display_state:
71 | name: $upper_devicename Display State
72 | id: ${devicename}_display_state
73 | internal: false
74 | outdoor_temperature:
75 | name: $upper_devicename Outdoor Temperature
76 | id: ${devicename}_outdoor_temp
77 | internal: false
78 | outbound_temperature:
79 | name: $upper_devicename Coolant Outbound Temperature
80 | id: ${devicename}_outbound_temp
81 | internal: false
82 | inbound_temperature:
83 | name: $upper_devicename Coolant Inbound Temperature
84 | id: ${devicename}_inbound_temp
85 | internal: false
86 | compressor_temperature:
87 | name: $upper_devicename Compressor Temperature
88 | id: ${devicename}_strange_temp
89 | internal: false
90 | defrost_state:
91 | name: $upper_devicename Defrost State
92 | id: ${devicename}_defrost_state
93 | internal: false
94 | inverter_power:
95 | name: $upper_devicename Inverter Power
96 | id: ${devicename}_invertor_power
97 | internal: false
98 | preset_reporter:
99 | name: $upper_devicename Preset Reporter
100 | id: ${devicename}_preset_reporter
101 | internal: false
102 | inverter_power_limit_value:
103 | name: $upper_devicename Inverter Power Limit Value
104 | id: ${devicename}_inverter_power_limit_value
105 | internal: false
106 | inverter_power_limit_state:
107 | name: $upper_devicename Inverter Power Limit State
108 | id: ${devicename}_inverter_power_limit_state
109 | internal: false
110 | visual:
111 | min_temperature: 16
112 | max_temperature: 32
113 | temperature_step: 0.5
114 | supported_modes:
115 | - HEAT_COOL
116 | - COOL
117 | - HEAT
118 | - DRY
119 | - FAN_ONLY
120 | custom_fan_modes:
121 | - MUTE
122 | - TURBO
123 | supported_presets:
124 | - SLEEP
125 | custom_presets:
126 | - CLEAN
127 | - HEALTH
128 | - ANTIFUNGUS
129 | supported_swing_modes:
130 | - VERTICAL
131 | - HORIZONTAL
132 | - BOTH
133 |
134 |
135 | button:
136 | - platform: template
137 | name: ${upper_devicename} IPower Limit Off
138 | icon: "mdi:power-plug-off-outline"
139 | on_press:
140 | - aux_ac.power_limit_off: aux_id
141 |
142 | - platform: template
143 | name: ${upper_devicename} IPower Limit On Half
144 | icon: "mdi:fraction-one-half"
145 | on_press:
146 | - aux_ac.power_limit_on:
147 | id: aux_id
148 | limit: 50
149 |
150 | number:
151 | - platform: template
152 | name: ${upper_devicename} IPower Limit Value
153 | id: ${devicename}_ipower_limit_value
154 | icon: "mdi:battery-unknown"
155 | mode: "slider"
156 | min_value: 30
157 | max_value: 100
158 | step: 1
159 | set_action:
160 | then:
161 | - lambda: !lambda |-
162 | id(aux_id).powerLimitationOnSequence( x );
163 |
164 |
--------------------------------------------------------------------------------
/tests/test-local.yaml:
--------------------------------------------------------------------------------
1 | external_components:
2 | - source:
3 | type: local
4 | path: ../components
5 |
6 | substitutions:
7 | devicename: test_local_airflow_dir
8 | upper_devicename: Test AUX
9 |
10 | esphome:
11 | name: $devicename
12 | platform: ESP8266
13 | board: esp12e
14 |
15 | wifi:
16 | ssid: !secret wifi_ssid
17 | password: !secret wifi_pass
18 | manual_ip:
19 | static_ip: !secret wifi_ip
20 | gateway: !secret wifi_gateway
21 | subnet: !secret wifi_subnet
22 | dns1: 8.8.8.8
23 | dns2: 1.1.1.1
24 | reboot_timeout: 0s
25 | ap:
26 | ssid: Test AUX Fallback Hotspot
27 | password: !secret wifi_ap_pass
28 |
29 | logger:
30 | level: DEBUG
31 | baud_rate: 0
32 |
33 | api:
34 | password: !secret api_pass
35 | reboot_timeout: 0s
36 |
37 | ota:
38 | - platform: esphome
39 | password: !secret ota_pass
40 |
41 | web_server:
42 | port: 80
43 |
44 | uart:
45 | id: ac_uart_bus
46 | tx_pin: GPIO1
47 | rx_pin: GPIO3
48 | baud_rate: 4800
49 | data_bits: 8
50 | parity: EVEN
51 | stop_bits: 1
52 |
53 | sensor:
54 | - platform: uptime
55 | name: Uptime Sensor
56 |
57 | climate:
58 | - platform: aux_ac
59 | name: $upper_devicename
60 | id: aux_id
61 | uart_id: ac_uart_bus
62 | period: 7s
63 | show_action: true
64 | display_inverted: true
65 | optimistic: true
66 | indoor_temperature:
67 | name: $upper_devicename Indoor Temperature
68 | id: ${devicename}_indoor_temp
69 | internal: false
70 | display_state:
71 | name: $upper_devicename Display State
72 | id: ${devicename}_display_state
73 | internal: false
74 | outdoor_temperature:
75 | name: $upper_devicename Outdoor Temperature
76 | id: ${devicename}_outdoor_temp
77 | internal: false
78 | outbound_temperature:
79 | name: $upper_devicename Coolant Outbound Temperature
80 | id: ${devicename}_outbound_temp
81 | internal: false
82 | inbound_temperature:
83 | name: $upper_devicename Coolant Inbound Temperature
84 | id: ${devicename}_inbound_temp
85 | internal: false
86 | compressor_temperature:
87 | name: $upper_devicename Compressor Temperature
88 | id: ${devicename}_strange_temp
89 | internal: false
90 | defrost_state:
91 | name: $upper_devicename Defrost State
92 | id: ${devicename}_defrost_state
93 | internal: false
94 | inverter_power:
95 | name: $upper_devicename Invertor Power
96 | id: ${devicename}_invertor_power
97 | internal: false
98 | preset_reporter:
99 | name: $upper_devicename Preset Reporter
100 | id: ${devicename}_preset_reporter
101 | internal: false
102 | visual:
103 | min_temperature: 16
104 | max_temperature: 32
105 | temperature_step: 0.5
106 | supported_modes:
107 | - HEAT_COOL
108 | - COOL
109 | - HEAT
110 | - DRY
111 | - FAN_ONLY
112 | custom_fan_modes:
113 | - MUTE
114 | - TURBO
115 | supported_presets:
116 | - SLEEP
117 | custom_presets:
118 | - CLEAN
119 | - HEALTH
120 | - ANTIFUNGUS
121 | supported_swing_modes:
122 | - VERTICAL
123 | - HORIZONTAL
124 | - BOTH
125 |
--------------------------------------------------------------------------------
/tests/test-minimal.yaml:
--------------------------------------------------------------------------------
1 | external_components:
2 | - source:
3 | type: local
4 | path: ../components
5 | #- source: github://GrKoR/esphome_aux_ac_component@dev
6 | #components: [ aux_ac ]
7 | #refresh: 0s
8 |
9 | substitutions:
10 | devicename: test_local_minimal
11 | upper_devicename: Test AUX
12 |
13 | esphome:
14 | name: $devicename
15 | platform: ESP8266
16 | board: esp12e
17 |
18 | wifi:
19 | ssid: !secret wifi_ssid
20 | password: !secret wifi_pass
21 | reboot_timeout: 0s
22 | ap:
23 | ssid: $upper_devicename Fallback Hotspot
24 | password: !secret wifi_ap_pass
25 |
26 | logger:
27 | level: DEBUG
28 | baud_rate: 0
29 |
30 | api:
31 | password: !secret api_pass
32 | reboot_timeout: 0s
33 |
34 | ota:
35 | - platform: esphome
36 | password: !secret ota_pass
37 |
38 | uart:
39 | id: ac_uart_bus
40 | tx_pin: GPIO1
41 | rx_pin: GPIO3
42 | baud_rate: 4800
43 | data_bits: 8
44 | parity: EVEN
45 | stop_bits: 1
46 |
47 | climate:
48 | - platform: aux_ac
49 | name: $upper_devicename
--------------------------------------------------------------------------------