|
2 | 2 | import asyncio
|
3 | 3 | from datetime import datetime, timedelta, timezone
|
4 | 4 | import logging
|
| 5 | +from math import sqrt |
5 | 6 | import time
|
6 | 7 | from typing import Dict
|
7 | 8 |
|
@@ -675,46 +676,53 @@ async def async_update_device_info(self, boot_info: dict):
|
675 | 676 |
|
676 | 677 | def process_phases(self, data):
|
677 | 678 | """Process phase data from meter values payload."""
|
678 |
| - extra_attr = {} |
| 679 | + measurand_data = {} |
679 | 680 | for sv in data:
|
680 |
| - # ordered Dict for each phase eg {"metric":{"unit":"V","L1":"230"...}} |
681 |
| - if sv.get(om.phase.value) is not None: |
682 |
| - metric = sv[om.measurand.value] |
683 |
| - if extra_attr.get(metric) is None: |
684 |
| - extra_attr[metric] = {} |
685 |
| - (extra_attr[metric])[om.unit.value] = sv.get(om.unit.value) |
686 |
| - if sv.get(om.phase.value) in [Phase.l1.value, Phase.l1_n.value]: |
687 |
| - (extra_attr[metric])[sv.get(om.phase.value)] = float( |
688 |
| - sv[om.value.value] |
689 |
| - ) |
690 |
| - if sv.get(om.phase.value) in [Phase.l2.value, Phase.l2_n.value]: |
691 |
| - (extra_attr[metric])[sv.get(om.phase.value)] = float( |
692 |
| - sv[om.value.value] |
693 |
| - ) |
694 |
| - if sv.get(om.phase.value) in [Phase.l3.value, Phase.l3_n.value]: |
695 |
| - (extra_attr[metric])[sv.get(om.phase.value)] = float( |
696 |
| - sv[om.value.value] |
697 |
| - ) |
698 |
| - for metric, value in extra_attr.items(): |
699 |
| - # _LOGGER.debug("Metric: %s, extra attributes: %s", metric, value) |
700 |
| - if metric in Measurand.voltage.value: |
701 |
| - sum = ( |
702 |
| - value[Phase.l1_n.value] |
703 |
| - + value[Phase.l2_n.value] |
704 |
| - + value[Phase.l3_n.value] |
705 |
| - ) |
706 |
| - self._metrics[metric] = round(sum / 3, 1) |
707 |
| - if metric in [ |
| 681 | + # create ordered Dict for each measurand, eg {"voltage":{"unit":"V","L1":"230"...}} |
| 682 | + measurand = sv.get(om.measurand.value, None) |
| 683 | + phase = sv.get(om.phase.value, None) |
| 684 | + value = sv.get(om.value.value, None) |
| 685 | + unit = sv.get(om.unit.value, None) |
| 686 | + if measurand is not None and phase is not None: |
| 687 | + if measurand not in measurand_data: |
| 688 | + measurand_data[measurand] = {} |
| 689 | + measurand_data[measurand][om.unit.value] = unit |
| 690 | + measurand_data[measurand][phase] = float(value) |
| 691 | + # store the measurand data as extra attributes |
| 692 | + self._extra_attr.update(measurand_data) |
| 693 | + for metric, phase_info in measurand_data.items(): |
| 694 | + # _LOGGER.debug("Metric: %s, extra attributes: %s", metric, phase_info) |
| 695 | + metric_value = None |
| 696 | + if metric in [Measurand.voltage.value]: |
| 697 | + if Phase.l1_n.value in phase_info: |
| 698 | + """Line-neutral voltages are averaged.""" |
| 699 | + metric_value = ( |
| 700 | + phase_info.get(Phase.l1_n.value, 0) |
| 701 | + + phase_info.get(Phase.l2_n.value, 0) |
| 702 | + + phase_info.get(Phase.l3_n.value, 0) |
| 703 | + ) / 3 |
| 704 | + elif Phase.l1_l2.value in phase_info: |
| 705 | + """Line-line voltages are converted to line-neutral and averaged.""" |
| 706 | + metric_value = ( |
| 707 | + phase_info.get(Phase.l1_l2.value, 0) |
| 708 | + + phase_info.get(Phase.l2_l3.value, 0) |
| 709 | + + phase_info.get(Phase.l3_l1.value, 0) |
| 710 | + ) / (3 * sqrt(3)) |
| 711 | + elif metric in [ |
708 | 712 | Measurand.current_import.value,
|
709 | 713 | Measurand.current_export.value,
|
| 714 | + Measurand.power_active_import.value, |
| 715 | + Measurand.power_active_export.value, |
710 | 716 | ]:
|
711 |
| - sum = ( |
712 |
| - value[Phase.l1.value] |
713 |
| - + value[Phase.l2.value] |
714 |
| - + value[Phase.l3.value] |
715 |
| - ) |
716 |
| - self._metrics[metric] = round(sum, 1) |
717 |
| - self._extra_attr[metric] = value |
| 717 | + """Line currents and powers are summed.""" |
| 718 | + if Phase.l1.value in phase_info: |
| 719 | + metric_value = ( |
| 720 | + phase_info.get(Phase.l1.value, 0) |
| 721 | + + phase_info.get(Phase.l2.value, 0) |
| 722 | + + phase_info.get(Phase.l3.value, 0) |
| 723 | + ) |
| 724 | + if metric_value is not None: |
| 725 | + self._metrics[metric] = round(metric_value, 1) |
718 | 726 |
|
719 | 727 | @on(Action.MeterValues)
|
720 | 728 | def on_meter_values(self, connector_id: int, meter_value: Dict, **kwargs):
|
|
0 commit comments