Ejemplo n.º 1
0
 def dev_write(self, *args):
     try:
         self.dev_sleep()
         return TCPModbusClient.dev_write(self.serverloc[0],
                                          self.serverloc[1],
                                          self.modbus_addr, *args)
     except:
         return None
Ejemplo n.º 2
0
Archivo: dent.py Proyecto: ahaas/smap
    def read_scale(self, modbus_addr):
        """Read the scale register on a dent"""
        self.modbus_addr = modbus_addr
        response = self.dev_read(self.scale_register, 3)
        data = [(TCPModbusClient.get_val(response.modbus_reg_val, i) & 0xffff)
                for i in range(0, response.modbus_val_bytes / 2)]

        if len(data) != 3:
            return None

        # return the scaling indicator expressed by the dent
        return data[1]
Ejemplo n.º 3
0
    def read_scale(self, modbus_addr):
        """Read the scale register on a dent"""
        self.modbus_addr = modbus_addr
        response = self.dev_read(self.scale_register, 3)
        data = [(TCPModbusClient.get_val(response.modbus_reg_val, i) & 0xffff)
                for i in range(0, response.modbus_val_bytes / 2)]

        if len(data) != 3:
            return None

        # return the scaling indicator expressed by the dent
        return data[1]
Ejemplo n.º 4
0
class VerisMeter:
    all_meters = range(1, 43)
    register_map = {
        'current_scale': (1000, 1041),
        'power_scale': (1042, 1083),
        'energy_scale': (1084, 1125),
        'kwh': (1168, 1251),
        'kwh_fl': (2000, 2083),
        'kw': (1252, 1293),
        'pf': (1294, 1335),
        'current': (1336, 1377),
        'pkw': (1378, 1419),
        'maxkw': (1420, 1461),
        'pcurrent': (1462, 1503),
        'maxcurrent': (1504, 1545),
        'reset': (1126, 1167),
    }

    val_clear_kw = 10203
    val_clear_max = 29877

    def __init__(self, server, port, bus_addr):
        self.server = server
        self.port = port
        self.bus_addr = bus_addr
        self.logger = logging.getLogger('VerisMeter')
        self.last_reading_time = 0.0
        self.last_reset_energy = None
        self.last_reset_time = 0.0
        self.boot_time = time.time()

    def get_current(self):
        values = self.read_reg_range(self.register_map['current'])
        scales = self.read_reg_range(self.register_map['current_scale'])
        return self.scale_vals(values, scales)

    def get_power(self):
        values = self.read_reg_range(self.register_map['kw'])
        scales = self.read_reg_range(self.register_map['power_scale'])
        return self.scale_vals(values, scales)

    def get_powerfactor(self):
        values = self.read_reg_range(self.register_map['pf'])
        scales = [-3] * len(values)
        return self.scale_vals(values, scales)

    def get_energy_totals(self):
        values_16bit = self.read_reg_range(self.register_map['kwh'])
        scale = self.read_reg_range(self.register_map['energy_scale'])

        values = []
        for i in range(0, len(values_16bit) / 2):
            values.append(((values_16bit[i * 2] & 0xffff) << 16)
                          | (values_16bit[i * 2 + 1] & 0xffff))
        return self.scale_vals(values, scale)

    def get_energy(self, current=None):
        if not current:
            current = self.get_energy_totals()
        if not self.last_reset_energy:
            return current

        return map(lambda x, y: x - y, current, self.last_reset_energy)

    def reset_energy(self, vals=None):
        # reset doesn't seem to work reliably -- just remember what it was last time
        if not vals:
            newvals = self.get_energy_totals()
        else:
            newvals = vals
        self.last_reset_time = time.time()
        self.last_reset_energy = newvals

    def scale_vals(self, vals, scale):
        return map(lambda x, y: x * (10**y), vals, scale)

    def read_reg_range(self, (start, end)):
        start -= 1
        end -= 1
        if end < start:
            self.logger.error("read_reg_range: invalid range: (%i, %i)" %
                              (start, end))
            return None
        self.logger.debug("read_reg_range: %i:%i" % (start, end))

        now = time.time()
        if now - self.last_reading_time < 2:
            time.sleep(2 - (now - self.last_reading_time))

        response = TCPModbusClient.dev_read(self.server, self.port,
                                            self.bus_addr, start,
                                            end - start + 1)

        self.last_reading_time = time.time()
        self.logger.debug("read_reg_range: %i response bytes",
                          response.modbus_val_bytes)

        return [
            TCPModbusClient.get_val(response.modbus_reg_val, i)
            for i in range(0, response.modbus_val_bytes / 2)
        ]
