bacpypes icon indicating copy to clipboard operation
bacpypes copied to clipboard

Unable to write DateTime datatype properties

Open dayanand4u opened this issue 5 years ago • 18 comments

Hi, I am trying to write DateTime datatype properties like starttime for trendlog object.

Tried with different options in property value writeproperty('trendLog', '1', 'startTime','(120, 4, 15, 3),(Any)')

I am getting below error unable to write the property. exception: %r invalid result datatype, expecting DateTime None

Need help to resolve this.

dayanand4u avatar Apr 11 '20 07:04 dayanand4u

I've noticed that an exception is raised when attempting to access objects that are of type dateTime

dayanand4u avatar Apr 11 '20 07:04 dayanand4u

It looks like your function takes an object identifier as two parameters, it should be something like (str, int) to be consistent with the rest of BACpypes. The startTime property is optional for the TrendLog and TrendLogMultiple objects, so register a subclass that provides a definition that makes it writable:

@register_object_type(vendor_id=999)
class MyTrendLogObject(TrendLogObject):
    properties = [ WritableProperty('startTime', DateTime) ]

And you have a character string '(120, 4, 15, 3),(Any)' and that should probably be a tuple (120, 4, 15, 3), but that's inside your function, so I can't help with that.

JoelBender avatar Apr 11 '20 14:04 JoelBender

Thank you for reply, Could you please give me an example how to send the property value of these types of datatypes (DateTime) for different objects for write property .

Ex : writeproperty [ ] [ ]""

dayanand4u avatar Apr 11 '20 14:04 dayanand4u

from bacpypes.pdu import Address
from bacpypes.primitivedata import Date
from bacpypes.constructeddata import Any
from bacpypes.apdu import WritePropertyRequest

# Python2/3 rename
try: input = raw_input
except NameError: pass

address = Address(input("address: "))
date_value = Date(input("date_value: "))

# build a request
request = WritePropertyRequest(
    destination=address,
    objectIdentifier=('trendLog', 5),
    propertyIdentifier='startTime',
    propertyValue=Any(),
    )

# encode the value
request.propertyValue.cast_in(date_value)

# dump the result
request.debug_contents()

JoelBender avatar Apr 11 '20 22:04 JoelBender

Hi ,I have tried to execute below properties datatypes using writeproperty but i am facing Invalid constructor datatype** . Could you please guide me to resolve.

Property ID:'35',
Property Name : eventEnable
Data Type : EventTransitionBits

Hi have tried to execute Datetime datatype property as well but i am unable to write that property.

writeproperty(obj_type, obj_inst, prop_id, value, prop_array_index=None, priority=None): #Tried with below code:

       if obj_type.isdigit():
            obj_type = int(obj_type)

        obj_inst = int(obj_inst)

        if prop_id.isdigit():
            prop_id = int(prop_id)
        
        # get the propertyArrayIndex if any
        if prop_array_index is not None:
            prop_array_index = int(prop_array_index)
        
        # get the priority if any
        if priority is not None:
            priority = int(priority)

        # get the datatype
        proprietary = False
        datatype = get_datatype(obj_type, prop_id)
        if not datatype:
            proprietary = True
            
        # change atomic values into something encodeable, null is a special case
        if value == 'null':
            value = Null()

        # elif (Proprietary == True) and issubclass(datatype, AnyAtomic):
        elif proprietary:
            dtype, dvalue = value.split(':')

            datatype = {
                'b': Boolean,
                'u': lambda x: Unsigned(int(x)),
                'i': lambda x: Integer(int(x)),
                'r': lambda x: Real(float(x)),
                'd': lambda x: Double(float(x)),
                'o': OctetString,
                'c': CharacterString,
                'bs': BitString,
                'date': Date,
                'time': Time,
                }[dtype]

            value = datatype(dvalue)
            value = Any(value)
            
        elif issubclass(datatype, Atomic):
            if datatype is Integer:
                value = int(value)
            elif datatype is Real:
                value = float(value)
            elif datatype is Unsigned:
                value = int(value)
                
            value = datatype(value)
            value = Any(value)
            
        elif issubclass(datatype, Array) and (prop_array_index is not None):
            if prop_array_index == 0:
                value = Integer(value)
            elif issubclass(datatype.subtype, Atomic):
                value = datatype.subtype(value)
            elif not isinstance(value, datatype.subtype):
                raise TypeError("invalid result datatype, expecting %s" % (datatype.subtype.__name__,))
        elif not isinstance(value, datatype):
            raise TypeError("invalid result datatype, expecting %s" % (datatype.__name__,))
        
        #date_value = Date(input("date_value: ")) 
        # build a request
        request = WritePropertyRequest(
            objectIdentifier=(obj_type, obj_inst),
            propertyIdentifier=prop_id
            )
        request.pduDestination = Address(self.addr)

        # save the value
        request.propertyValue = Any()
        try:
            request.propertyValue.cast_in(value)
        except Exception as error:
            print("WriteProperty cast error: %r", error)

        # optional array index
        if prop_array_index is not None:
            request.propertyArrayIndex = prop_array_index

        # optional priority
        if priority is not None:
            request.priority = priority

        # make an IOCB
        iocb = IOCB(request)
        deferred(self.this_application.request_io, iocb)

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

        # wait for it to complete
        iocb.wait()

        # parse response for success
        if iocb.ioResponse:
            # should be an ack
            if not isinstance(iocb.ioResponse, SimpleAckPDU):
                return

            return "ack"

        # report and exit for error/reject/abort
        if iocb.ioError:
            print(str(iocb.ioError) + '\n')

