def __write_value(self, config_obj_id: str, _value: float) -> None:
        try:
            # get config obj
            obj = self.__get_object(config_obj_id)
            obj_id = obj.get('object_id')
            obj_id = ObjectIdentifier(obj_id).value # make a bacpypes obj id
            addr = self.__get_device()
            prop_id = self.__get_prop()

            # write <addr> <objid> <prop> <value> 
            value = float(_value)
            self.logger.debug(f"write: {config_obj_id} {_value} for port \'{obj.get('name')}\' {str(obj_id)} {prop_id} {value}")

            request = WritePropertyRequest(
                objectIdentifier=obj_id,
                propertyIdentifier=prop_id
                )
            request.pduDestination = Address(addr)

            # the value to write 
            datatype = get_datatype(obj_id[0], prop_id)
            value = datatype(value)
            request.propertyValue = Any()
            try:
                request.propertyValue.cast_in(value)
            except Exception as err:
                self.logger.critical(f"write: {err}")

            iocb = IOCB(request)
            self.app.request_io(iocb)
            self.logger.debug("write: waiting for response...")
            loopCount = 0
            while loopCount < 20 and not iocb.ioResponse:
                loopCount += 1
                run_once()
                asyncore.loop(timeout=0.2, count=1)
                time.sleep(0.2)
                self.logger.debug(f"write: loopy {loopCount}")
            stop()

            # do something for success
            if iocb.ioResponse:
                self.logger.debug(f"write: iocb response success!")

                apdu = iocb.ioResponse

                # should be an ack
                if not isinstance(iocb.ioResponse, SimpleAckPDU):
                    self.logger.error(f"write: Not an ACK")
                    return
                self.logger.debug(f"write: received ACK")

            # do something for error/reject/abort
            if iocb.ioError:
                self.logger.error(f"write: ioError {str(iocb.ioError)}")

        except Exception as err:
            exc_type, exc_value, exc_traceback = sys.exc_info()
            traceback.print_tb(exc_traceback, file=sys.stdout)
            self.logger.critical(f"write: {err}")
예제 #2
0
def run_time_machine(time_limit):
    """This function is called after a set of tasks have been installed
    and they should run.  The machine will stop when the limit has been
    reached (maybe the middle of some tests) and can be called again to
    continue running.
    """
    if _debug: run_time_machine._debug("run_time_machine %r", time_limit)
    global time_machine

    # a little error checking
    if not time_machine:
        raise RuntimeError("no time machine")
    if time_limit <= 0.0:
        raise ValueError("time limit required")
    if time_machine.current_time is None:
        raise RuntimeError("reset the time machine before running")

    # pass the limit to the time machine
    time_machine.time_limit = time_machine.current_time + time_limit

    # check if there are deferred functions
    if _core.deferredFns:
        if _debug: run_time_machine._debug("    - deferred functions!")

    # run until there is nothing left to do
    while True:
        _core.run_once()
        if _debug: run_time_machine._debug("    - ran once")

        if not time_machine.more_to_do():
            if _debug: run_time_machine._debug("    - no more to do")
            break
예제 #3
0
def run_time_machine(duration=None, stop_time=None):
    """This function is called after a set of tasks have been installed
    and they should run.  The machine will stop when the stop time has been
    reached (maybe the middle of some tests) and can be called again to
    continue running.
    """
    if _debug:
        run_time_machine._debug("run_time_machine %r %r", duration, stop_time)
    global time_machine

    # a little error checking
    if not time_machine:
        raise RuntimeError("no time machine")
    if time_machine.current_time is None:
        raise RuntimeError("reset the time machine before running")

    # check for duration, calculate the time limit
    if duration is not None:
        # pass the limit to the time machine
        time_machine.time_limit = time_machine.current_time + duration

    elif stop_time is not None:
        # the start might be a special string
        if isinstance(stop_time, str):
            stop_time = xdatetime(stop_time, time_machine.current_time)
            if _debug:
                reset_time_machine._debug("    - stop_time: %r", stop_time)

        # pass the limit to the time machine
        time_machine.time_limit = stop_time
    else:
        raise RuntimeError("duration or stop_time required")

    # check if there are deferred functions
    if _core.deferredFns:
        if _debug: run_time_machine._debug("    - deferred functions!")

    # run until there is nothing left to do
    while True:
        _core.run_once()
        if _debug: run_time_machine._debug("    - ran once")

        if not time_machine.more_to_do():
            if _debug: run_time_machine._debug("    - no more to do")
            break

    # update the current time to the time limit
    time_machine.current_time = time_machine.time_limit
예제 #4
0
def run_time_machine(time_limit):
    """This function is called after a set of tasks have been installed
    and they should all run.
    """
    if _debug: run_time_machine._debug("run_time_machine %r", time_limit)
    global time_machine

    # a little error checking
    if not time_machine:
        raise RuntimeError("no time machine")
    if time_limit <= 0.0:
        raise ValueError("time limit required")

    # pass the limit to the time machine
    time_machine.time_limit = time_limit

    # run until there is nothing left to do
    run_once()
