Exemplo 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')
Exemplo n.º 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])
     )
Exemplo n.º 3
0
def test_add():
    e1 = Energy(1, 1, 1)
    e2 = Energy(1, 1, 1)
    t1 = Tariff(e1, e2)
    t2 = Tariff(e1, e2)
    t_total = t1 + t2

    assert t_total.energy_import.apparent == t1.energy_import.apparent + t2.energy_import.apparent
    assert t_total.energy_import.active == t1.energy_import.active + t2.energy_import.active
    assert t_total.energy_import.reactive == t1.energy_import.reactive + t2.energy_import.reactive
    assert t_total.energy_export.apparent == t1.energy_export.apparent + t2.energy_export.apparent
    assert t_total.energy_export.active == t1.energy_export.active + t2.energy_export.active
    assert t_total.energy_export.reactive == t1.energy_export.reactive + t2.energy_export.reactive
Exemplo n.º 4
0
def test_balance():
    e1 = Energy(1000, 1000, 1000)
    e2 = Energy(1000, 1000, 1000)
    balance = Tariff(e1, e2).balance

    assert isinstance(balance, Energy)
    assert balance.apparent == 0
    assert balance.active == 0
    assert balance.reactive == 0
Exemplo n.º 5
0
def test_div():
    e1 = Energy(1000, 1000, 1000)
    e2 = Energy(1000, 1000, 1000)
    p_import, p_export = Tariff(e1, e2) / 7200

    assert isinstance(p_import, Power)
    assert isinstance(p_export, Power)
    assert p_import.apparent == 1000 / 2
    assert p_export.apparent == 1000 / 2
    assert p_import.active == e1.active / 2
    assert p_export.active == e1.active / 2
    assert p_import.reactive == e1.reactive / 2
    assert p_export.reactive == e1.reactive / 2

    p_import, p_export = Tariff(e1, e2) / timedelta(minutes=30)

    assert isinstance(p_import, Power)
    assert isinstance(p_export, Power)
    assert p_import.apparent == 1000 * 2
    assert p_export.apparent == 1000 * 2
    assert p_import.active == e1.active * 2
    assert p_export.active == e1.active * 2
    assert p_import.reactive == e1.reactive * 2
    assert p_export.reactive == e1.reactive * 2
Exemplo n.º 6
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),
        }