Перейти до змісту

Облік енергії (Energy Tracking)

Відстежуйте електроенергію, спожиту кожним друком, і за весь lifetime принтера, потім помножте на ваш kWh-тариф для cost. Числа йдуть прямо з energy register розумної розетки — не з оцінок.


Що це

BamDude читає два значення з кожної розумної розетки:

  1. Live wattage — скільки ват принтер тягне зараз.
  2. Lifetime energy counter — загальні kWh, які розетка нарахувала з моменту скиду.

Коли друк стартує, lifetime counter записується на рядок архіву як energy_start_kwh. Коли друк завершується, BamDude читає counter знову і зберігає дельту як energy_kwh. Стартове значення живе на рядку архіву, а не у пам'яті — тож перезапуск backend'у посеред друку не втрачає baseline, і дельта рахується при завершенні друку. (Якщо друк завершився під час простою — див. «Якщо друк завершився, поки BamDude лежав» нижче.)

Цифри, записані до 0.5.3, занижують друки, запущені поза BamDude

«На старті друку» завжди було наміром, і для друків, які BamDude диспатчив сам, це було й фактом. Для друку з екрана принтера або надісланого прямо зі слайсера baseline читався тоді, коли зʼявлявся рядок архіву — а той створювався лише після того, як BamDude витягне 3MF назад із принтера, що на P1S заміряно у 8m40s. Усе спожите за цей час, включно з розігрівом столу, не рахувалося. Похибка завжди йшла в один бік, тож ніколи не усереднювалась. Історичні рядки не перераховуються — перераховувати їх нема з чого.

Для lifetime / date-range вьюх щогодинний background-loop робить snapshot lifetime counter кожної розетки у smart_plug_energy_snapshots. Date-range total потім рахується як last_snapshot_in_range − last_snapshot_before_range per plug.

Потрібен дозвіл

Читання даних про енергію вимагає stats:read. Tracking стартує автоматично, як тільки розетка прив'язана до принтера — окремого тогла "enable energy tracking" немає.


Вимоги

Облік енергії потребує розумної розетки з kWh metering між розеткою у стіні та принтером. Тип розетки, деталі power monitoring і кроки конфігурації — у Smart Plugs.

Тип розетки kWh Metering Нотатки
Tasmota Native HTTP energy endpoint
Home Assistant Bind HA energy sensor entity
REST / Webhook Вкажіть JSON path для kWh
MQTT Вкажіть MQTT topic + JSON path

Розетки без energy register (прості on/off) теж працюють для power control, але їхні рядки архіву матимуть NULL energy_kwh і не зайдуть у lifetime totals.


Per-Print kWh

Зберігається на PrintArchive:

Колонка Коли пишеться Що означає
energy_start_kwh На старті друку Lifetime counter розетки на момент початку друку
energy_kwh При завершенні (end_counter − energy_start_kwh), скільки kWh з'їв саме цей друк
energy_cost При завершенні energy_kwh × cost_per_kwh (у вашій валюті)

Restart-resilient. Оскільки energy_start_kwh персиститься на рядок архіву у тій самій транзакції, що і started_at, краш backend'у або перезапуск контейнера посеред друку не втрачає baseline — наступний on_print_complete правильно порахує дельту.

Якщо друк завершився, поки BamDude лежав, ніякого on_print_complete не буде: принтер закінчив сам, а BamDude дізнається про це аж на наступному старті. Стартовий sweep закриває такий друк і читає лічильник тоді ж, тож архів усе одно отримує цифру — але лічильник рахував і весь той час, поки принтер стояв без діла, тож цей простій потрапляє всередину числа. Такі архіви несуть extra_data.energy_is_approximate = true, а в лозі видно (approximate — recovered print). Альтернативою було лишити поле порожнім — а це читається як «друк не спожив нічого», що далі від правди, ніж помірне завищення.

Failed і cancelled друки теж записують енергію. 6-годинний друк, який впав на 4-й годині, спожив 4 години електрики — дельта все ще змістовна і все ще пишеться.


Lifetime kWh та діапазони дат

Щогодинний snapshot-loop (SmartPlugManager._snapshot_loop) пише один рядок на розетку у smart_plug_energy_snapshots. Знімок пишеться також на старті кожного друку — з того самого читання, що задає базову лінію архіву, — тож початок друку стає справжньою межею в історії, а не тим, коли востаннє встиг спрацювати цикл:

Колонка Що означає
plug_id FK до розумної розетки
recorded_at UTC timestamp снапшоту
lifetime_kwh Lifetime energy register розетки на той момент

Для діапазону [date_from, date_to] BamDude рахує per plug:

range_total = max(0, last_snapshot_in_range − last_snapshot_before_range)

max(0, …) клампить до нуля, коли lifetime counter був скинутий (наприклад, factory-reset розетки), щоб ви ніколи не отримали від'ємну енергію.

Який день вважається «сьогодні». Дати, які ви обираєте, і «спожито сьогодні» рахуються у вашому часовому поясі — браузер повідомляє серверу, в якому саме. Знімки зберігаються в UTC, як вище, а межа доби переводиться перед запитом. Те, що BamDude робить за власним розкладом — нічні бекапи, дайджести — і далі живе за поясом сервера, як і має. Тим, хто не може передати пояс (Telegram-бот, API-ключі, вебхуки), відповідь дається в поясі сервера.


Калькуляція cost

Cost — це single-rate проти lifetime / per-print дельти:

cost = energy_kwh × energy_cost_per_kwh

Налаштуйте rate у Settings → System → Energy:

Setting Опис
energy_cost_per_kwh Ваша ціна за kWh (default 0.15)

