Найти тему
Smart home Russia

Устройство учета электроэнергии [Код и его разбор]

Как и обещал в своем посте, привожу код для проекта с разбором. Возможно, поможет начинающим. Подходит как к одноканальной, так и к шестиканальной версии.

Translation to English is here. Также новостной канал в telegram

Для тех, кто что-то упустил, напомню, что у меня вышло 2 публикации про контроль и учет электроэнергии. Вот они:

Если технически они имеет значительные различия, то вот код у них одинаковый, с той лишь разницей, что в шестиканальной версии некоторые куски повторяются по 6 раз соответственно. Сначала я хотел вставить код, а уже ниже комментировать его по кускам, но тогда статья получилась бы "мегадлинной" и читать ее было бы неудобно. Если я не прав, то можете меня оспорить, тогда в будущем я буду

Ниже используемый на данный момент код и комментарии:

esphome:
name: current-sensor-6

1. Данный кусок формируется автоматом при создании нового проекта несет в себе его имя. Если его изменить, то обновление прошивки уже не произойдет. Поэтому его не трогаем и у меня не копируем ☺. Для изменения имени проекта есть соответствующая кнопка, поэтому используем ее.

2. Следующий кусок формируется также автоматом и содержит в себе описание используемой платы. Это важно для компиляции прошивки. Если выбрать неправильное имя платы, но угадать модель чипа, то прошивка может заработать некорректно, т.к. указывая названия пинов мы чаще всего указываем именно пин с привязкой к плате, а не к чипу. Если же неправильно указать чип, то прошивка или не скомпилируется или не заработает.

esp32:
board: lolin32
framework:
type: arduino

3. Данный текст говорит нам о том, что мы будем использовать логи и по умолчанию выбран debug уровень, хотя мы его и не прописали.

Logger Component
logger:

4. Компонент web-сервера. Является необязательной частью программы, однако очень удобен для отладки и визуализации. Именно благодаря нему калибровка датчика проходит быстрее, ведь вооружившись тестером телефоном, ручкой и листочком таблица соответствий создается всего за пару минут.

Web Server Component
web_server:
port: 80

5. Компонент ниже необходим для того, чтобы ESP получила данные о времени. Необходимо в дальнейших расчетах потребленной за сутки электроэнергии. Часовой пояс подтягивается с компьютера, на котором компилируется прошивка.

Time
time:
- platform: sntp

6. Далее указывается на то, что мы будем использовать API для легкой интеграции в Home Assistant. Данная строка, как и ключ, генерируются автоматом. Если не требуется интегрировать в HA, то и строки ниже не нужны

Native API Component
api:
encryption:
key: "тут генерируется ключ"

7. Данные строчки генерируются также автоматически и позволяют нам обновляться по воздуху. Можно конечно и отключить данный компонент, но тогда придется каждый раз бежать к контроллеру с кабелем, что определенно не удобно.

OTA Update Component
ota:
password: "тут генерируется ключ"

8. Строки ниже также генерируются автоматом для каждого нового проекта и в них указывается логин и пароль к вашей точке доступа. Необходимо для того, чтобы ESP подключилась к сети.

ssid: !secret wifi_ssid
password: !secret wifi_password

9. Данные строки тоже генерируются автоматом и содержат в себе название точки доступа и пароль к ней. Если вы ошиблись выше или принесли ваше устройство в новое место, то данный способ будет единственным, чтобы заставить устройство работать без перепрошивки.

ap:
ssid: "Current-Sensor-6"
password: "тут генерируется ключ"

10. Собственно параметры выше еще ничего не значат и работают вместе со строчками ниже. Портал создает окошко, в котором мы выберем новую сеть. Прописывается также по умолчанию для всех новых проектов.

Captive Portal
captive_portal:

11. Начиная с этих строк стартует наша основная часть. Мы прописываем что у нас в прошивке будут сенсоры, далее мы начинаем по очереди указывать эти самые сенсоры

Sensor Component
sensor:

12. Наш первый сенсор является необязательным и несет чисто информативный характер. Плата замеряет время работы с последней загрузки и передает его в HA. Нужен исключительно для понимания наличия или отсутствия сбоев на плате.

Uptime Sensor
- platform: uptime
name: Uptime Sensor

13.1. И вот наш первый сенсор, которые несет в себе информацию, ради которой мы тут собрались. Данная платформа позволяет рассчитать ток на основании данных с источника. В качестве источника мы выбираем АЦП, который у нас называется adc_1, даем ему имя balcony и говорим, что обновляется он будет раз в 10 секунд. В разделе фильтр мы говорим о том, что с данными этого сенсора, после получения результата, надо еще поработать. Есть линейная и полиномиальная. Линейная работает по 2 точкам и позволяет строить показания согласно простому соответствию, и полиномиальная уже намного сложнее. Мы делаем несколько замеров, каждое из которых является истинным и присваиваем ему измеренное нашим сенсором значение. Использую данную функцию, т.к. линейная функция давала сильное расхождение. В конце мы присваиваем данному датчику имя, чтобы далее с ним работать и тип/класс устройства, для правильного отображения его в HA.

