Example #1
0
    def build_rrange_request(
        self, args, range_params=None, arr_index=None, vendor_id=0, bacoid=None
    ):
        addr, obj_type, obj_inst, prop_id = args[:4]

        vendor_id = vendor_id
        bacoid = bacoid

        if obj_type.isdigit():
            obj_type = int(obj_type)
        elif not get_object_class(obj_type, vendor_id=vendor_id):
            raise ValueError("Unknown object type {}".format(obj_type))

        obj_inst = int(obj_inst)

        if prop_id.isdigit():
            prop_id = int(prop_id)
        datatype = get_datatype(obj_type, prop_id, vendor_id=vendor_id)
        if not datatype:
            raise ValueError("invalid property for object type")

        # build a request
        request = ReadRangeRequest(
            objectIdentifier=(obj_type, obj_inst), propertyIdentifier=prop_id
        )
        request.pduDestination = Address(addr)
        if range_params is not None:
            range_type, first, date, time, count = range_params
            if range_type == "p":
                rbp = RangeByPosition(referenceIndex=int(first), count=int(count))
                request.range = Range(byPosition=rbp)
            elif range_type == "s":
                rbs = RangeBySequenceNumber(
                    referenceSequenceNumber=int(first), count=int(count)
                )
                request.range = Range(bySequenceNumber=rbs)
            elif range_type == "t":
                rbt = RangeByTime(
                    referenceTime=DateTime(
                        date=Date(date).value, time=Time(time).value
                    ),
                    count=int(count),
                )
                request.range = Range(byTime=rbt)
            elif range_type == "x":
                # should be missing required parameter
                request.range = Range()
            else:
                raise ValueError("unknown range type: %r" % (range_type,))

        if len(args) == 5:
            request.propertyArrayIndex = int(args[4])
        self._log.debug("{:<20} {!r}".format("REQUEST", request))
        return request
Example #2
0
    def do_readrange(self, args):
        """readrange <addr> <objid> <prop> [ <indx> ]
            [ p <indx> <count> ]
            [ s <seq> <count> ]
            [ t <date> <time> <count> ]
        """
        args = args.split()
        if _debug:
            ReadRangeConsoleCmd._debug("do_readrange %r", args)

        try:
            addr = Address(args.pop(0))
            obj_id = ObjectIdentifier(args.pop(0)).value
            prop_id = args.pop(0)

            datatype = get_datatype(obj_id[0], prop_id)
            if not datatype:
                raise ValueError("invalid property for object type")

            # build a request
            request = ReadRangeRequest(destination=addr,
                                       objectIdentifier=obj_id,
                                       propertyIdentifier=prop_id)

            # index is optional
            if args:
                if args[0].isdigit():
                    if not issubclass(datatype, Array):
                        raise ValueError("property is not an array")
                    request.propertyArrayIndex = int(args.pop(0))
                    datatype = datatype.subtype
            if not issubclass(datatype, List):
                raise ValueError("property is not a list")

            # range is optional
            if args:
                range_type = args.pop(0)
                if range_type == "p":
                    rbp = RangeByPosition(referenceIndex=int(args[0]),
                                          count=int(args[1]))
                    request.range = Range(byPosition=rbp)
                elif range_type == "s":
                    rbs = RangeBySequenceNumber(referenceSequenceNumber=int(
                        args[0]),
                                                count=int(args[1]))
                    request.range = Range(bySequenceNumber=rbs)
                elif range_type == "t":
                    rbt = RangeByTime(
                        referenceTime=DateTime(date=Date(args[0]),
                                               time=Time(args[1])),
                        count=int(args[2]),
                    )
                    request.range = Range(byTime=rbt)
                else:
                    raise ValueError("unknown range type: %r" % (range_type, ))

            if _debug:
                ReadRangeConsoleCmd._debug("    - request: %r", request)

            # make an IOCB
            iocb = IOCB(request)
            if _debug:
                ReadRangeConsoleCmd._debug("    - iocb: %r", iocb)

            # give it to the application
            deferred(this_application.request_io, iocb)

            # wait for it to complete
            iocb.wait()

            # do something for success
            if iocb.ioResponse:
                apdu = iocb.ioResponse
                if _debug:
                    ReadRangeConsoleCmd._debug("    - apdu: %r", apdu)

                # should be an ack
                if not isinstance(apdu, ReadRangeACK):
                    if _debug:
                        ReadRangeConsoleCmd._debug("    - not an ack")
                    return

                # find the datatype
                datatype = get_datatype(apdu.objectIdentifier[0],
                                        apdu.propertyIdentifier)
                if _debug:
                    ReadRangeConsoleCmd._debug("    - datatype: %r", datatype)
                if not datatype:
                    raise TypeError("unknown datatype")

                sys.stdout.write("firstSequenceNumber: %s\n" %
                                 (apdu.firstSequenceNumber, ))
                sys.stdout.write("resultFlags: %s\n" % (apdu.resultFlags, ))

                # cast out the data into a list
                value = apdu.itemData.cast_out(datatype)

                # dump it out
                for i, item in enumerate(value):
                    sys.stdout.write("[%d]\n" % (i, ))
                    item.debug_contents(file=sys.stdout, indent=2)
                sys.stdout.flush()

            # do something for error/reject/abort
            if iocb.ioError:
                sys.stdout.write(str(iocb.ioError) + "\n")

        except Exception as error:
            ReadRangeConsoleCmd._exception("exception: %r", error)