Numeric rate безрозмірний — показуйте cost у тій валюті, що відповідає вашому реальному тарифу. BamDude не конвертує валюти; він просто множить.


Energy Tracking Mode

Settings → System → Energy → Energy Tracking Mode (energy_tracking_mode):

Mode Що означає "Energy used" на Stats
print Сума per-archive energy_kwh за діапазон. Без idle, standby, chamber-only heating. Pure printing cost.
total (default) Lifetime plug counter через snapshot range — last_in_range − baseline_before_range. Включає idle / standby / chamber heating / firmware-update сесії / усе, що принтер тягнув, поки був у розетці.

Виберіть print, якщо білите клієнтів per job. Виберіть total, якщо хочете знати, скільки реально коштує тримати ферму ввімкнутою.


Індикатор "Warming-Up"

Mode total потребує хоча б один snapshot до початку обраного діапазону, щоб порахувати baseline. На свіжому install, відразу після апгрейду на білд, що везе snapshot support, або одразу після зсуву Last 7 days у вікно без попереднього snapshot — цього baseline ще немає.

Коли так, сторінка Stats показує жовту іконку попередження поруч з Energy Used і Energy Cost:

Still warming up — at least one plug doesn't have a snapshot from before the start of your range.

Іконка зникає, як тільки накопичиться достатньо snapshot'ів. Налаштовувати нічого не треба; система просто збирає дані. Backend-флаг: energy_data_warming_up=True у відповіді stats.


Tibber / Octopus / Dynamic Tariff

Якщо у вас динамічний тариф (Tibber, Octopus, Nordpool, …), пушайте live-rate у BamDude з Home Assistant — кожна cost-калькуляція тоді користуватиметься поточним тарифом замість static value.

1. Створіть API key

Settings → API Keys → Create і ввімкніть на ключі toggle Update electricity price. Це вузько-обмежений opt-in для POST /settings/electricity-price — він не надає загальний settings-write дозвіл (старий PATCH /settings лишається). Скопіюйте ключ.

Старі docs згадували PATCH /settings

Загальний PATCH /settings все ще працює з API key, але виставляє увесь settings payload (SMTP / LDAP / MQTT credentials, HA token, всі UI-ручки) — значно ширшу поверхню, ніж потрібно для dynamic-tariff кейсу. Новий POST /settings/electricity-price приймає тільки {energy_cost_per_kwh}, повертає повну settings response щоб HA міг переконатись що значення прийнялось, і захищений per-key toggle-ом — адмін має явно opt-in. Конфіги що вказують на legacy URL продовжать працювати; перейдіть на новий URL при наступному оновленні конфігу.

2. Додайте REST command у HA

У configuration.yaml:

rest_command:
  bamdude_electricity_price:
    url: "http://YOUR_BAMDUDE_IP:8000/api/v1/settings/electricity-price"
    method: POST
    headers:
      X-API-Key: "YOUR_API_KEY"
    content_type: "application/json"
    payload: '{"energy_cost_per_kwh": {{ states("sensor.electricity_price") }}}'

3. Тригерніть REST command на зміну ціни

automation:
  - id: bamdude_push_electricity_price
    alias: "Update BamDude electricity price"
    mode: restart
    trigger:
      - platform: state
        entity_id: sensor.electricity_price
        for: "00:00:05"
    condition:
      - condition: template
        value_template: >
          {{ states('sensor.electricity_price')|float(none) is not none }}
    action:
      - service: rest_command.bamdude_electricity_price
Постачальник Типовий sensor entity
Tibber sensor.tibber_prices (current price attribute)
Octopus Energy sensor.octopus_energy_electricity_current_rate
Nordpool sensor.nordpool_kwh_*

Перевірте, що sensor повертає число

BamDude чекає numeric value для energy_cost_per_kwh. Якщо ваш sensor повертає рядок із currency symbol, поправте template ({{ states('sensor.x')|float }}) перед push.

Більше про архітектуру HA-інтеграції — у Smart Plugs → Home Assistant.


Віджети на Stats Page

Сторінка Statistics показує енергію у трьох місцях:

  • Energy used (kWh) за діапазон, з урахуванням energy_tracking_mode
  • Energy cost у вашій валюті
  • Per-printer breakdown — який саме принтер тягне найбільше

Графіки і totals синхронізовані з тогл print vs total — перемикання перебудовує їх серверно. Повний тур по віджетах — у Statistics.


Дивіться також

  • Smart Plugs — типи розеток, конфігурація, HA / Tasmota / REST / MQTT setup
  • Archiving — поля energy_kwh / energy_cost на кожному рядку архіву
  • Statistics — energy віджет, cost charts, date-range фільтри
  • Print Queue — auto-power-off після друку + smart-plug-driven автоматизація черги
  • Export — CSV/XLSX з колонками per-print energy + cost

Поради

Беріть реальний тариф

Витягніть all-in rate з останнього рахунку (energy + delivery + taxes + fees). "Headline" rate з сайту постачальника зазвичай занижує реальну вартість.

Failed-друки теж коштують

energy_kwh записується для failed і cancelled архівів теж — це ще один аргумент за Failure Analysis і Obico. Кожен fail — це реальні гроші на лічильнику.

Snapshot baselines потребують uptime

Щогодинний snapshot loop працює лише поки BamDude працює. Якщо ви зупинили контейнер на два дні і питаєте 7-day total, відсутні 48 годин виглядають як flat baseline — warming-up іконка це підкаже.

Print mode для інвойсів, total mode для ROI

Перемикайтеся на print, експортуючи інвойси клієнтам — вони не повинні платити за ваш standby. Перемикайтеся на total, коли рахуєте, чи ферма окуповує себе.