1# Copyright: (c)  2024, Intel Corporation
2
3import logging
4
5import pytest
6from abstract.PowerMonitor import PowerMonitor
7from twister_harness import DeviceAdapter
8from utils.UtilityFunctions import current_RMS
9
10logger = logging.getLogger(__name__)
11
12
13@pytest.mark.parametrize("probe_class", ['stm_powershield'], indirect=True)
14def test_power_harness(probe_class: PowerMonitor, test_data, request, dut: DeviceAdapter):
15    """
16    This test measures and validates the RMS current values from the power monitor
17    and compares them against expected RMS values.
18
19    Arguments:
20    probe_class -- The Abstract class of the power monitor.
21    test_data -- Fixture to prepare data.
22    request -- Request object that provides access to test configuration.
23    dut -- The Device Under Test (DUT) that the power monitor is measuring.
24    """
25
26    # Initialize the probe with the provided path
27    probe = probe_class  # Instantiate the power monitor probe
28
29    # Get test data
30    measurements_dict = test_data
31
32    # Start the measurement process with the provided duration
33    probe.measure(time=measurements_dict['measurement_duration'])
34
35    # Retrieve the measured data
36    data = probe.get_data()
37
38    # Calculate the RMS current values using utility functions
39    rms_values_measured = current_RMS(
40        data,
41        trim=measurements_dict['elements_to_trim'],
42        num_peaks=measurements_dict['num_of_transitions'],
43        peak_distance=measurements_dict['min_peak_distance'],
44        peak_height=measurements_dict['min_peak_height'],
45        padding=measurements_dict['peak_padding'],
46    )
47
48    # # Convert measured values from amps to milliamps for comparison
49    rms_values_in_milliamps = [value * 1e3 for value in rms_values_measured]
50
51    # # Log the calculated values in milliamps for debugging purposes
52    logger.debug(f"Measured RMS values in mA: {rms_values_in_milliamps}")
53
54    tuples = zip(measurements_dict['expected_rms_values'], rms_values_in_milliamps, strict=False)
55    for expected_rms_value, measured_rms_value in tuples:
56        assert is_within_tolerance(
57            measured_rms_value, expected_rms_value, measurements_dict['tolerance_percentage']
58        )
59
60
61def is_within_tolerance(measured_rms_value, expected_rms_value, tolerance_percentage) -> bool:
62    """
63    Checks if the measured RMS value is within the acceptable tolerance.
64
65    Arguments:
66    measured_rms_value -- The measured RMS current value in milliamps.
67    expected_rms_value -- The expected RMS current value in milliamps.
68    tolerance_percentage -- The allowed tolerance as a percentage of the expected value.
69
70    Returns:
71    bool -- True if the measured value is within the tolerance, False otherwise.
72    """
73    # Calculate tolerance as a percentage of the expected value
74    tolerance = (tolerance_percentage / 100) * expected_rms_value
75
76    # Log the values for debugging purposes
77    logger.debug(f"Expected RMS: {expected_rms_value:.2f} mA")
78    logger.debug(f"Tolerance: {tolerance:.2f} mA")
79    logger.debug(f"Measured  RMS: {measured_rms_value:.2f} mA")
80    logger.info(
81        'RECORD: ['
82        '{'
83        f'"expected_rms_ua": {expected_rms_value:.2f}'
84        '}'
85        ',{'
86        f'"tolerance_ua": {tolerance:.2f}'
87        '}'
88        ',{'
89        f'"measured_rms_ua": {measured_rms_value:.2f}'
90        '}'
91        ']'
92    )
93    # Check if the measured value is within the range of expected ± tolerance
94    return (expected_rms_value - tolerance) < measured_rms_value < (expected_rms_value + tolerance)
95