Ejemplo n.º 1
0
class ReadMeterCommand(Command):
    '''Read a single P1 packet

    Read a single packet from the smart meter.
    Packets can either be printed to stdout or stored
    in a sqlite database.
    '''

    args = [
        arg('--serial-port',
            default=DEFAULT_SERIAL,
            metavar=DEFAULT_SERIAL,
            help='serial port to read packets from (defaults to %s)' %
            DEFAULT_SERIAL),
        arg('--baudrate',
            default=115200,
            help='baudrate for the serial connection'),
        arg('--tsv',
            action='store_true',
            help='display packet in tab seperated value form'),
        arg('--raw', action='store_true', help='display packet in raw form'),
    ]

    def run(self, args, parser):
        meter = SmartMeter(args.serial_port, baudrate=args.baudrate)

        try:
            packet = meter.read_one_packet()
        except SerialException as e:
            parser.error(e)
        finally:
            meter.disconnect()

        if args.raw:
            print(str(packet))
            return 0

        data = [('Time', datetime.now()),
                ('Total kWh High consumed',
                 int(packet['kwh']['high']['consumed'] * 1000)),
                ('Total kWh Low consumed',
                 int(packet['kwh']['low']['consumed'] * 1000)),
                ('Total gas consumed', int(packet['gas']['total'] * 1000)),
                ('Current kWh tariff', packet['kwh']['tariff'])]

        if args.tsv:
            print('\t'.join(map(str, [d for k, d in data])))
        else:
            print('\n'.join(['%-25s %s' % (k, d) for k, d in data]))
Ejemplo n.º 2
0
class ViewCertCommand(Command):
    '''view the subject of a generated certificate'''

    args = [arg('cert_file', help='the certificate file')]

    def run(self, args, store, parser):
        print store.view_info(args.cert_file)
Ejemplo n.º 3
0
class DomainCommand(Command):
    '''create a server certificate for a FQDN'''

    args = [arg('domain', help='domain name to generate the certificate for')]

    def run(self, args, store, parser):
        try:
            store.add_domain(args.domain)
        except SslStoreNotInitializedError:
            parser.error(
                'No store in %s. Maybe you should bootstrap it first?' %
                args.base_dir)
Ejemplo n.º 4
0
class InitCommand(Command):
    '''bootstrap a new CA SslStore in the given directory.'''

    args = [
        arg('--force', action='store_true', help=\
            'if the current directory already exists and is not '
            'empty: do not ask for confirmation and overwrite '
            'its contents.')
    ]

    def run(self, args, store, parser):
        try:
            store.initialize(force=args.force)
        except SslStoreExistsError as e:
            parser.error('%s\nUse --force to overwrite' % e)
        else:
            parser.exit(message='Store initialized\n')
Ejemplo n.º 5
0
class GenerateCaCommand(Command):
    '''create the root certificate authority'''

    args = [
        arg('--days',
            default="3650",
            help='the amount of days the ca certificate is valid')
    ]

    def run(self, args, store, parser):
        try:
            store.generate_root_ca_key(args.days)
        except AuthorityExistsError as e:
            parser.error(e)
        except AuthorityCertificateError as e:
            parser.error(e)
        except AuthorityKeyError as e:
            parser.error(e)
        else:
            parser.exit(message='CA key generated in %s\n' % store.ca_key)
