277277
278278-- [[ ELECTRICAL ENERGY MEASUREMENT CLUSTER ATTRIBUTES ]] --
279279
280- local function report_power_consumption_to_st_energy (device , endpoint_id , latest_total_imported_energy_wh )
280+ local function report_power_consumption_to_st_energy (device , total_imported_energy_wh )
281+ device :set_field (fields .TOTAL_IMPORTED_ENERGY , total_imported_energy_wh , { persist = true })
282+
281283 local current_time = os.time ()
282284 local last_time = device :get_field (fields .LAST_IMPORTED_REPORT_TIMESTAMP ) or 0
283285
@@ -287,54 +289,45 @@ local function report_power_consumption_to_st_energy(device, endpoint_id, latest
287289 end
288290 device :set_field (fields .LAST_IMPORTED_REPORT_TIMESTAMP , current_time , { persist = true })
289291
290- local state_device = switch_utils .find_child (device , endpoint_id ) or device
292+ local state_device = switch_utils .find_child (device , device : get_field ( fields . POWER_CONSUMPTION_REPORT_EP ) ) or device
291293 local previous_imported_report = state_device :get_latest_state (" main" , capabilities .powerConsumptionReport .ID ,
292- capabilities .powerConsumptionReport .powerConsumption .NAME , { energy = latest_total_imported_energy_wh })
293- local energy_delta_wh = math.max ( latest_total_imported_energy_wh - previous_imported_report .energy , 0.0 ) -- Calculate the energy delta between reports
294+ capabilities .powerConsumptionReport .powerConsumption .NAME , { energy = total_imported_energy_wh }) -- default value if nil
295+ local energy_delta_wh = total_imported_energy_wh - previous_imported_report .energy -- Calculate the energy delta between reports
294296
295297 -- Report the energy consumed during the time interval. The unit of these values should be 'Wh'
296298 local epoch_to_iso8601 = function (time ) return os.date (" !%Y-%m-%dT%H:%M:%SZ" , time ) end -- Return an ISO-8061 timestamp from UTC
297- device :emit_event_for_endpoint (endpoint_id , capabilities .powerConsumptionReport .powerConsumption ({
299+ device :emit_event_for_endpoint (device : get_field ( fields . POWER_CONSUMPTION_REPORT_EP ) , capabilities .powerConsumptionReport .powerConsumption ({
298300 start = epoch_to_iso8601 (last_time ),
299301 [" end" ] = epoch_to_iso8601 (current_time - 1 ),
300302 deltaEnergy = energy_delta_wh ,
301- energy = latest_total_imported_energy_wh
303+ energy = total_imported_energy_wh
302304 }))
303305end
304306
305- function AttributeHandlers .cumul_energy_imported_handler (driver , device , ib , response )
306- if ib .data .elements .energy then
307- local watt_hour_value = ib .data .elements .energy .value / fields .CONVERSION_CONST_MILLIWATT_TO_WATT
308- device :set_field (fields .TOTAL_IMPORTED_ENERGY , watt_hour_value , {persist = true })
309- device :emit_event_for_endpoint (ib .endpoint_id , capabilities .energyMeter .energy ({ value = watt_hour_value , unit = " Wh" }))
310- report_power_consumption_to_st_energy (device , ib .endpoint_id , device :get_field (fields .TOTAL_IMPORTED_ENERGY ))
311- end
312- end
313-
314- function AttributeHandlers .per_energy_imported_handler (driver , device , ib , response )
315- if ib .data .elements .energy then
316- local watt_hour_value = ib .data .elements .energy .value / fields .CONVERSION_CONST_MILLIWATT_TO_WATT
317- local latest_energy_report = device :get_field (fields .TOTAL_IMPORTED_ENERGY ) or 0
318- local summed_energy_report = latest_energy_report + watt_hour_value
319- device :set_field (fields .TOTAL_IMPORTED_ENERGY , summed_energy_report , {persist = true })
320- device :emit_event_for_endpoint (ib .endpoint_id , capabilities .energyMeter .energy ({ value = summed_energy_report , unit = " Wh" }))
321- report_power_consumption_to_st_energy (device , ib .endpoint_id , device :get_field (fields .TOTAL_IMPORTED_ENERGY ))
322- end
323- end
324-
325- function AttributeHandlers .energy_imported_factory (is_cumulative_report )
307+ function AttributeHandlers .energy_imported_factory (is_periodic_report )
326308 return function (driver , device , ib , response )
327309 -- workaround: ignore devices supporting Eve's private energy cluster AND the ElectricalEnergyMeasurement cluster
328310 local EVE_MANUFACTURER_ID , EVE_PRIVATE_CLUSTER_ID = 0x130A , 0x130AFC01
329311 local eve_private_energy_eps = device :get_endpoints (EVE_PRIVATE_CLUSTER_ID )
330312 if device .manufacturer_info .vendor_id == EVE_MANUFACTURER_ID and # eve_private_energy_eps > 0 then
331313 return
332314 end
315+ local state_device = switch_utils .find_child (device , ib .endpoint_id ) or device
316+ local energy_meter_latest_state = state_device :get_latest_state (
317+ " main" , capabilities .energyMeter .ID , capabilities .energyMeter .energy .NAME , 0 -- 0 as the default if state is nil
318+ )
319+ if ib .data .elements .energy then
320+ local energy_imported_wh = ib .data .elements .energy .value / fields .CONVERSION_CONST_MILLIWATT_TO_WATT
321+ if is_periodic_report then
322+ -- handle this report only if cumulative reports are not supported
323+ if device :get_field (fields .CUMULATIVE_REPORTS_SUPPORTED ) then return end
324+ energy_imported_wh = energy_imported_wh + energy_meter_latest_state
325+ end
326+ device :emit_event_for_endpoint (ib .endpoint_id , capabilities .energyMeter .energy ({ value = energy_imported_wh , unit = " Wh" }))
333327
334- if is_cumulative_report then
335- AttributeHandlers .cumul_energy_imported_handler (driver , device , ib , response )
336- elseif device :get_field (fields .CUMULATIVE_REPORTS_NOT_SUPPORTED ) then
337- AttributeHandlers .per_energy_imported_handler (driver , device , ib , response )
328+ local energy_wh_delta = energy_imported_wh - energy_meter_latest_state
329+ local device_total_imported_energy_wh = (device :get_field (fields .TOTAL_IMPORTED_ENERGY ) or 0 ) + energy_wh_delta
330+ report_power_consumption_to_st_energy (device , device_total_imported_energy_wh )
338331 end
339332 end
340333end
0 commit comments