Add цпш
This commit is contained in:
@@ -108,18 +108,24 @@ HEATING_TARGET_TEMP = Gauge('zont_heating_target_temp_celsius', 'Heating circuit
|
|||||||
HEATING_SETPOINT_TEMP = Gauge('zont_heating_setpoint_temp_celsius', 'Heating circuit setpoint temperature', ['device_id', 'circuit_id', 'name'])
|
HEATING_SETPOINT_TEMP = Gauge('zont_heating_setpoint_temp_celsius', 'Heating circuit setpoint temperature', ['device_id', 'circuit_id', 'name'])
|
||||||
HEATING_WORKTIME = Gauge('zont_heating_worktime_seconds', 'Heating circuit work time in last minute', ['device_id', 'circuit_id', 'name'])
|
HEATING_WORKTIME = Gauge('zont_heating_worktime_seconds', 'Heating circuit work time in last minute', ['device_id', 'circuit_id', 'name'])
|
||||||
HEATING_STATUS = Gauge('zont_heating_status', 'Heating circuit status code', ['device_id', 'circuit_id', 'name'])
|
HEATING_STATUS = Gauge('zont_heating_status', 'Heating circuit status code', ['device_id', 'circuit_id', 'name'])
|
||||||
# Фактическая температура контура отопления (подача теплоносителя)
|
|
||||||
HEATING_FLOW_TEMP = Gauge('zont_heating_flow_temp_celsius', 'Heating circuit flow temperature (actual)', ['device_id', 'circuit_id', 'name'])
|
HEATING_FLOW_TEMP = Gauge('zont_heating_flow_temp_celsius', 'Heating circuit flow temperature (actual)', ['device_id', 'circuit_id', 'name'])
|
||||||
|
|
||||||
# Котёл / OpenTherm
|
# Котёл / OpenTherm / цифровая шина
|
||||||
BOILER_CS = Gauge('zont_boiler_cs_celsius', 'Boiler calculated CH water temp', ['device_id', 'adapter_id'])
|
BOILER_CS = Gauge('zont_boiler_cs_celsius', 'Boiler calculated CH water temp (setpoint from boiler)', ['device_id', 'adapter_id'])
|
||||||
BOILER_DS = Gauge('zont_boiler_ds_celsius', 'Boiler DHW setpoint', ['device_id', 'adapter_id'])
|
BOILER_DS = Gauge('zont_boiler_ds_celsius', 'Boiler DHW setpoint', ['device_id', 'adapter_id'])
|
||||||
BOILER_BT = Gauge('zont_boiler_bt_celsius', 'Boiler actual flow water temp (OpenTherm)', ['device_id', 'adapter_id'])
|
BOILER_BT = Gauge('zont_boiler_water_celsius', 'Boiler actual flow water temp (water)', ['device_id', 'adapter_id'])
|
||||||
BOILER_DT = Gauge('zont_boiler_dt_celsius', 'Boiler actual DHW temp (OpenTherm)', ['device_id', 'adapter_id'])
|
BOILER_DT = Gauge('zont_boiler_dhw_celsius', 'Boiler actual DHW temp (dhw)', ['device_id', 'adapter_id'])
|
||||||
BOILER_OT = Gauge('zont_boiler_outdoor_celsius', 'Boiler outdoor temperature (OpenTherm)', ['device_id', 'adapter_id'])
|
BOILER_RWT = Gauge('zont_boiler_return_celsius', 'Boiler return water temp (return)', ['device_id', 'adapter_id'])
|
||||||
|
BOILER_OT = Gauge('zont_boiler_outdoor_celsius', 'Boiler outdoor temperature', ['device_id', 'adapter_id'])
|
||||||
|
BOILER_MODULATION = Gauge('zont_boiler_modulation_percent', 'Boiler burner modulation level (modul), %', ['device_id', 'adapter_id'])
|
||||||
|
BOILER_PRESSURE = Gauge('zont_boiler_pressure_bar', 'Boiler water pressure (press), bar', ['device_id', 'adapter_id'])
|
||||||
|
BOILER_STATE = Gauge('zont_boiler_state', 'Boiler state (0=off, 1=running, 2=error)', ['device_id', 'adapter_id'])
|
||||||
|
BOILER_ERROR_CODE = Gauge('zont_boiler_error_code', 'Boiler OEM error code (err)', ['device_id', 'adapter_id'])
|
||||||
BOILER_CONNECTED = Gauge('zont_boiler_connected', 'Boiler connected (1=yes,0=no)', ['device_id', 'adapter_id'])
|
BOILER_CONNECTED = Gauge('zont_boiler_connected', 'Boiler connected (1=yes,0=no)', ['device_id', 'adapter_id'])
|
||||||
BOILER_FAIL = Gauge('zont_boiler_fail', 'Boiler failure (1=fail)', ['device_id', 'adapter_id'])
|
BOILER_FAIL = Gauge('zont_boiler_fail', 'Boiler failure (1=fail)', ['device_id', 'adapter_id'])
|
||||||
BOILER_FLAME = Gauge('zont_boiler_flame', 'Boiler flame on (1=on,0=off)', ['device_id', 'adapter_id'])
|
BOILER_FLAME = Gauge('zont_boiler_flame', 'Boiler flame on (1=on,0=off)', ['device_id', 'adapter_id'])
|
||||||
|
BOILER_CH_ACTIVE = Gauge('zont_boiler_ch_active', 'Boiler CH active (1=on)', ['device_id', 'adapter_id'])
|
||||||
|
BOILER_DHW_ACTIVE = Gauge('zont_boiler_dhw_active', 'Boiler DHW active (1=on)', ['device_id', 'adapter_id'])
|
||||||
|
|
||||||
# Дискретные датчики
|
# Дискретные датчики
|
||||||
DOOR_OPEN = Gauge('zont_door_open', 'Door open (1=open, 0=closed)', ['device_id', 'input_id', 'name'])
|
DOOR_OPEN = Gauge('zont_door_open', 'Door open (1=open, 0=closed)', ['device_id', 'input_id', 'name'])
|
||||||
@@ -390,6 +396,21 @@ def build_analog_input_types(device):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
# --- Вычисление состояния котла ---
|
||||||
|
|
||||||
|
def compute_boiler_state(flags):
|
||||||
|
"""Вычисляет состояние котла по массиву флагов REST API.
|
||||||
|
Возвращает: 2 = авария, 1 = работает (горит пламя), 0 = выключен.
|
||||||
|
"""
|
||||||
|
if not flags:
|
||||||
|
return 0
|
||||||
|
if 'f' in flags: # авария
|
||||||
|
return 2
|
||||||
|
if 'fl' in flags: # горелка работает
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
# --- Описание событий ---
|
# --- Описание событий ---
|
||||||
|
|
||||||
def describe_event(ev_type, data):
|
def describe_event(ev_type, data):
|
||||||
@@ -502,7 +523,7 @@ def collect_events(did):
|
|||||||
events = events[-EVENT_MAX:]
|
events = events[-EVENT_MAX:]
|
||||||
|
|
||||||
_last_event_poll_time = now
|
_last_event_poll_time = now
|
||||||
|
|
||||||
logging.debug(f"raw_events returned {len(events)} events for window [{mintime}, {now}]")
|
logging.debug(f"raw_events returned {len(events)} events for window [{mintime}, {now}]")
|
||||||
|
|
||||||
if not events:
|
if not events:
|
||||||
@@ -630,50 +651,59 @@ def collect_metrics():
|
|||||||
if 'internet_weather' in device:
|
if 'internet_weather' in device:
|
||||||
INTERNET_WEATHER.labels(device_id=did).set(device['internet_weather'])
|
INTERNET_WEATHER.labels(device_id=did).set(device['internet_weather'])
|
||||||
|
|
||||||
# --- last-boiler-state (для ZONT H-1/H-2/H-1V с OpenTherm) ---
|
# --- last-boiler-state (для ZONT H-1/H-2/H-1V с OpenTherm/цифровой шиной) ---
|
||||||
last_boiler = io.get('last-boiler-state', {})
|
last_boiler = io.get('last-boiler-state', {})
|
||||||
if last_boiler:
|
if last_boiler:
|
||||||
ot = last_boiler.get('ot', {}) or {}
|
ot = last_boiler.get('ot', {}) or {}
|
||||||
|
adapter = 'boiler'
|
||||||
|
|
||||||
# Фактическая температура теплоносителя (подача) — то, что нужно
|
# Температуры
|
||||||
if ot.get('bt') is not None:
|
if ot.get('bt') is not None:
|
||||||
HEATING_FLOW_TEMP.labels(
|
BOILER_BT.labels(device_id=did, adapter_id=adapter).set(ot['bt'])
|
||||||
device_id=did, circuit_id='boiler', name='boiler_flow'
|
HEATING_FLOW_TEMP.labels(device_id=did, circuit_id=adapter, name='boiler_flow').set(ot['bt'])
|
||||||
).set(ot['bt'])
|
|
||||||
BOILER_BT.labels(device_id=did, adapter_id='boiler').set(ot['bt'])
|
|
||||||
|
|
||||||
# Расчётная температура теплоносителя
|
|
||||||
if ot.get('cs') is not None:
|
|
||||||
BOILER_CS.labels(device_id=did, adapter_id='boiler').set(ot['cs'])
|
|
||||||
|
|
||||||
# Фактическая температура ГВС
|
|
||||||
if ot.get('dt') is not None:
|
if ot.get('dt') is not None:
|
||||||
BOILER_DT.labels(device_id=did, adapter_id='boiler').set(ot['dt'])
|
BOILER_DT.labels(device_id=did, adapter_id=adapter).set(ot['dt'])
|
||||||
|
if ot.get('rwt') is not None:
|
||||||
# Уличная температура по данным котла
|
BOILER_RWT.labels(device_id=did, adapter_id=adapter).set(ot['rwt'])
|
||||||
if ot.get('ot') is not None:
|
if ot.get('ot') is not None:
|
||||||
BOILER_OT.labels(device_id=did, adapter_id='boiler').set(ot['ot'])
|
BOILER_OT.labels(device_id=did, adapter_id=adapter).set(ot['ot'])
|
||||||
|
if ot.get('cs') is not None:
|
||||||
|
BOILER_CS.labels(device_id=did, adapter_id=adapter).set(ot['cs'])
|
||||||
|
if ot.get('ds') is not None:
|
||||||
|
BOILER_DS.labels(device_id=did, adapter_id=adapter).set(ot['ds'])
|
||||||
|
|
||||||
# Флаг работы горелки
|
# Модуляция горелки
|
||||||
|
if ot.get('rml') is not None:
|
||||||
|
BOILER_MODULATION.labels(device_id=did, adapter_id=adapter).set(ot['rml'])
|
||||||
|
|
||||||
|
# Давление теплоносителя
|
||||||
|
if ot.get('wp') is not None:
|
||||||
|
BOILER_PRESSURE.labels(device_id=did, adapter_id=adapter).set(ot['wp'])
|
||||||
|
|
||||||
|
# Флаги состояния
|
||||||
flags = ot.get('s', []) or []
|
flags = ot.get('s', []) or []
|
||||||
BOILER_FLAME.labels(device_id=did, adapter_id='boiler').set(
|
BOILER_STATE.labels(device_id=did, adapter_id=adapter).set(compute_boiler_state(flags))
|
||||||
1 if 'fl' in flags else 0
|
BOILER_FLAME.labels(device_id=did, adapter_id=adapter).set(1 if 'fl' in flags else 0)
|
||||||
)
|
BOILER_CH_ACTIVE.labels(device_id=did, adapter_id=adapter).set(1 if 'ch' in flags else 0)
|
||||||
|
BOILER_DHW_ACTIVE.labels(device_id=did, adapter_id=adapter).set(1 if 'dhw' in flags else 0)
|
||||||
|
|
||||||
# Авария котла
|
# Авария (код + признак)
|
||||||
ff = ot.get('ff', {}) or {}
|
ff = ot.get('ff', {}) or {}
|
||||||
BOILER_FAIL.labels(device_id=did, adapter_id='boiler').set(
|
err_code = ff.get('c') or 0
|
||||||
1 if (ff.get('c') or ff.get('f')) else 0
|
err_flags = ff.get('f') or []
|
||||||
|
BOILER_ERROR_CODE.labels(device_id=did, adapter_id=adapter).set(err_code)
|
||||||
|
BOILER_FAIL.labels(device_id=did, adapter_id=adapter).set(
|
||||||
|
1 if (err_code or err_flags) else 0
|
||||||
)
|
)
|
||||||
|
|
||||||
# Целевая температура и время работы
|
# Целевая температура и время работы
|
||||||
if last_boiler.get('target_temp') is not None:
|
if last_boiler.get('target_temp') is not None:
|
||||||
HEATING_TARGET_TEMP.labels(
|
HEATING_TARGET_TEMP.labels(
|
||||||
device_id=did, circuit_id='boiler', name='boiler_target'
|
device_id=did, circuit_id=adapter, name='boiler_target'
|
||||||
).set(last_boiler['target_temp'])
|
).set(last_boiler['target_temp'])
|
||||||
if last_boiler.get('boiler_work_time') is not None:
|
if last_boiler.get('boiler_work_time') is not None:
|
||||||
HEATING_WORKTIME.labels(
|
HEATING_WORKTIME.labels(
|
||||||
device_id=did, circuit_id='boiler', name='boiler_worktime'
|
device_id=did, circuit_id=adapter, name='boiler_worktime'
|
||||||
).set(last_boiler['boiler_work_time'])
|
).set(last_boiler['boiler_work_time'])
|
||||||
|
|
||||||
# --- z3k-state ---
|
# --- z3k-state ---
|
||||||
@@ -726,31 +756,58 @@ def collect_metrics():
|
|||||||
if flow_temp is not None:
|
if flow_temp is not None:
|
||||||
HEATING_FLOW_TEMP.labels(device_id=did, circuit_id=obj_id, name=name).set(flow_temp)
|
HEATING_FLOW_TEMP.labels(device_id=did, circuit_id=obj_id, name=name).set(flow_temp)
|
||||||
|
|
||||||
# Адаптер котла / OpenTherm
|
# Адаптер котла / OpenTherm / цифровая шина (z3k)
|
||||||
if isinstance(obj, dict) and 'ot' in obj and 'status' in obj:
|
if isinstance(obj, dict) and 'ot' in obj and 'status' in obj:
|
||||||
ot = obj.get('ot', {}) or {}
|
ot = obj.get('ot', {}) or {}
|
||||||
if ot.get('cs') is not None:
|
|
||||||
BOILER_CS.labels(device_id=did, adapter_id=obj_id).set(ot['cs'])
|
# Температуры
|
||||||
if ot.get('ds') is not None:
|
|
||||||
BOILER_DS.labels(device_id=did, adapter_id=obj_id).set(ot['ds'])
|
|
||||||
if ot.get('bt') is not None:
|
if ot.get('bt') is not None:
|
||||||
BOILER_BT.labels(device_id=did, adapter_id=obj_id).set(ot['bt'])
|
BOILER_BT.labels(device_id=did, adapter_id=obj_id).set(ot['bt'])
|
||||||
HEATING_FLOW_TEMP.labels(device_id=did, circuit_id=obj_id, name=name).set(ot['bt'])
|
HEATING_FLOW_TEMP.labels(device_id=did, circuit_id=obj_id, name=name).set(ot['bt'])
|
||||||
if ot.get('dt') is not None:
|
if ot.get('dt') is not None:
|
||||||
BOILER_DT.labels(device_id=did, adapter_id=obj_id).set(ot['dt'])
|
BOILER_DT.labels(device_id=did, adapter_id=obj_id).set(ot['dt'])
|
||||||
|
if ot.get('rwt') is not None:
|
||||||
|
BOILER_RWT.labels(device_id=did, adapter_id=obj_id).set(ot['rwt'])
|
||||||
if ot.get('ot') is not None:
|
if ot.get('ot') is not None:
|
||||||
BOILER_OT.labels(device_id=did, adapter_id=obj_id).set(ot['ot'])
|
BOILER_OT.labels(device_id=did, adapter_id=obj_id).set(ot['ot'])
|
||||||
|
if ot.get('cs') is not None:
|
||||||
|
BOILER_CS.labels(device_id=did, adapter_id=obj_id).set(ot['cs'])
|
||||||
|
if ot.get('cs2') is not None:
|
||||||
|
BOILER_CS.labels(device_id=did, adapter_id=f"{obj_id}_ch2").set(ot['cs2'])
|
||||||
|
if ot.get('ds') is not None:
|
||||||
|
BOILER_DS.labels(device_id=did, adapter_id=obj_id).set(ot['ds'])
|
||||||
|
|
||||||
|
# Модуляция горелки
|
||||||
|
if ot.get('rml') is not None:
|
||||||
|
BOILER_MODULATION.labels(device_id=did, adapter_id=obj_id).set(ot['rml'])
|
||||||
|
if ot.get('mrml') is not None:
|
||||||
|
BOILER_MODULATION.labels(device_id=did, adapter_id=f"{obj_id}_max").set(ot['mrml'])
|
||||||
|
|
||||||
|
# Давление теплоносителя
|
||||||
|
if ot.get('wp') is not None:
|
||||||
|
BOILER_PRESSURE.labels(device_id=did, adapter_id=obj_id).set(ot['wp'])
|
||||||
|
|
||||||
|
# Флаги состояния
|
||||||
flags = ot.get('s', []) or []
|
flags = ot.get('s', []) or []
|
||||||
|
BOILER_STATE.labels(device_id=did, adapter_id=obj_id).set(compute_boiler_state(flags))
|
||||||
BOILER_FLAME.labels(device_id=did, adapter_id=obj_id).set(1 if 'fl' in flags else 0)
|
BOILER_FLAME.labels(device_id=did, adapter_id=obj_id).set(1 if 'fl' in flags else 0)
|
||||||
|
BOILER_CH_ACTIVE.labels(device_id=did, adapter_id=obj_id).set(1 if 'ch' in flags else 0)
|
||||||
|
BOILER_DHW_ACTIVE.labels(device_id=did, adapter_id=obj_id).set(1 if 'dhw' in flags else 0)
|
||||||
|
|
||||||
|
# Авария
|
||||||
|
ff = ot.get('ff', {}) or {}
|
||||||
|
err_code = ff.get('c') or 0
|
||||||
|
err_flags = ff.get('f') or []
|
||||||
|
BOILER_ERROR_CODE.labels(device_id=did, adapter_id=obj_id).set(err_code)
|
||||||
|
BOILER_FAIL.labels(device_id=did, adapter_id=obj_id).set(
|
||||||
|
1 if (err_code or err_flags) else 0
|
||||||
|
)
|
||||||
|
|
||||||
|
# Статус адаптера
|
||||||
status = obj.get('status', {})
|
status = obj.get('status', {})
|
||||||
BOILER_CONNECTED.labels(device_id=did, adapter_id=obj_id).set(
|
BOILER_CONNECTED.labels(device_id=did, adapter_id=obj_id).set(
|
||||||
0 if status.get('no_boiler_connection') else 1
|
0 if status.get('no_boiler_connection') else 1
|
||||||
)
|
)
|
||||||
BOILER_FAIL.labels(device_id=did, adapter_id=obj_id).set(
|
|
||||||
1 if status.get('boiler_fail') else 0
|
|
||||||
)
|
|
||||||
|
|
||||||
logging.info(f"Metrics collected successfully for device {DEVICE_ID}")
|
logging.info(f"Metrics collected successfully for device {DEVICE_ID}")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user