예제 #5
0
def run_time_machine(time_limit):
    """This function is called after a set of tasks have been installed
    and they should all run.
    """
    if _debug: run_time_machine._debug("run_time_machine %r", time_limit)
    global time_machine

    # a little error checking
    if not time_machine:
        raise RuntimeError("no time machine")
    if time_limit <= 0.0:
        raise ValueError("time limit required")

    # pass the limit to the time machine
    time_machine.time_limit = time_limit

    # run until there is nothing left to do
    run_once()
    def ping(self) -> None:
        try:
            # build a request
            request = WhoIsRequest() 
            # ping all devices on network
            request.pduDestination = GlobalBroadcast() 
            # make an IOCB (input output callback)
            iocb = IOCB(request)
            self.app.request_io(iocb)
            self.logger.debug("ping: waiting for responses...")
            loopCount = 0
            while loopCount < 20 and not iocb.ioResponse:
                loopCount += 1
                run_once()
                asyncore.loop(timeout=0.2, count=1)
                time.sleep(0.2)
                self.logger.debug(f"ping: loopy {loopCount}")
            stop()

            # handle responses
            if iocb.ioResponse:
                self.logger.debug(f"ping: iocb response success!")
                apdu = iocb.ioResponse
                if not isinstance(apdu, IAmRequest):
                    self.logger.error(f"ping: Not an IAmRequest")
                    return
                device_type, device_instance = apdu.iAmDeviceIdentifier
                if device_type != 'device':
                    raise DecodingError("ping: invalid object type")
                self.logger.info(f"ping: pduSource={repr(apdu.pduSource)}")
                self.logger.info(f"ping: deviceId={str(apdu.iAmDeviceIdentifier)}")

            # do something for error/reject/abort
            if iocb.ioError:
                self.logger.error(f"ping: {str(iocb.ioError)}")

        except Exception as err:
            exc_type, exc_value, exc_traceback = sys.exc_info()
            traceback.print_tb(exc_traceback, file=sys.stdout)
            self.logger.critical(f"ping: {err}")
예제 #7
0
# analog value 2
av2 = AnalogValueObject(
    objectIdentifier=('analogValue', 2),
    presentValue=75.3,
)
if _debug: _log.debug("    - av2: %r", av2)

# sample event detection
sed = SampleEventDetection(
    pParameter=(av1, 'presentValue'),
    pSetPoint=(av2, 'presentValue'),
)
if _debug: _log.debug("    - sed: %r", sed)

print("")

av1.presentValue = 12.5
run_once()

print("")

av2.presentValue = 12.5
run_once()

print("")

av1.presentValue = 9.8
av2.presentValue = 10.3
run_once()
    def __read_value(self, config_obj_id: str) -> float:
        try:
            # get config obj
            obj = self.__get_object(config_obj_id)
            obj_id = obj.get('object_id')
            obj_id = ObjectIdentifier(obj_id).value # make a bacpypes obj id
            addr = self.__get_device()
            prop_id = self.__get_prop()

            # read <addr> <objid> <prop> 
            self.logger.debug(f"read: {config_obj_id} for port \'{obj.get('name')}\' {addr} {str(obj_id)} {prop_id}")

            request = ReadPropertyRequest(
                objectIdentifier=obj_id,
                propertyIdentifier=prop_id
                )
            request.pduDestination = Address(addr)

            iocb = IOCB(request)
            self.app.request_io(iocb)
            self.logger.debug("read: waiting for response...")
            loopCount = 0
            while loopCount < 20 and not iocb.ioResponse:
                loopCount += 1
                run_once()
                asyncore.loop(timeout=0.2, count=1)
                time.sleep(0.2)
                self.logger.debug(f"read: loopy {loopCount}")
            stop()

            # do something for success
            if iocb.ioResponse:
                self.logger.debug(f"read: iocb response success!")
                apdu = iocb.ioResponse

                # should be an ack
                if not isinstance(apdu, ReadPropertyACK):
                    self.logger.error(f"read: response: Not an ACK")
                    return 0

                # find the datatype
                datatype = get_datatype(apdu.objectIdentifier[0], 
                        apdu.propertyIdentifier)
                self.logger.debug(f"read: datatype {datatype}")
                if not datatype:
                    self.logger.error(f"read: unknown datatype")
                    return

                value = apdu.propertyValue.cast_out(datatype)
                self.logger.debug(f"read: value {value}")

                if hasattr(value, 'debug_contents'):
                    value.debug_contents(file=sys.stdout)
                    sys.stdout.flush()

                return value

            # do something for error/reject/abort
            if iocb.ioError:
                self.logger.error(f"read: ioError {str(iocb.ioError)}")

        except Exception as err:
            exc_type, exc_value, exc_traceback = sys.exc_info()
            traceback.print_tb(exc_traceback, file=sys.stdout)
            self.logger.critical(f"read: {err}")
        return None
예제 #9
0
# analog value 2
av2 = AnalogValueObject(
    objectIdentifier=('analogValue', 2),
    presentValue=75.3,
    )
if _debug: _log.debug("    - av2: %r", av2)

# sample event detection
sed = SampleEventDetection(
    pParameter=(av1, 'presentValue'),
    pSetPoint=(av2, 'presentValue'),
    )
if _debug: _log.debug("    - sed: %r", sed)

print("")

av1.presentValue = 12.5
run_once()

print("")

av2.presentValue = 12.5
run_once()

print("")

av1.presentValue = 9.8
av2.presentValue = 10.3
run_once()