Ejemplo n.º 5
0
Archivo: dent.py Proyecto: ahaas/smap
    def update(self, elt, scale, modbus_addr):
        self.modbus_addr = modbus_addr
        response = self.dev_read(4000, 70)
        time.sleep(2)
        data = [(TCPModbusClient.get_val(response.modbus_reg_val, i) & 0xffff)
                for i in range(0, response.modbus_val_bytes / 2)]
        if len(data) != 70:
            print "Short read from", self.serverloc,  modbus_addr
            return

        reading_time = int(time.time())
        base = '/%s' % elt
        self.add(base + '/ABC/true_energy', reading_time,
                 float(self.to_word(data[0:2])) / e_d(scale))
        self.add(base + '/ABC/reactive_energy', reading_time,
                 float(self.to_word(data[7:9])) / e_d(scale))
        self.add(base + '/ABC/apparent_energy', reading_time,
                 float(self.to_word(data[10:12])) / e_d(scale))
        self.add(base + '/ABC/true_power', reading_time,
                 float(data[2]) / e_d(scale))
        # min=data[6], max=data[5]))
        self.add(base + '/ABC/reactive_power', reading_time,
                 float(data[9]) / e_d(scale))
        self.add(base + '/ABC/apparent_power', reading_time,
                 float(data[12]) / e_d(scale))
        self.add(base + '/ABC/displacement_pf', reading_time,
                 float(data[13]) / 100)
        self.add(base + '/ABC/apparent_pf', reading_time,
                 float(data[14]) / 100)
        self.add(base + '/ABC/current', reading_time,
                 float(data[15]) / c_d(scale))
        # line frequency divisor is not in the datasheet, but called Dent to verify 3-26-2010
        self.add(base + '/ABC/line_frequency', reading_time,
                 float(data[21]) / 100)
        self.add(base + '/AB/volts', reading_time,
                 float(data[18]) / v_d(scale))
        self.add(base + '/BC/volts',  reading_time,
                 float(data[19]) / v_d(scale))
        self.add(base + '/AC/volts', reading_time,
                 float(data[20]) / v_d(scale))

        def w_i(d, i):
            return d[i] | (d[i+1] << 16)

        for (i,v) in [(0,'A'), (1,'B'), (2,'C')]:
            base = '/%s/%s/' % (elt, v)
            self.add(base + 'true_energy', reading_time,
                     float(w_i(data, 22+(i*2))) / e_d(scale))
            self.add(base + 'reactive_energy', reading_time, 
                     float(w_i(data, 31+(i*2))) / e_d(scale))
            self.add(base + 'apparent_energy', reading_time, 
                     float(w_i(data, 40+(i*2))) / e_d(scale))
            self.add(base + 'true_power', reading_time, 
                     float(data[28+i]) / e_d(scale))
            self.add(base + 'reactive_power', reading_time, 
                     float(data[37+i]) / e_d(scale))
            self.add(base + 'apparent_power', reading_time, 
                     float(data[46+i]) / e_d(scale))
            self.add(base + 'displacement_pf', reading_time, 
                     float(data[49+i]) / 100)
            self.add(base + 'apparent_pf', reading_time, 
                     float(data[52+i]) / 100)
            self.add(base + 'current', reading_time, 
                     float(data[55+i]) / c_d(scale))
            self.add(base + 'phase-neutral_voltage', reading_time, 
                     float(data[58+i]) / v_d(scale))