dayanand4u avatar Apr 28 '20 17:04 dayanand4u

I'll make an issue for this, but for now, change this line:

'bs': BitString,

To this:

'bs': lambda x: BitString([int(y) for y in x]),

The BitString type is looking for a list of ones and zeros, so the value is "bs:001" for a to-normal event transition.

JoelBender avatar Apr 29 '20 20:04 JoelBender

Thank you very much Joel for response. I am able perform write operation for eventEnable property. Working syntax Examples:

  1. bacnet.writeproperty('analogValue', '3', '35', 'bs:111')
  2. bacnet.writeproperty('2', '3', 'eventEnable', 'bs:111')

But if i am using the property value argument as property name ,i am facing below error. How it will success if we use property name as argument please sujjest.

bacnet.writeproperty('analogValue', '3', 'eventEnable', 'bs:111') Error: exception: %r invalid constructor datatype

dayanand4u avatar Apr 30 '20 15:04 dayanand4u

There is not enough information in your example for me to help, I need to know the name of the class that you are attempting to instantiate. I'm also confused by what you mean by "using the property value argument as property name" because those are two different concepts.

JoelBender avatar May 02 '20 14:05 JoelBender

I am using do_write request method from class ReadPropertyApplication(BIPSimpleApplication) and created small combined wrapper which is having all services like read, write and subsribe cov and other required services.

Currently i am trying to use write request and using this writing all accessible object properties. Refer my #5 comment here of my write request code in my wrapper.

#Syntax of Writeproperty. writeproperty(obj_type, obj_inst, prop_id, value, prop_array_index=None, priority=None):

Here obj_type = Object Identifier, obj_inst = Object Instanance, prop_id = Property name value = Property Value prop_array_index = Index priority= priority Value.

If i pass the arguments like below for write request , It working fine.

bacnet.writeproperty('analogValue', '3', '35', 'bs:111') bacnet.writeproperty('2', '3', 'eventEnable', 'bs:111')

If i pass the arguments like below for write request , It not working fine.

bacnet.writeproperty('analogValue', '3', 'eventEnable', 'bs:111') Error: exception: %r invalid constructor datatype

Here i have another query is for other properties i am not specifying the datatype but still its working please find example below.

self.bacnet.writeproperty('analogValue', '3', 'presentValue', '8')

dayanand4u avatar May 02 '20 18:05 dayanand4u

Need support for clearing the priority array for my Analog Value object. I am trying use the same mentioned write request method but its showing error. could please guide me to with syntax or example to clear the priority array.

Syntax i am using - self.bacnet.writeproperty('analogValue', '3', 'priorityArray', 'null',prop_array_index=16, priority=None)

Error i am getting below- applicationExceededReplyTime

None

Please guide me the mentioned queries. Thanks in advance for support.

dayanand4u avatar May 02 '20 18:05 dayanand4u

If you are getting this error it is coming from your gateway:

H.2.1.4 Handling Requests That Take Too Long Confirmed requests that cannot be fulfilled within the allowed APDU_Timeout shall result in an abort PDU being returned to the client. This condition may be caused by requests for too much data or for too many properties that are not cached in the gateway ...[clip]... the gateway shall return the abort PDU with an abort reason of APPLICATION_EXCEEDED_REPLY_TIME, and the client is expected to retry the request with fewer properties.

JoelBender avatar May 02 '20 20:05 JoelBender

My application(Windows Environment) and python bacpypes script is in same PC . [Configured different ip address for local interface adapter]

Could you please guide me about my below Query's:

  1. How to clear the priority array for Analog Value object . Please guide me shal i use same writeproperty request or any other class defined for it. Please give me an example to write the priority array as Null.

  2. How the writeproperty request will work for all properties without define datatype like below. self.bacnet.writeproperty('analogValue', '3', 'presentValue', '8') [ Please see my 6th comment] in this issue.

For Few properties its not working in the above syntax mananer . EX: bacnet.writeproperty('analogValue', '3', 'eventEnable', 'bs:111') Error: exception: %r invalid constructor datatype

dayanand4u avatar May 03 '20 16:05 dayanand4u

Could you please help me out my queries

dayanand4u avatar May 06 '20 11:05 dayanand4u

The writeproperty() is not in the BACpypes library, and with four different parameters there is no way to know which of the primitive datatypes is giving you the problem. Turning debugging will not help much because there is very little debugging code in that module. Please check the parameters you are passing with the values shown in the tests (the tests/test_primitive_data/ directory).

JoelBender avatar May 07 '20 00:05 JoelBender

Hi Joel, Need your help, My requirement is to clear the priority value for any object. What is the correct way to clear the priority array for a given object?

Could you please guide me the method to use clear the priority value and example of code syntax

dayanand4u avatar May 21 '20 14:05 dayanand4u

Hi joel, could you please help me out for above request reg clear the priority value of object

dayanand4u avatar May 26 '20 17:05 dayanand4u

To "relinquish" an override at a particular priority level, write a "null" to the priority array at the specific array index. For example, if you wrote a 75.3 to an analog value object at priority level 7, to clear that out write a NULL to the Priority_Array (called priorityArray in BACpypes) at index 7. See Clause 19.2.1.3 Relinquish Commands.

JoelBender avatar May 26 '20 18:05 JoelBender

Thank You Joel for response . I am able to clear the priority array by using property id as presentValue instead of Propertyarray property id.

Not working Ex: writeproperty('analogValue', '3', 'priorityArray','null,'prop_array_index='15')

Working Ex: writeproperty('analogValue', '3', 'presentValue', 'null', priority=16)

dayanand4u avatar May 27 '20 14:05 dayanand4u