Exemplo n.º 1
0
def send_tarif_frame(ser, tarif, address=None, req=None):
    if address is not None and meterbus.is_primary_address(address) == False:
        return False

    if req is None:
        frame = meterbus.TelegramLong()
        frame.header.cField.parts = [
            #      meterbus.CONTROL_MASK_REQ_UD2 | meterbus.CONTROL_MASK_DIR_M2S | meterbus.CONTROL_MASK_FCV | meterbus.CONTROL_MASK_FCB
            meterbus.CONTROL_MASK_SND_UD | meterbus.CONTROL_MASK_DIR_M2S
            #	0x73
        ]
        frame.header.aField.parts = [address]
    else:
        frame = req
    frame.body.bodyHeaderLength = 2
    frame.body.bodyHeader = [0x51]
    #  frame.body.bodyHeader = [0xBD]
    #  frame.body.bodyPayload = [0x0D, 0xFD, 0x0B, 0xED, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ]
    #  frame.body.bodyPayload = [0x0D, 0xFD, 0x0B, 0xED, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x80, 0xFF, 0x01 ]
    frame.body.bodyPayload = [0x01, 0xFF, 0x54, tarif]
    #  frame.body.bodyPayload = [0x7F]
    frame.header.crcField = frame.compute_crc()

    #  print(''.join(format(x, '02x') for x in bytearray(frame)))
    meterbus.serial_send(ser, frame)

    return frame
Exemplo n.º 2
0
    def do_char_dev(self, **kwargs):
        address = self.address
        device = self.device
        baudrate = self.baudrate

        try:
            address = int(address)
            if not (0 <= address <= 254):
                address = address
        except ValueError:
            address = address.upper()

        try:
            ibt = meterbus.inter_byte_timeout(baudrate)
            with serial.serial_for_url(device,
                                       baudrate,
                                       8,
                                       'E',
                                       1,
                                       inter_byte_timeout=ibt,
                                       timeout=1) as ser:
                frame = None

                if meterbus.is_primary_address(address):
                    self.ping_address(ser, meterbus.ADDRESS_NETWORK_LAYER, 0)

                    meterbus.send_request_frame(ser, address)
                    frame = meterbus.load(
                        meterbus.recv_frame(ser, meterbus.FRAME_DATA_LENGTH))

                elif meterbus.is_secondary_address(address):
                    meterbus.send_select_frame(ser, address)
                    try:
                        frame = meterbus.load(meterbus.recv_frame(ser, 1))
                    except meterbus.MBusFrameDecodeError as e:
                        frame = e.value

                    assert isinstance(frame, meterbus.TelegramACK)

                    frame = None
                    # ping_address(ser, meterbus.ADDRESS_NETWORK_LAYER, 0)

                    meterbus.send_request_frame(ser,
                                                meterbus.ADDRESS_NETWORK_LAYER)

                    time.sleep(0.3)

                    frame = meterbus.load(
                        meterbus.recv_frame(ser, meterbus.FRAME_DATA_LENGTH))

                if frame is not None:
                    #print(frame.to_JSON())
                    return frame.to_JSON()

        except serial.serialutil.SerialException as e:
            print(e)
Exemplo n.º 3
0
def do_char_dev(args):
    address = None

    try:
         address = int(args.address)
         if not (0 <= address <= 254):
             address = args.address
    except ValueError:
        address = args.address.upper()

    try:
        ibt = meterbus.inter_byte_timeout(args.baudrate)
        with serial.serial_for_url(args.device,
                                   args.baudrate, 8, 'E', 1,
                                   inter_byte_timeout=ibt,
                                   timeout=1) as ser:
            frame = None

            if meterbus.is_primary_address(address):
                if ping_address(ser, address, args.retries, args.echofix):
                    meterbus.send_request_frame(ser, address, read_echo=args.echofix)
                    frame = meterbus.load(
                        meterbus.recv_frame(ser, meterbus.FRAME_DATA_LENGTH))

            elif meterbus.is_secondary_address(address):
                if ping_address(ser, meterbus.ADDRESS_NETWORK_LAYER, args.retries, args.echofix):
                    meterbus.send_select_frame(ser, address, args.echofix)
                    try:
                        frame = meterbus.load(meterbus.recv_frame(ser, 1))
                    except meterbus.MBusFrameDecodeError as e:
                        frame = e.value

                    # Ensure that the select frame request was handled by the slave
                    assert isinstance(frame, meterbus.TelegramACK)

                    frame = None

                    meterbus.send_request_frame(
                        ser, meterbus.ADDRESS_NETWORK_LAYER, read_echo=args.echofix)

                    time.sleep(0.3)

                    frame = meterbus.load(
                        meterbus.recv_frame(ser, meterbus.FRAME_DATA_LENGTH))

            if frame is not None:
                return frame

    except serial.serialutil.SerialException as e:
        print(e)

    return None