Ejemplo n.º 6
0
Archivo: dent.py Proyecto: ahaas/smap
 def dev_write(self, *args):
     try:
         self.dev_sleep()
         return TCPModbusClient.dev_write(self.serverloc[0], self.serverloc[1],self.modbus_addr,*args)
     except:
         return None
Ejemplo n.º 7
0
    def update(self, elt, scale, modbus_addr):
        self.modbus_addr = modbus_addr
        response = self.dev_read(4000, 70)
        time.sleep(2)
        data = [(TCPModbusClient.get_val(response.modbus_reg_val, i) & 0xffff)
                for i in range(0, response.modbus_val_bytes / 2)]
        if len(data) != 70:
            print "Short read from", self.serverloc, modbus_addr
            return

        reading_time = int(time.time())
        base = '/%s' % elt
        self.add(base + '/ABC/true_energy', reading_time,
                 float(self.to_word(data[0:2])) / e_d(scale))
        self.add(base + '/ABC/reactive_energy', reading_time,
                 float(self.to_word(data[7:9])) / e_d(scale))
        self.add(base + '/ABC/apparent_energy', reading_time,
                 float(self.to_word(data[10:12])) / e_d(scale))
        self.add(base + '/ABC/true_power', reading_time,
                 float(data[2]) / e_d(scale))
        # min=data[6], max=data[5]))
        self.add(base + '/ABC/reactive_power', reading_time,
                 float(data[9]) / e_d(scale))
        self.add(base + '/ABC/apparent_power', reading_time,
                 float(data[12]) / e_d(scale))
        self.add(base + '/ABC/displacement_pf', reading_time,
                 float(data[13]) / 100)
        self.add(base + '/ABC/apparent_pf', reading_time,
                 float(data[14]) / 100)
        self.add(base + '/ABC/current', reading_time,
                 float(data[15]) / c_d(scale))
        # line frequency divisor is not in the datasheet, but called Dent to verify 3-26-2010
        self.add(base + '/ABC/line_frequency', reading_time,
                 float(data[21]) / 100)
        self.add(base + '/AB/volts', reading_time,
                 float(data[18]) / v_d(scale))
        self.add(base + '/BC/volts', reading_time,
                 float(data[19]) / v_d(scale))
        self.add(base + '/AC/volts', reading_time,
                 float(data[20]) / v_d(scale))

        def w_i(d, i):
            return d[i] | (d[i + 1] << 16)

        for (i, v) in [(0, 'A'), (1, 'B'), (2, 'C')]:
            base = '/%s/%s/' % (elt, v)
            self.add(base + 'true_energy', reading_time,
                     float(w_i(data, 22 + (i * 2))) / e_d(scale))
            self.add(base + 'reactive_energy', reading_time,
                     float(w_i(data, 31 + (i * 2))) / e_d(scale))
            self.add(base + 'apparent_energy', reading_time,
                     float(w_i(data, 40 + (i * 2))) / e_d(scale))
            self.add(base + 'true_power', reading_time,
                     float(data[28 + i]) / e_d(scale))
            self.add(base + 'reactive_power', reading_time,
                     float(data[37 + i]) / e_d(scale))
            self.add(base + 'apparent_power', reading_time,
                     float(data[46 + i]) / e_d(scale))
            self.add(base + 'displacement_pf', reading_time,
                     float(data[49 + i]) / 100)
            self.add(base + 'apparent_pf', reading_time,
                     float(data[52 + i]) / 100)
            self.add(base + 'current', reading_time,
                     float(data[55 + i]) / c_d(scale))
            self.add(base + 'phase-neutral_voltage', reading_time,
                     float(data[58 + i]) / v_d(scale))