Ejemplo n.º 1
0
 def __init__(self):
     self.power = Power()
     self.L1 = Phase()
     self.L2 = Phase()
     self.L3 = Phase()
     self.tariff_1 = Tariff()
     self.tariff_2 = Tariff()
     self.frequency = float('nan')
Ejemplo n.º 2
0
def test_add():
    p1 = Power(1, 1, 1)
    p2 = Power(1, 1, 1)
    p_total = p1 + p2

    assert isinstance(p_total, Power)
    assert p_total.apparent == p1.apparent + p2.apparent
    assert p_total.active == p1.active + p2.active
    assert p_total.reactive != p1.reactive + p2.reactive
    assert p_total.reactive == sqrt((p2.apparent + p1.apparent)**2 -
                                    (p2.active + p1.active)**2)
Ejemplo n.º 3
0
def test_sub():
    # Reactive power values shouldn't matter -> setting them here to something absurd.
    p2 = Power(3, 2, 3)
    p1 = Power(2, 1, 4)
    p_total = p2 - p1

    assert isinstance(p_total, Power)
    assert p_total.apparent == p2.apparent - p1.apparent
    assert p_total.active == p2.active - p1.active
    assert p_total.reactive != p2.reactive - p1.reactive
    assert p_total.reactive == sqrt((p2.apparent - p1.apparent)**2 -
                                    (p2.active - p1.active)**2)
Ejemplo n.º 4
0
def test_mul():
    p1 = Power(1000, 1000, 1000)
    p_total = p1 * 7200

    assert isinstance(p_total, Energy)
    assert p_total.apparent == 1000 * 2
    assert p_total.active == p1.active * 2
    assert p_total.reactive == p1.reactive * 2

    p_total = p1 * timedelta(minutes=30)

    assert isinstance(p_total, Energy)
    assert p_total.apparent == 1000 / 2
    assert p_total.active == p1.active / 2
    assert p_total.reactive == p1.reactive / 2
Ejemplo n.º 5
0
class PAC(object):
    _master = None
    _unit = None

    def __init__(self):
        self.power = Power()
        self.L1 = Phase()
        self.L2 = Phase()
        self.L3 = Phase()
        self.tariff_1 = Tariff()
        self.tariff_2 = Tariff()
        self.frequency = float('nan')

    def _from_float(self, values):
        return [unpack(str('>f'), pack(str('>HH'), *values[i:i + 2]))[0] for i in range(0, len(values), 2)]

    def _from_double(self, values):
        return [unpack(str('>d'), pack(str('>HHHH'), *values[i:i + 4]))[0] for i in range(0, len(values), 4)]

    def read_input_register(self, register_start, count=1):
        if self._master is None or self._unit is None:
            raise ValueError('Connection uninitialized.')

        result = self._master.execute(self._unit, READ_INPUT_REGISTERS, register_start, count)

        if not result:
            raise IOError('Register read failed.')

        return result

    def read_power(self):
        self.power = Power(*self._from_float(self.read_input_register(63, 4)))

    def read_phases(self):
        values = self._from_float(self.read_input_register(1, 30))

        # Note: PAC reports phase powers as NaN, if all phases aren't connected.
        #       However, the total power read with PAC.read_power() is seems valid even then.
        self.L1 = Phase(values[0], values[6], values[9], values[12])
        self.L2 = Phase(values[1], values[7], values[10], values[13])
        self.L3 = Phase(values[2], values[8], values[11], values[14])

    def read_frequency(self):
        self.frequency = self._from_float(self.read_input_register(55, 2))[0]

    def read_energy(self):
        values = self._from_double(self.read_input_register(801, 40))
        self.tariff_1 = Tariff(
            Energy(values[8], values[0], values[4]),
            Energy(values[8], values[2], values[6])
        )
        self.tariff_2 = Tariff(
            Energy(values[9], values[1], values[5]),
            Energy(values[9], values[3], values[7])
        )

    def read(self):
        self.read_power()
        self.read_phases()
        self.read_frequency()
        self.read_energy()

    def clear_tariff(self, tariff):
        if self._master is None or self._unit is None:
            raise ValueError('Connection uninitialized.')

        if tariff == 1:
            start = 801
        if tariff == 2:
            start = 805
        registers = range(start, start + 5 * 8, 8)
        for x in registers:
            self._master.execute(self._unit, WRITE_MULTIPLE_REGISTERS, x, output_value=[0, 0, 0, 0])
        # Read energy to update values...
        self.read_energy()
        
    def close(self):
        if self._master is None or self._unit is None:
            return
        self._master.close()

    @property
    def energy(self):
        return self.tariff_1 + self.tariff_2

    @property
    def energy_balance(self):
        return self.tariff_1.energy_import + self.tariff_2.energy_import - self.tariff_1.energy_export - self.tariff_2.energy_export

    def as_dict(self, replace_nan=False):
        return {
            'power': self.power.as_dict(replace_nan=replace_nan),
            'phases': {
                'L1': self.L1.as_dict(replace_nan=replace_nan),
                'L2': self.L2.as_dict(replace_nan=replace_nan),
                'L3': self.L3.as_dict(replace_nan=replace_nan),
            },
            'energy': self.energy.as_dict(replace_nan=replace_nan),
            'balance': self.energy_balance.as_dict(replace_nan=replace_nan),
            'tariffs': [
                self.tariff_1.as_dict(replace_nan=replace_nan),
                self.tariff_2.as_dict(replace_nan=replace_nan),
            ],
            'frequency': zero_if_nan(self.frequency, replace_nan),
        }
Ejemplo n.º 6
0
 def read_power(self):
     self.power = Power(*self._from_float(self.read_input_register(63, 4)))