CT Clamp Current Sensor
Sensor Component
- platform: ct_clamp
sensor: adc_1
name: "balcony"
update_interval: 10s
filters:
- calibrate_polynomial:
degree: 2
datapoints:
- 0.00 -> 0.0
- 0.00772 -> 0.153
- 0.00832 -> 0.156
- 0.03627 -> 1.977
- 0.05085 -> 2.28
- 0.06490 -> 3.23
- 0.08641 -> 3.86
accuracy_decimals: 5
id: measured_current1
device_class: current

13.2-6. Строки ниже являются полной копией строк выше. Меняем лишь калибровочную таблицу по необходимости и названия сенсоров.

- platform: ct_clamp
sensor: adc_1
name: "Bal RAW"
update_interval: 10s
accuracy_decimals: 5
device_class: current
- platform: ct_clamp
sensor: adc_2
name: "Bedroom"
update_interval: 10s
filters:
- calibrate_polynomial:
degree: 2
datapoints:
- 0.00 -> 0.0
- 0.00772 -> 0.153
- 0.00832 -> 0.156
- 0.03627 -> 1.977
- 0.05085 -> 2.28
- 0.06490 -> 3.23
- 0.08641 -> 3.86
accuracy_decimals: 5
id: measured_current2
device_class: current
- platform: ct_clamp
sensor: adc_2
name: "Bed RAW"
update_interval: 10s
accuracy_decimals: 5
device_class: current
- platform: ct_clamp
sensor: adc_3
name: "washing machine"
update_interval: 10s
filters:
- calibrate_polynomial:
degree: 2
datapoints:
- 0.00 -> 0.0
- 0.0083 -> 0.053
- 0.00772 -> 0.153
- 0.00832 -> 0.156
- 0.03627 -> 1.977
- 0.05085 -> 2.28
- 0.06490 -> 3.23
- 0.08641 -> 3.86
- 0.16095 -> 7.48
accuracy_decimals: 5
id: measured_current3
device_class: current
- platform: ct_clamp
sensor: adc_3
name: "WM RAW"
update_interval: 10s
accuracy_decimals: 5
device_class: current
- platform: ct_clamp
sensor: adc_4
name: "conditioner bedroom"
update_interval: 10s
filters:
- calibrate_polynomial:
degree: 2
datapoints:
- 0.00 -> 0.0
- 0.00772 -> 0.153
- 0.00832 -> 0.156
- 0.03627 -> 1.977
- 0.05085 -> 2.28
- 0.06490 -> 3.23
- 0.08641 -> 3.86
accuracy_decimals: 5
id: measured_current4
device_class: current
- platform: ct_clamp
sensor: adc_4
name: "CBR RAW"
update_interval: 10s
accuracy_decimals: 5
device_class: current
- platform: ct_clamp
sensor: adc_5
name: "conditioner kids room"
update_interval: 10s
filters:
- calibrate_polynomial:
degree: 2
datapoints:
- 0.00 -> 0.0
- 0.00772 -> 0.153
- 0.00832 -> 0.156
- 0.03627 -> 1.977
- 0.05085 -> 2.28
- 0.06490 -> 3.23
- 0.08641 -> 3.86
accuracy_decimals: 5
id: measured_current5
device_class: current
- platform: ct_clamp
sensor: adc_5
name: "CKR RAW"
update_interval: 10s
accuracy_decimals: 5
device_class: current
- platform: ct_clamp
sensor: adc_6
name: "conditioner living room"
update_interval: 10s
filters:
- calibrate_polynomial:
degree: 2
datapoints:
- 0.00 -> 0.0
- 0.00772 -> 0.153
- 0.00832 -> 0.156
- 0.03627 -> 1.977
- 0.05085 -> 2.28
- 0.06490 -> 3.23
- 0.08641 -> 3.86
accuracy_decimals: 5
id: measured_current6
device_class: current
- platform: ct_clamp
sensor: adc_6
name: "CLR RAW"
update_interval: 10s
accuracy_decimals: 5
device_class: current

14.1. Данная платформа позволяет получить нам данные с АЦП нашего микроконтроллера. Указываем два параметра: номер пина и его ID, для того чтобы работать далее с его данными. Также рекомендуется использовать параметр raw для того, чтобы посмотреть, что же у нас реально идет с АЦП в "сырых данных" в случае, если есть проблемы

Analog To Digital Sensor
- platform: adc
pin: A0
id: adc_1

14.2-6. Повторяем все еще пять раз, меняя названия и номера пинов.

- platform: adc
pin: A3
id: adc_2
- platform: adc
pin: A4
id: adc_3
- platform: adc
pin: A5
id: adc_4
- platform: adc
pin: A6
id: adc_5
- platform: adc
pin: A7
id: adc_6

15.1 Данный компонент позволяет нам посчитать потребленную за день энергию. Параметров не так много, это: Отображаемое имя, еденица измерения, сенсор, данные с которого будут считать в течении суток, количество цифр после запятой. Все считается на основе данных о времени, поэтому мы и указывали в начале конфигурации о подключении к серверу точного времени. Далее, платформа считает ватты, а нам нужны киловатты, поэтому делим все на 1000. Ну и указываем класс устройства для правильного отображения в HA.