def do_char_dev(args):
    address = None

    try:
        address = int(args.address)
        if not (0 <= address <= 254):
            address = args.address
    except ValueError:
        address = args.address.upper()

    try:
        ibt = meterbus.inter_byte_timeout(args.baudrate)
        with serial.serial_for_url(args.device,
                           args.baudrate, 8, 'E', 1,
                           inter_byte_timeout=ibt,
                           timeout=1) as ser:
            frame = None

            if meterbus.is_primary_address(address):
                ping_address(ser, meterbus.ADDRESS_NETWORK_LAYER, 0)

                meterbus.send_request_frame(ser, address)
                frame = meterbus.load(
                    meterbus.recv_frame(ser, meterbus.FRAME_DATA_LENGTH))

            elif meterbus.is_secondary_address(address):
                meterbus.send_select_frame(ser, address)
                try:
                    frame = meterbus.load(meterbus.recv_frame(ser, 1))
                except meterbus.MBusFrameDecodeError as e:
                    frame = e.value

                assert isinstance(frame, meterbus.TelegramACK)

                frame = None
                # ping_address(ser, meterbus.ADDRESS_NETWORK_LAYER, 0)

                meterbus.send_request_frame(
                    ser, meterbus.ADDRESS_NETWORK_LAYER)

                time.sleep(0.3)

                frame = meterbus.load(
                    meterbus.recv_frame(ser, meterbus.FRAME_DATA_LENGTH))

            if frame is not None:
                print(frame.to_JSON())

    except serial.serialutil.SerialException as e:
        print(e)
Exemplo n.º 5
0
 def test_is_primary_false_str(self):
     self.assertEqual(False, meterbus.is_primary_address("A"))
Exemplo n.º 6
0
 def test_is_primary_false(self):
     self.assertEqual(False, meterbus.is_primary_address(256))
Exemplo n.º 7
0
 def test_is_primary_true(self):
     self.assertEqual(True, meterbus.is_primary_address(1))
    address = args.address
    try:
        if 0 <= int(args.address) <= 254:
            address = int(args.address)
    except ValueError:
        pass

    try:
        ibt = meterbus.inter_byte_timeout(args.baudrate)
        with serial.serial_for_url(args.device,
                           args.baudrate, 8, 'E', 1,
                           inter_byte_timeout=ibt,
                           timeout=1) as ser:
            frame = None

            if meterbus.is_primary_address(address):
                if False == ping_address(ser, address, 0):
                     sys.exit(1)

                meterbus.send_request_frame_multi(ser, address)
                frame = meterbus.load(
                    meterbus.recv_frame(ser))

            elif meterbus.is_secondary_address(address):
                if False == ping_address(ser, meterbus.ADDRESS_NETWORK_LAYER, 0):
                    ping_address(ser, meterbus.ADDRESS_BROADCAST_NOREPLY, 0)

                meterbus.send_select_frame(ser, address)
                frame = meterbus.load(meterbus.recv_frame(ser, 1))
                assert isinstance(frame, meterbus.TelegramACK)
            address = int(args.address)
    except ValueError:
        pass

    try:
        ibt = meterbus.inter_byte_timeout(args.baudrate)
        with serial.serial_for_url(args.device,
                                   args.baudrate,
                                   8,
                                   'E',
                                   1,
                                   inter_byte_timeout=ibt,
                                   timeout=1) as ser:
            frame = None

            if meterbus.is_primary_address(address):
                if False == ping_address(ser, address, args.retries,
                                         args.echofix):
                    sys.exit(1)

                meterbus.send_request_frame_multi(ser,
                                                  address,
                                                  read_echo=args.echofix)
                frame = meterbus.load(meterbus.recv_frame(ser))

            elif meterbus.is_secondary_address(address):
                if False == ping_address(ser, meterbus.ADDRESS_NETWORK_LAYER,
                                         args.retries, args.echofix):
                    ping_address(ser, meterbus.ADDRESS_BROADCAST_NOREPLY,
                                 args.retries, args.echofix)
