Looking up and determining what AmbiguousValue is
When reading the schedule default property, even if it is a BinaryPV, BACnet4j returns an AmbiguousValue object.
I've found the convertTo(Class<T>) method which allows the object to be converted to its correct type, and that works as expected (as I know what it should be converted to), but is there a way of determining what object it should be converted to via reflection or similar?
The problem is that AmbiguousValue is the class, so Java-based reflection will not work. This class is used to store the serialized data when it is uncertain how it should be deserialized. So, to determine what type of data it is you would need to peek into the byte array and take your best guess. This is theoretically possible, but as of yet unattempted.
I'm a little surprised/confused by your answer.
The data in reponse back contains the application tag as well as data length (section 20.2.1 in the standard), which can be used to determine what the data type is and process it, which means it shouldn't be necessary to guess. I would have thought that we should know what we are dealing with, with absolute certainty. Am I correct in saying that?
If I print the data in the AmbiguousValue to the console (which is of type binary value/inactive), I get this:
9 Indicates it is enumerated, 1 indicates the length, 0 indicates inactive.
If I print the data in the AmbiguousValue to the console (which is of type real/777.0), I get this:
First 4 indicates it is real, second 4 indicates 4 bytes, remaining 4 bytes is 777.0 in IEEE754-1985 format.
I am fine with peeking into the byte array to handle converting it to the relevant object, but I don't see any method which exposes the application type (or the byte array), which would be necessary if it were to be done without modifying any BACnet4J source files.
Of course, if the correct type could be determined in the first place, that would be better :D
That's what i mean by peeking into the byte array. Deserialization is done by "knowing" what should be in the response, an approach that results in ambiguous content in some cases. It may be possible to determine from the bytes what the content is - certainly in the cases that you've described - but i personally don't know if this is always possible, or also leads to ambiguity. I imagine some combination of the two would be possible, where in ambiguous cases a list of possible types is provided to a resolver. But, as i said, nothing like this has been attempted.
I've written a function which could be used in conjuction with the convertTo(Class<T>) function to get the Object in its correct form for any Primitive class
With it, you could then do the following:
AmbiguousValue av = (AmbiguousValue)schedule.getProperty(PropertyIdentifier.scheduleDefault); Class<? extends Primitive> c = (Class<? extends Primitive>)av.getPrimitiveClass(); Primitive pr = av.convertTo(c);
What is your preferred way for code submissions? A diff file as an attachment or pasted directly into the body in a code block? Or other?
Attachment: download link