- platform: total_daily_energy
name: "Total Daily Power Consumption balcony"
unit_of_measurement: kWh
power_id: power1
accuracy_decimals: 2
filters:
- multiply: 0.001
device_class: energy

15.2-6. Повторяем все тоже самое для остальных датчиков

- platform: total_daily_energy
name: "Total Daily Power Consumption Bedroom"
unit_of_measurement: kWh
power_id: power2
accuracy_decimals: 2
filters:
- multiply: 0.001
device_class: energy
- platform: total_daily_energy
name: "Total Daily Power Consumption washing machine"
unit_of_measurement: kWh
power_id: power3
accuracy_decimals: 2
filters:
- multiply: 0.001
device_class: energy
- platform: total_daily_energy
name: "Total Daily Power Consumption conditioner bedroom"
unit_of_measurement: kWh
power_id: power4
accuracy_decimals: 2
filters:
- multiply: 0.001
device_class: energy
- platform: total_daily_energy
name: "Total Daily Power Consumption conditioner kids room"
unit_of_measurement: kWh
power_id: power5
accuracy_decimals: 2
filters:
- multiply: 0.001
device_class: energy
- platform: total_daily_energy
name: "Total Daily Power Consumption conditioner living room"
unit_of_measurement: kWh
power_id: power6
accuracy_decimals: 2
filters:
- multiply: 0.001
device_class: energy

16.1 Платформа "шаблон". Позволяет нам сделать все что угодно. В данном примере используем ее для расчета мощности, т.к. напряжение нашим контроллером мы не замеряем. Каждые 5 секунд с точностью до 2 знаков после запятой мы получаем значение потребленной мощности. Просто умножаем ток на напряжение. Точность данной процедуры весьма сомнительна и работает в диапазоне ±"трамвайная остановка"

- platform: template
name: "Measured Power balcony"
id: power1
lambda: |-
return id(measured_current1).state * 230;
accuracy_decimals: 2
update_interval: 5s
device_class: power
unit_of_measurement: W

16.2-6. Повторяем расчет "трамвайных остановок" для других пяти сенсоров с уже объявленной точностью. Без комментариев ☺.

- platform: template
name: "Measured Power Bedroom"
id: power2
lambda: |-
return id(measured_current2).state * 230;
accuracy_decimals: 2
update_interval: 5s
device_class: power
unit_of_measurement: W
- platform: template
name: "Measured Power washing machine"
id: power3
lambda: |-
return id(measured_current3).state * 230;
accuracy_decimals: 2
update_interval: 5s
device_class: power
unit_of_measurement: W
- platform: template
name: "Measured Power conditioner bedroom"
id: power4
lambda: |-
return id(measured_current4).state * 230;
accuracy_decimals: 2
update_interval: 5s
device_class: power
unit_of_measurement: W
- platform: template
name: "Measured Power conditioner kids room"
id: power5
lambda: |-
return id(measured_current5).state * 230;
update_interval: 5s
device_class: power
unit_of_measurement: W
- platform: template
name: "Measured Power conditioner living room"
id: power6
lambda: |-
return id(measured_current6).state * 230;
accuracy_decimals: 2
update_interval: 5s
device_class: power
unit_of_measurement: W

17.1. Выше уже описывал эту платформу. Теперь считаем все тоже самое для тока. Не самая нужная информация, но некоторым может пригодится. Не нужно - просто не используем код ниже. Я сделал на будущее, вдруг когда-то пойму зачем мне это...

- platform: total_daily_energy
name: "Daily Current balcony"
power_id: measured_current1
accuracy_decimals: 2
unit_of_measurement: Ah

17.2-6. Повторяем все еще пять раз. Схема уже проверенная.

- platform: total_daily_energy
name: "Daily Current Bedroom"
power_id: measured_current2
accuracy_decimals: 2
unit_of_measurement: Ah
- platform: total_daily_energy
name: "Daily Current washing machine"
power_id: measured_current3
accuracy_decimals: 2
unit_of_measurement: Ah
- platform: total_daily_energy
name: "Daily Current conditioner bedroom"
power_id: measured_current4
accuracy_decimals: 2
unit_of_measurement: Ah
- platform: total_daily_energy
name: "Daily Current conditioner kids room"
power_id: measured_current5
accuracy_decimals: 2
unit_of_measurement: Ah
- platform: total_daily_energy
name: "Daily Current conditioner living room"
power_id: measured_current6
accuracy_decimals: 2
unit_of_measurement: Ah

Несмотря на тот факт, что код выглядит очень длинным, он очень простой, длину ему придает шестикратное упоминание каждого сенсора. Если остались вопросы - задавайте, отвечу с удовольствием. А сегодня на этом все ☺.

Подпишитесь, чтобы не пропускать следующий контент.
Нажмите лайк, если интересно, так я пойму какие публикации больше нужны моей публике.

Также публикации можно найти на других площадках: Instagram, telegram (RU, EN, DE), Medium, LiveJournal, YouTube.

Мой блог является некоммерческим, поэтому позитивный комментарий, лайк или репост поможет публикациям выходить чаще ☺.