Exemplo n.º 10
0
def serial_request_multi():
    parser = argparse.ArgumentParser(
        description='Request data over serial M-Bus for devices.')
    parser.add_argument('-d', action='store_true',
                        help='Enable verbose debug')
    parser.add_argument('-b', '--baudrate',
                        type=int, default=2400,
                        help='Serial bus baudrate')
    parser.add_argument('-a', '--address',
                        type=str, default=meterbus.ADDRESS_BROADCAST_REPLY,
                        help='Primary or secondary address')
    parser.add_argument('-r', '--retries',
                        type=int, default=5,
                        help='Number of ping retries for each address')
    parser.add_argument('-o', '--output', default="json",
                        help='Output format')
    parser.add_argument('--echofix', action='store_true',
                        help='Read and ignore echoed data from target')
    parser.add_argument('device', type=str, help='Serial device or URI')
    args = parser.parse_args()

    meterbus.debug(args.d)

    address = args.address
    try:
        if 0 <= int(args.address) <= 254:
            address = int(args.address)
    except ValueError:
        pass

    try:
        ibt = meterbus.inter_byte_timeout(args.baudrate)
        with serial.serial_for_url(args.device,
                                   args.baudrate, 8, 'E', 1,
                                   inter_byte_timeout=ibt,
                                   timeout=1) as ser:
            frame = None

            if meterbus.is_primary_address(address):
                if False is ping_address(ser, address, args.retries):
                    sys.exit(1)

                meterbus.send_request_frame_multi(ser, address, read_echo=args.echofix)
                frame = meterbus.load(
                    meterbus.recv_frame(ser))

            elif meterbus.is_secondary_address(address):
                if False is ping_address(ser,
                                         meterbus.ADDRESS_NETWORK_LAYER, args.retries, args.echofix):
                    ping_address(ser, meterbus.ADDRESS_BROADCAST_NOREPLY, args.retries, args.echofix)

                meterbus.send_select_frame(ser, address, read_echo=args.echofix)
                frame = meterbus.load(meterbus.recv_frame(ser, 1))

                # Ensure that the select frame request was handled by the slave
                assert isinstance(frame, meterbus.TelegramACK)

                req = meterbus.send_request_frame_multi(
                          ser, meterbus.ADDRESS_NETWORK_LAYER, read_echo=args.echofix)

                try:
                    frame = meterbus.load(meterbus.recv_frame(ser))
                except meterbus.MBusFrameDecodeError:
                    frame = None

                while frame and frame.more_records_follow:
                    # toogle FCB on and off
                    req.header.cField.parts[0] ^= meterbus.CONTROL_MASK_FCB

                    req = meterbus.send_request_frame_multi(
                              ser, meterbus.ADDRESS_NETWORK_LAYER, req, read_echo=args.echofix)

                    next_frame = meterbus.load(meterbus.recv_frame(ser))
                    frame += next_frame

            if frame is not None:
                print(serialize_frame(frame, args.output))

    except serial.serialutil.SerialException as e:
        print(e)