Ejemplo n.º 6
0
class ReadMeterCommand(Command):
    '''read a single P1 packet to stdout

    Read a single packet from the smart meter.
    Packets will be printed to stdout.

    All the options starting with --serial-* are passed directly to the
    underlying serial object. For more information on the possible values and
    their behavior please refer to the documentation here
    http://pyserial.readthedocs.io/en/latest/pyserial_api.html
    '''

    show_output_choices = [
        'time', 'kwh_eid', 'gas_eid', 'consumed', 'tariff', 'gas_measured_at',
        'produced', 'current'
    ]

    args = [
        # options controlling input
        arg('--serial-port',
            help='device name to read packets from (defaults to %s)' %
            __default_serial__,
            metavar=__default_serial__,
            default=__default_serial__),
        arg('--baudrate',
            help=
            'baud rate such as 9600 or 115200 etc. This option is deprecated in favor of --serial-baudrate and will be removed in future versions.',
            type=int,
            dest='serial_baudrate',
            default=9600,
            metavar=9600),
        arg('--serial-baudrate',
            help='baud rate such as 9600 or 115200 etc (defaults to 9600).',
            type=int,
            default=9600,
            metavar=9600),
        arg('--serial-xonxoff',
            help=
            'enable software flow control. By default software flow control is disabled.',
            action='store_true'),
        arg('--serial-bytesize',
            help='number of data bits (defaults to 7).',
            default=serial.SEVENBITS,
            type=int,
            choices=[5, 6, 7, 8]),
        arg('--serial-parity',
            help='enable parity checking (defaults to E)',
            default=serial.PARITY_EVEN,
            choices=['N', 'E', 'O', 'M', 'S']),
        arg('--serial-stopbits',
            help='number of stop bits (defaults to 1).',
            default=serial.STOPBITS_ONE,
            type=float,
            choices=[1, 1.5, 2]),
        arg('--serial-timeout',
            help='set a read timeout value in seconds (defaults to 10).',
            default=10,
            type=int,
            metavar=10),

        # options controlling output
        arg('--elec-unit',
            help='electricity unit to use (defaults to Wh).',
            default='Wh',
            type=str,
            choices=['Wh', 'kWh', 'J', 'MJ']),
        arg('--gas-unit',
            help=
            'gas unit to use (defaults to m^3). Caloric units (J, MJ) based on Dutch gas @ 43.94 MJ/m^3.',
            default='m3',
            type=str,
            choices=['m3', 'l', 'J', 'MJ']),
        arg('--show-output',
            help='choose output to display. (one of: ' +
            ", ".join(show_output_choices) + ')',
            default=('time', 'consumed', 'tariff', 'gas_measured_at'),
            type=str,
            nargs='+',
            metavar='param',
            choices=show_output_choices),
        arg('--tsv',
            help='display packet in tab separated value form',
            action='store_true'),
        arg('--raw', help='display packet in raw form', action='store_true'),
    ]

    def run(self, args, parser):
        meter = SmartMeter(
            args.serial_port,
            baudrate=args.serial_baudrate,
            bytesize=args.serial_bytesize,
            parity=args.serial_parity,
            stopbits=args.serial_stopbits,
            xonxoff=args.serial_xonxoff,
            timeout=args.serial_timeout,
        )

        try:
            packet = meter.read_one_packet()
        except SerialException as e:
            parser.error(e)
        finally:
            meter.disconnect()

        if args.raw:
            print(str(packet))
            return 0

        # Set multiplication factor based on requested unit
        elec_unit_factor = {
            'Wh': 1000,
            'kWh': 1,
            'J': 1000 * 3600,
            'MJ': 1000 * 3600 / 1000 / 1000
        }
        gas_unit_factor = {
            'm3': 1000,
            'l': 1,
            'J': 43.935,
            'MJ': 1000 *
            43.935  # 43.46 - 44.41 MJ/m^3(n) legal Wobbe-index ('Bovenwaarde') for Dutch Groningen gas, also widely used in north-west Europe: https://wetten.overheid.nl/BWBR0035367/2019-01-01#Bijlage2
        }

        # Construct output depending on user request
        data = []
        if ('time' in args.show_output):
            data.append(('Time', datetime.now()))
        if ('kwh_eid' in args.show_output):
            data.append(('Electricity serial', packet['kwh']['eid']))
        if ('gas_eid' in args.show_output):
            data.append(('Gas serial', packet['gas']['eid']))
        if ('consumed' in args.show_output):
            data.extend([
                ('Total electricity consumed (high, ' + args.elec_unit + ')',
                 int(packet['kwh']['high']['consumed'] *
                     elec_unit_factor[args.elec_unit])),
                ('Total electricity consumed (low, ' + args.elec_unit + ')',
                 int(packet['kwh']['low']['consumed'] *
                     elec_unit_factor[args.elec_unit])),
                ('Total gas consumed (' + args.gas_unit + ')',
                 int(packet['gas']['total'] * gas_unit_factor[args.gas_unit]))
            ])
        if ('produced' in args.show_output):
            data.extend([
                ('Total electricity produced (high, ' + args.elec_unit + ')',
                 int(packet['kwh']['high']['produced'] *
                     elec_unit_factor[args.elec_unit])),
                ('Total electricity produced (low, ' + args.elec_unit + ')',
                 int(packet['kwh']['low']['produced'] *
                     elec_unit_factor[args.elec_unit]))
            ])
        if ('current' in args.show_output):
            data.extend([('Current electricity consumption (W)',
                          int(packet['kwh']['current_consumed'] * 1000)),
                         ('Current electricity production (W)',
                          int(packet['kwh']['current_produced'] * 1000))])
        if ('tariff' in args.show_output):
            data.append(
                ('Current electricity tariff', packet['kwh']['tariff']))
        if ('gas_measured_at' in args.show_output):
            data.append(('Gas measured at', packet['gas']['measured_at']))

        if args.tsv:
            print('\t'.join(map(str, [d for k, d in data])))
        else:
            print('\n'.join(['%-40s %s' % (k, d) for k, d in data]))

        return 0
