예제 #1
0
    def test_multi_req_frame(self):
        self.reset()
        frame = meterbus.send_request_frame_multi(self.master, 0)

        self.assertEqual(self.slave.read(5), b"\x10\x7B\x00\x7B\x16")

        # Next frame
        frame.header.cField.parts[0] ^= meterbus.CONTROL_MASK_FCB
        frame = meterbus.send_request_frame_multi(self.master, req=frame)

        self.assertEqual(self.slave.read(5), b"\x10\x5B\x00\x5B\x16")
예제 #2
0
    def test_multi_req_frame(self):
        self.reset()
        frame = meterbus.send_request_frame_multi(self.master,
                                                  0)

        self.assertEqual(self.slave.read(5),
                         b"\x10\x7B\x00\x7B\x16")

        # Next frame
        frame.header.cField.parts[0] ^= meterbus.CONTROL_MASK_FCB
        frame = meterbus.send_request_frame_multi(self.master,
                                                  req=frame)

        self.assertEqual(self.slave.read(5),
                         b"\x10\x5B\x00\x5B\x16")
예제 #3
0
 def test_invalid_multi_req_frame_address(self):
     self.reset()
     retval = meterbus.send_request_frame_multi(self.master,
                                                600)
     self.assertEqual(retval, False)
    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)

                req = meterbus.send_request_frame_multi(
                          ser, meterbus.ADDRESS_NETWORK_LAYER)

                try:
        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)

                meterbus.send_select_frame(ser, address, args.echofix)
                frame = meterbus.load(meterbus.recv_frame(ser, 1))
                assert isinstance(frame, meterbus.TelegramACK)

                req = meterbus.send_request_frame_multi(
                    ser,
예제 #6
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)
예제 #7
0
 def test_invalid_multi_req_frame_address(self):
     self.reset()
     retval = meterbus.send_request_frame_multi(self.master, 600)
     self.assertEqual(retval, False)
예제 #8
0
    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)

                req = meterbus.send_request_frame_multi(
                          ser, meterbus.ADDRESS_NETWORK_LAYER)

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