|
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 |
|
@@ -735,46 +736,53 @@ async def async_update_device_info(self, boot_info: dict):
|
735 | 736 |
|
736 | 737 | def process_phases(self, data):
|
737 | 738 | """Process phase data from meter values payload."""
|
738 |
| - extra_attr = {} |
| 739 | + measurand_data = {} |
739 | 740 | for sv in data:
|
740 |
| - # ordered Dict for each phase eg {"metric":{"unit":"V","L1":"230"...}} |
741 |
| - if sv.get(om.phase.value) is not None: |
742 |
| - metric = sv[om.measurand.value] |
743 |
| - if extra_attr.get(metric) is None: |
744 |
| - extra_attr[metric] = {} |
745 |
| - (extra_attr[metric])[om.unit.value] = sv.get(om.unit.value) |
746 |
| - if sv.get(om.phase.value) in [Phase.l1.value, Phase.l1_n.value]: |
747 |
| - (extra_attr[metric])[sv.get(om.phase.value)] = float( |
748 |
| - sv[om.value.value] |
749 |
| - ) |
750 |
| - if sv.get(om.phase.value) in [Phase.l2.value, Phase.l2_n.value]: |
751 |
| - (extra_attr[metric])[sv.get(om.phase.value)] = float( |
752 |
| - sv[om.value.value] |
753 |
| - ) |
754 |
| - if sv.get(om.phase.value) in [Phase.l3.value, Phase.l3_n.value]: |
755 |
| - (extra_attr[metric])[sv.get(om.phase.value)] = float( |
756 |
| - sv[om.value.value] |
757 |
| - ) |
758 |
| - for metric, value in extra_attr.items(): |
759 |
| - # _LOGGER.debug("Metric: %s, extra attributes: %s", metric, value) |
760 |
| - if metric in Measurand.voltage.value: |
761 |
| - sum = ( |
762 |
| - value[Phase.l1_n.value] |
763 |
| - + value[Phase.l2_n.value] |
764 |
| - + value[Phase.l3_n.value] |
765 |
| - ) |
766 |
| - self._metrics[metric] = round(sum / 3, 1) |
767 |
| - if metric in [ |
| 741 | + # create ordered Dict for each measurand, eg {"voltage":{"unit":"V","L1":"230"...}} |
| 742 | + measurand = sv.get(om.measurand.value, None) |
| 743 | + phase = sv.get(om.phase.value, None) |
| 744 | + value = sv.get(om.value.value, None) |
| 745 | + unit = sv.get(om.unit.value, None) |
| 746 | + if measurand is not None and phase is not None: |
| 747 | + if measurand not in measurand_data: |
| 748 | + measurand_data[measurand] = {} |
| 749 | + measurand_data[measurand][om.unit.value] = unit |
| 750 | + measurand_data[measurand][phase] = float(value) |
| 751 | + # store the measurand data as extra attributes |
| 752 | + self._extra_attr.update(measurand_data) |
| 753 | + for metric, phase_info in measurand_data.items(): |
| 754 | + # _LOGGER.debug("Metric: %s, extra attributes: %s", metric, phase_info) |
| 755 | + metric_value = None |
| 756 | + if metric in [Measurand.voltage.value]: |
| 757 | + if Phase.l1_n.value in phase_info: |
| 758 | + """Line-neutral voltages are averaged.""" |
| 759 | + metric_value = ( |
| 760 | + phase_info.get(Phase.l1_n.value, 0) |
| 761 | + + phase_info.get(Phase.l2_n.value, 0) |
| 762 | + + phase_info.get(Phase.l3_n.value, 0) |
| 763 | + ) / 3 |
| 764 | + elif Phase.l1_l2.value in phase_info: |
| 765 | + """Line-line voltages are converted to line-neutral and averaged.""" |
| 766 | + metric_value = ( |
| 767 | + phase_info.get(Phase.l1_l2.value, 0) |
| 768 | + + phase_info.get(Phase.l2_l3.value, 0) |
| 769 | + + phase_info.get(Phase.l3_l1.value, 0) |
| 770 | + ) / (3 * sqrt(3)) |
| 771 | + elif metric in [ |
768 | 772 | Measurand.current_import.value,
|
769 | 773 | Measurand.current_export.value,
|
| 774 | + Measurand.power_active_import.value, |
| 775 | + Measurand.power_active_export.value, |
770 | 776 | ]:
|
771 |
| - sum = ( |
772 |
| - value[Phase.l1.value] |
773 |
| - + value[Phase.l2.value] |
774 |
| - + value[Phase.l3.value] |
775 |
| - ) |
776 |
| - self._metrics[metric] = round(sum, 1) |
777 |
| - self._extra_attr[metric] = value |
| 777 | + """Line currents and powers are summed.""" |
| 778 | + if Phase.l1.value in phase_info: |
| 779 | + metric_value = ( |
| 780 | + phase_info.get(Phase.l1.value, 0) |
| 781 | + + phase_info.get(Phase.l2.value, 0) |
| 782 | + + phase_info.get(Phase.l3.value, 0) |
| 783 | + ) |
| 784 | + if metric_value is not None: |
| 785 | + self._metrics[metric] = round(metric_value, 1) |
778 | 786 |
|
779 | 787 | @on(Action.MeterValues)
|
780 | 788 | def on_meter_values(self, connector_id: int, meter_value: Dict, **kwargs):
|
|
0 commit comments