Ejemplo n.º 7
0
class ReadMeterCommand(Command):
    '''read a single P1 packet to stdout

    Read a single packet from the smart meter.
    Packets will be printed to stdout.

    All the options starting with --serial-* are passed directly to the
    underlying serial object. For more information on the possible values and
    their behavior please refer to the documentation here
    http://pyserial.readthedocs.io/en/latest/pyserial_api.html
    '''

    args = [
        # options controlling input
        arg('--serial-port',
            help='device name to read packets from (defaults to %s)' %
            __default_serial__,
            metavar=__default_serial__,
            default=__default_serial__),
        arg('--baudrate',
            help=
            'baud rate such as 9600 or 115200 etc. This option is deprecated in favor of --serial-baudrate and will be removed in future versions.',
            type=int,
            dest='serial_baudrate',
            default=9600,
            metavar=9600),
        arg('--serial-baudrate',
            help='baud rate such as 9600 or 115200 etc (defaults to 9600).',
            type=int,
            default=9600,
            metavar=9600),
        arg('--serial-xonxoff',
            help=
            'enable software flow control. By default software flow control is disabled.',
            action='store_true'),
        arg('--serial-bytesize',
            help='number of data bits (defaults to 7).',
            default=serial.SEVENBITS,
            type=int,
            choices=[5, 6, 7, 8]),
        arg('--serial-parity',
            help='enable parity checking (defaults to E)',
            default=serial.PARITY_EVEN,
            choices=['N', 'E', 'O', 'M', 'S']),
        arg('--serial-stopbits',
            help='number of stop bits (defaults to 1).',
            default=serial.STOPBITS_ONE,
            type=float,
            choices=[1, 1.5, 2]),
        arg('--serial-timeout',
            help='set a read timeout value in seconds (defaults to 10).',
            default=10,
            type=int,
            metavar=10),

        # options controlling output
        arg('--tsv',
            help='display packet in tab separated value form',
            action='store_true'),
        arg('--raw', help='display packet in raw form', action='store_true'),
    ]

    def run(self, args, parser):
        meter = SmartMeter(
            args.serial_port,
            baudrate=args.serial_baudrate,
            bytesize=args.serial_bytesize,
            parity=args.serial_parity,
            stopbits=args.serial_stopbits,
            xonxoff=args.serial_xonxoff,
            timeout=args.serial_timeout,
        )

        try:
            packet = meter.read_one_packet()
        except SerialException as e:
            parser.error(e)
        finally:
            meter.disconnect()

        if args.raw:
            print(str(packet))
            return 0

        data = [('Time', datetime.now()),
                ('Total kWh High consumed',
                 int(packet['kwh']['high']['consumed'] * 1000)),
                ('Total kWh Low consumed',
                 int(packet['kwh']['low']['consumed'] * 1000)),
                ('Total gas consumed', int(packet['gas']['total'] * 1000)),
                ('Current kWh tariff', packet['kwh']['tariff'])]

        if args.tsv:
            print('\t'.join(map(str, [d for k, d in data])))
        else:
            print('\n'.join(['%-25s %s' % (k, d) for k, d in data]))

        return 0