Skip to content

Commit fc03367

Browse files
committed
bugfix meter value logic
1 parent 6616437 commit fc03367

File tree

2 files changed

+81
-16
lines changed

2 files changed

+81
-16
lines changed

custom_components/ocpp/api.py

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,29 +1126,40 @@ def on_meter_values(self, connector_id: int, meter_value: dict, **kwargs):
11261126
measurand = DEFAULT_MEASURAND
11271127
unit = DEFAULT_ENERGY_UNIT
11281128

1129+
if measurand == DEFAULT_MEASURAND and unit is None:
1130+
unit = DEFAULT_ENERGY_UNIT
1131+
1132+
if self._metrics[csess.meter_start.value].value == 0:
1133+
# Charger reports Energy.Active.Import.Register directly as Session energy for transactions.
1134+
self._charger_reports_session_energy = True
1135+
11291136
if phase is None:
11301137
if unit == DEFAULT_POWER_UNIT:
11311138
self._metrics[measurand].value = float(value) / 1000
11321139
self._metrics[measurand].unit = HA_POWER_UNIT
1133-
elif unit == DEFAULT_ENERGY_UNIT or "Energy" in str(measurand):
1134-
if self._metrics[csess.meter_start.value].value == 0:
1135-
# Charger reports Energy.Active.Import.Register directly as Session energy for transactions
1136-
self._charger_reports_session_energy = True
1137-
if (
1138-
transaction_matches
1139-
and self._charger_reports_session_energy
1140-
and measurand == DEFAULT_MEASURAND
1141-
and connector_id
1142-
):
1143-
self._metrics[csess.session_energy.value].value = (
1144-
float(value) / 1000
1140+
elif (
1141+
measurand == DEFAULT_MEASURAND
1142+
and self._charger_reports_session_energy
1143+
):
1144+
if transaction_matches:
1145+
if unit == DEFAULT_ENERGY_UNIT:
1146+
value = float(value) / 1000
1147+
unit = HA_ENERGY_UNIT
1148+
self._metrics[csess.session_energy.value].value = float(
1149+
value
11451150
)
1151+
self._metrics[csess.session_energy.value].unit = unit
11461152
self._metrics[csess.session_energy.value].extra_attr[
11471153
cstat.id_tag.name
11481154
] = self._metrics[cstat.id_tag.value].value
1149-
elif (
1150-
transaction_matches or self._charger_reports_session_energy
1151-
):
1155+
else:
1156+
if unit == DEFAULT_ENERGY_UNIT:
1157+
value = float(value) / 1000
1158+
unit = HA_ENERGY_UNIT
1159+
self._metrics[measurand].value = float(value)
1160+
self._metrics[measurand].unit = unit
1161+
elif unit == DEFAULT_ENERGY_UNIT:
1162+
if transaction_matches:
11521163
self._metrics[measurand].value = float(value) / 1000
11531164
self._metrics[measurand].unit = HA_ENERGY_UNIT
11541165
else:

tests/test_charge_point.py

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,6 @@ async def test_services(hass, socket_enabled):
308308
cp.send_meter_err_phases(),
309309
cp.send_meter_line_voltage(),
310310
cp.send_meter_periodic_data(),
311-
cp.send_main_meter_clock_data(),
312311
# add delay to allow meter data to be processed
313312
cp.send_stop_transaction(2),
314313
),
@@ -370,6 +369,9 @@ async def test_services(hass, socket_enabled):
370369
pass
371370
await ws.close()
372371
assert int(cs.get_metric("test_cpid", "Frequency")) == int(50)
372+
assert float(cs.get_metric("test_cpid", "Energy.Active.Import.Register")) == float(
373+
1101.452
374+
)
373375

374376
await asyncio.sleep(1)
375377

@@ -410,6 +412,33 @@ async def test_services(hass, socket_enabled):
410412

411413
await asyncio.sleep(1)
412414

415+
# test ocpp messages sent from charger that don't support errata 3.9 with meter values with kWh as energy unit
416+
async with websockets.connect(
417+
"ws://127.0.0.1:9000/CP_1_non_er_3.9",
418+
subprotocols=["ocpp1.6"],
419+
) as ws:
420+
# use a different id for debugging
421+
cp = ChargePoint("CP_1_non_errata_3.9", ws)
422+
try:
423+
await asyncio.wait_for(
424+
asyncio.gather(
425+
cp.start(),
426+
cp.send_start_transaction(0),
427+
cp.send_meter_energy_kwh(),
428+
cp.send_meter_clock_data(),
429+
# add delay to allow meter data to be processed
430+
cp.send_stop_transaction(2),
431+
),
432+
timeout=5,
433+
)
434+
except asyncio.TimeoutError:
435+
pass
436+
await ws.close()
437+
438+
assert int(cs.get_metric("test_cpid", "Energy.Active.Import.Register")) == int(1101)
439+
assert int(cs.get_metric("test_cpid", "Energy.Session")) == int(11)
440+
assert cs.get_unit("test_cpid", "Energy.Active.Import.Register") == "kWh"
441+
413442
# test ocpp rejection messages sent from charger to cms
414443
cs.charge_points["test_cpid"].received_boot_notification = False
415444
cs.charge_points["test_cpid"].post_connect_success = False
@@ -971,6 +1000,31 @@ async def send_meter_err_phases(self):
9711000
resp = await self.call(request)
9721001
assert resp is not None
9731002

1003+
async def send_meter_energy_kwh(self):
1004+
"""Send periodic energy meter value with kWh unit."""
1005+
while self.active_transactionId == 0:
1006+
await asyncio.sleep(1)
1007+
request = call.MeterValuesPayload(
1008+
connector_id=1,
1009+
transaction_id=self.active_transactionId,
1010+
meter_value=[
1011+
{
1012+
"timestamp": "2021-06-21T16:15:09Z",
1013+
"sampledValue": [
1014+
{
1015+
"unit": "kWh",
1016+
"value": "11",
1017+
"context": "Sample.Periodic",
1018+
"format": "Raw",
1019+
"measurand": "Energy.Active.Import.Register",
1020+
},
1021+
],
1022+
}
1023+
],
1024+
)
1025+
resp = await self.call(request)
1026+
assert resp is not None
1027+
9741028
async def send_main_meter_clock_data(self):
9751029
"""Send periodic main meter value. Main meter values dont have transaction_id."""
9761030
while self.active_transactionId == 0:

0 commit comments

Comments
 (0)