def do_char_dev(args):
    address = None

    try:
        address = int(args.address)
        if not (0 <= address <= 254):
            address = args.address
    except ValueError:
        address = args.address.upper()

    try:
        ibt = meterbus.inter_byte_timeout(args.baudrate)
        with serial.serial_for_url(args.device,
                                   args.baudrate,
                                   8,
                                   'E',
                                   1,
                                   inter_byte_timeout=ibt,
                                   timeout=1) as ser:
            frame = None
            result = None
            if meterbus.is_primary_address(address):
                if ping_address(ser, address, args.retries, args.echofix):
                    meterbus.send_request_frame(ser,
                                                address,
                                                read_echo=args.echofix)
                    frame = meterbus.load(
                        meterbus.recv_frame(ser, meterbus.FRAME_DATA_LENGTH))
                else:
                    print("no reply")

            elif meterbus.is_secondary_address(address):
                if ping_address(ser, meterbus.ADDRESS_NETWORK_LAYER,
                                args.retries, args.echofix):
                    meterbus.send_select_frame(ser, address, args.echofix)
                    try:
                        frame = meterbus.load(meterbus.recv_frame(ser, 1))
                    except meterbus.MBusFrameDecodeError as e:
                        frame = e.value

                    # Ensure that the select frame request was handled by the slave
                    assert isinstance(frame, meterbus.TelegramACK)

                    frame = None

                    meterbus.send_request_frame(ser,
                                                meterbus.ADDRESS_NETWORK_LAYER,
                                                read_echo=args.echofix)

                    time.sleep(0.3)

                    frame = meterbus.load(
                        meterbus.recv_frame(ser, meterbus.FRAME_DATA_LENGTH))
                else:
                    print("no reply")

            if frame is not None and args.output != 'dump':
                recs = []
                for rec in frame.records:
                    recs.append({'value': rec.value, 'unit': rec.unit})

                ydata = {
                    'manufacturer':
                    frame.body.bodyHeader.manufacturer_field.
                    decodeManufacturer,
                    'identification':
                    ''.join(map('{:02x}'.format, frame.body.bodyHeader.id_nr)),
                    'access_no':
                    frame.body.bodyHeader.acc_nr_field.parts[0],
                    'medium':
                    frame.body.bodyHeader.measure_medium_field.parts[0],
                    'records':
                    recs
                }

                if args.output == 'json':
                    result = json.dumps(ydata, indent=4, sort_keys=True)
                    print(json.dumps(ydata, indent=4, sort_keys=True))

                elif args.output == 'yaml':

                    def float_representer(dumper, value):
                        if int(value) == value:
                            text = '{0:.4f}'.format(value).rstrip('0').rstrip(
                                '.')
                            return dumper.represent_scalar(
                                u'tag:yaml.org,2002:int', text)
                        else:
                            text = '{0:.4f}'.format(value).rstrip('0').rstrip(
                                '.')
                        return dumper.represent_scalar(
                            u'tag:yaml.org,2002:float', text)

                    # Handle float and Decimal representation
                    yaml.add_representer(float, float_representer)
                    yaml.add_representer(Decimal, float_representer)

                    result = yaml.dump(ydata,
                                       default_flow_style=False,
                                       allow_unicode=True,
                                       encoding=None)
                    print(
                        yaml.dump(ydata,
                                  default_flow_style=False,
                                  allow_unicode=True,
                                  encoding=None))

            elif frame is not None:
                result = frame.to_JSON()
                print(frame.to_JSON())
            return result

    except serial.serialutil.SerialException as e:
        print(e)
