# Path: BAC0/core/io/IOExceptions.py
# class NoResponseFromController(Exception):
#     """
#     This exception is used when trying to read or write and there is not answer.
#     """
# 
#     pass
# 
# class WritePropertyException(Exception):
#     """
#     This exception is used when trying to write a property.
#     """
# 
#     pass
# 
# Path: BAC0/core/io/Read.py
# def find_reason(apdu):
#     try:
#         if apdu == TimeoutError:
#             return "Timeout"
#         elif apdu.pduType == RejectPDU.pduType:
#             reasons = RejectReason.enumerations
#         elif apdu.pduType == AbortPDU.pduType:
#             reasons = AbortReason.enumerations
#         else:
#             if apdu.errorCode and apdu.errorClass:
#                 return "{}".format(apdu.errorCode)
#             else:
#                 raise ValueError("Cannot find reason...")
#         code = apdu.apduAbortRejectReason
#         try:
#             return [k for k, v in reasons.items() if v == code][0]
#         except IndexError:
#             return code
#     except KeyError as err:
#         return "KeyError: {} has no key {0!r}".format(type(apdu), err.args[0])


from bacpypes.iocb import IOCB
from bacpypes.core import deferred
from bacpypes.apdu import WritePropertyRequest, SimpleAckPDU
from bacpypes.primitivedata import CharacterString
from bacpypes.constructeddata import Any
from bacpypes.pdu import Address
from BAC0.core.io.IOExceptions import NoResponseFromController, WritePropertyException
from BAC0.core.io.Read import find_reason
    ):
        request = WritePropertyRequest(
            objectIdentifier=(obj_type, obj_inst), propertyIdentifier=prop_id
        )
        request.pduDestination = Address(addr)

        _value = Any()
        _value.cast_in(CharacterString(value))
        request.propertyValue = _value

        return request

    def write_text_value(self, request, timeout=10):
        try:
            iocb = IOCB(request)
            iocb.set_timeout(timeout)
            # pass to the BACnet stack
            deferred(self.this_application.request_io, iocb)

            iocb.wait()  # Wait for BACnet response

            if iocb.ioResponse:  # successful response
                apdu = iocb.ioResponse

                if not isinstance(apdu, SimpleAckPDU):  # expect an ACK
                    self._log.error("Not an ack, see debug for more infos.")
                    return

            if iocb.ioError:  # unsuccessful: error/reject/abort
                apdu = iocb.ioError

# Path: BAC0/core/io/IOExceptions.py
# class NoResponseFromController(Exception):
#     """
#     This exception is used when trying to read or write and there is not answer.
#     """
# 
#     pass
# 
# class WritePropertyException(Exception):
#     """
#     This exception is used when trying to write a property.
#     """
# 
#     pass
# 
# Path: BAC0/core/io/Read.py
# def find_reason(apdu):
#     try:
#         if apdu == TimeoutError:
#             return "Timeout"
#         elif apdu.pduType == RejectPDU.pduType:
#             reasons = RejectReason.enumerations
#         elif apdu.pduType == AbortPDU.pduType:
#             reasons = AbortReason.enumerations
#         else:
#             if apdu.errorCode and apdu.errorClass:
#                 return "{}".format(apdu.errorCode)
#             else:
#                 raise ValueError("Cannot find reason...")
#         code = apdu.apduAbortRejectReason
#         try:
#             return [k for k, v in reasons.items() if v == code][0]
#         except IndexError:
#             return code
#     except KeyError as err:
#         return "KeyError: {} has no key {0!r}".format(type(apdu), err.args[0])


# Path: BAC0/core/functions/Text.py
from bacpypes.iocb import IOCB
from bacpypes.core import deferred
from bacpypes.apdu import WritePropertyRequest, SimpleAckPDU
from bacpypes.primitivedata import CharacterString
from bacpypes.constructeddata import Any
from bacpypes.pdu import Address
from BAC0.core.io.IOExceptions import NoResponseFromController, WritePropertyException
from BAC0.core.io.Read import find_reason

    ):
        request = WritePropertyRequest(
            objectIdentifier=(obj_type, obj_inst), propertyIdentifier=prop_id
        )
        request.pduDestination = Address(addr)

        _value = Any()
        _value.cast_in(CharacterString(value))
        request.propertyValue = _value

        return request

    def write_text_value(self, request, timeout=10):
        try:
            iocb = IOCB(request)
            iocb.set_timeout(timeout)
            # pass to the BACnet stack
            deferred(self.this_application.request_io, iocb)

            iocb.wait()  # Wait for BACnet response

            if iocb.ioResponse:  # successful response
                apdu = iocb.ioResponse

                if not isinstance(apdu, SimpleAckPDU):  # expect an ACK
                    self._log.error("Not an ack, see debug for more infos.")
                    return

            if iocb.ioError:  # unsuccessful: error/reject/abort
                apdu = iocb.ioError

                reason = find_reason(apdu)