def do_char_dev(args):
    address = None

    try:
        address = int(args.address)
        if not (0 <= address <= 254):
            address = args.address
    except ValueError:
        address = args.address.upper()

    try:
        #vib_to_show = ['14:0','59:1','59:0','89:0', '93:0', '255.34:0']
        #vib_to_show = ['14:0','59:0','89:0', '93:0']
        filter = {
            ((14, ), 0, 0): "one",
            #((14,), 0, 1): "one_b",
            ((59, ), 0, 0): "FLOW",
            ((62, ), 0, 0): "FLOW",
            ((89, ), 0, 0): "FLOW_TEMPERATURE",
            ((91, ), 0, 0): "FLOW_TEMPERATURE",
            ((93, ), 0, 0): "RETURN_TEMPERATURE",
            ((95, ), 0, 0): "RETURN_TEMPERATURE",
            ((255, 34), 0, 0): "five",
            ((90, ), 0, 0): "FLOW_TEMPERATURE",
            ((94, ), 0, 0): "RETURN_TEMPERATURE",
        }

        ibt = meterbus.inter_byte_timeout(args.baudrate)

        parity = 'E'
        if args.monitor: parity = 'N'

        with serial.serial_for_url(args.device,
                                   args.baudrate,
                                   8,
                                   parity,
                                   1,
                                   inter_byte_timeout=ibt,
                                   timeout=1) as ser:

            if meterbus.is_primary_address(address):
                if not args.monitor:
                    ping_address(ser, address, 0)
                    #ping_address(ser, meterbus.ADDRESS_NETWORK_LAYER, 0)

                    #setG4modern(ser, address)
                    #print("Landis+Gyr needs time")
                    #time.sleep(4)
                    #print("done")

                t_start = time.time() - 3

                try:
                    #ser.read(1)
                    while True:
                        time.sleep(0.1)

                        if not args.monitor:
                            if (time.time() - t_start) <= int(args.sleep):
                                continue
                            t_start = time.time()
                            meterbus.send_request_frame(ser, address)
                            time.sleep(0.2)

                        frame = None
                        #print(ser.inWaiting(), end = ' ')
                        if ser.inWaiting():  # >= 205:
                            #ser.read()
                            framedata = meterbus.recv_frame(
                                ser, meterbus.FRAME_DATA_LENGTH)
                            print("frame:  ", framedata)
                            if framedata:
                                frame = meterbus.load(framedata)

                        if not frame:
                            continue

                        records = frame.body.bodyPayload.records
                        filtered = {
                            "ts": '{:10.0f}'.format(time.time()),
                            "records": [],
                            "framedata": framedata.hex(),
                        }
                        for record in records:
                            vib = tuple(record.vib.parts)
                            func = record.dib.function_type.value
                            storage_number = record.dib.storage_number
                            key = (vib, func, storage_number)
                            if key in filter:
                                #name = filter.get(key,"value")
                                filtered['records'].append(record.interpreted)
                                # print(name)
                                #record = records[vib]
                                #print('{:10},{:30}:{}'.format(vib, record['type'], record['value']))
                                # value = record.value
                                # if type(value) is int:
                                #     print(' {:8} '.format(value), end='')
                                # else:
                                #     print(' {:10.8} '.format(value), end='')
                                #print()
                        import simplejson as json
                        print(
                            json.dumps(filtered,
                                       sort_keys=True,
                                       indent=4,
                                       use_decimal=True))

                except KeyboardInterrupt:
                    pass

            elif meterbus.is_secondary_address(address):
                meterbus.send_select_frame(ser, address)
                try:
                    frame = meterbus.load(meterbus.recv_frame(ser, 1))
                except meterbus.MBusFrameDecodeError as e:
                    frame = e.value

                assert isinstance(frame, meterbus.TelegramACK)

                frame = None
                # ping_address(ser, meterbus.ADDRESS_NETWORK_LAYER, 0)

                meterbus.send_request_frame(ser,
                                            meterbus.ADDRESS_NETWORK_LAYER)

                time.sleep(0.3)

                frame = meterbus.load(
                    meterbus.recv_frame(ser, meterbus.FRAME_DATA_LENGTH))

                if frame is not None:
                    print(frame.to_JSON())

    except serial.serialutil.SerialException as e:
        print(e)
Exemplo n.º 13
0
 def test_is_primary_false_str(self):
     self.assertEqual(False, meterbus.is_primary_address("A"))
Exemplo n.º 14
0
 def test_is_primary_false(self):
     self.assertEqual(False, meterbus.is_primary_address(256))
Exemplo n.º 15
0
 def test_is_primary_true(self):
     self.assertEqual(True, meterbus.is_primary_address(1))