bacpypes icon indicating copy to clipboard operation
bacpypes copied to clipboard

i want to read Data from bacnet device using python code instead of commandline

Open ankit-mabzone opened this issue 3 years ago • 3 comments

Hello

I have created a class which has similar function and steps those are in ReadWrite property of this library. but when i am trying to read data it stucks at IOCB wait and i didn't get any response from device. where as lib works for the same command and gives data back.

I have MSTP client so i am using MISTY library for that

class BACNetClientDevice(ConsoleCmd): def init(self,interface,baudrate,address,MaxApdulength,maxinfo,maxmasters):

self.baudrate = int(baudrate)
self.address = int(address)
self.interface = str(interface)
self.MaxApdulength = int(MaxApdulength)
self.maxinfo = int(maxinfo)
self.maxmasters =int(maxmasters)
global this_application



BACnetIni = {
"objectname" : "BACClient", 
"address" : address,
"interface" : interface, 
"max_masters" : maxmasters,
"maxinfo":maxinfo,
"objectidentifier": "599",
"baudrate" : baudrate,
"objectidentifier": "599",
"maxapduLengthaccepted": MaxApdulength,
"segmentationsupported": "segmentedBoth",
"vendoridentifier": "15",
"foreignPort": "0",
"foreignbbmd": "128.253.109.254",
"foreignttl": "30"
 }

mstp_args = {
    '_address': int(address),
    '_interface':str(interface),
    '_max_masters': int(maxmasters),
    '_baudrate': int(baudrate),
    '_maxinfo': int(maxinfo),
}
this_device = LocalDeviceObject(ini=Settings(BACnetIni),**mstp_args)        
this_application = MSTPSimpleApplication(this_device,address)
this_console = ConsoleCmd()
enable_sleeping()

def ReadAnalogvaluee(self,SourceAddress,reg): cmd=str(SourceAddress)+' analogValue:'+str(reg)+' presentValue'

print(cmd)
args = cmd.split()
if _debug: print("Read ", args)
try:
    addr, obj_id, prop_id = args[:3]
    obj_id = ObjectIdentifier(obj_id).value

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

    # build a request
    request = ReadPropertyRequest(
        objectIdentifier=obj_id,
        propertyIdentifier=prop_id,
        )
    request.pduDestination = Address(addr)
       
    if len(args) == 4:
        request.propertyArrayIndex = int(args[3])
    if _debug: print("    - request:", request)

        # make an IOCB
    iocb = IOCB(request)
    if _debug: print("    - iocb: ", iocb)

  
        # give it to the application
    deferred(this_application.request_io, iocb)
    #iocb.set_timeout(2, err=TimeoutError)
    #this_application.request_io(iocb)
        # wait for it to complete
    
    
    iocb.wait()
   
    if iocb.ioResponse:
        apdu = iocb.ioResponse

            # should be an ack
        if not isinstance(apdu, ReadPropertyACK):
            if _debug: print("    - not an ack")
            return

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

            # special case for array parts, others are managed by cast_out
        if issubclass(datatype, Array) and (apdu.propertyArrayIndex is not None):
            if apdu.propertyArrayIndex == 0:
                value = apdu.propertyValue.cast_out(Unsigned)
            else:
                value = apdu.propertyValue.cast_out(datatype.subtype)
        else:
            value = apdu.propertyValue.cast_out(datatype)
        if _debug: print("    - value: ", value)

        sys.stdout.write(str(value) + '\n')
        if hasattr(value, 'debug_contents'):
            value.debug_contents(file=sys.stdout)
        sys.stdout.flush()

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

except Exception as error:
    print("exception: ", error)

NewDevice = BACNetClientDevice("/dev/ttyS0",38400,25,1024,1,127) NewDevice.ReadAnalogvaluee(127,1)

image

Please help me to duplicate this issue

ankit-mabzone avatar Nov 14 '21 06:11 ankit-mabzone

The IOCB is used in two different ways; (1) in threaded applications that synchronize requests/responses through events, and (2) through non-threaded applications using callbacks. If your thread stalls at the iocb.wait() it implies that you are using threads and that some other thread has not called the iocb.complete() function. If you run the application with --debug bacpypes.iocb then you can see the IOCB instances that are created, number in parenthesis is the IOCB identity (just a monotonically increasing number) so you can line them up in the debug output.

I do not have other MSTP devices, so I cannot help with misty.

JoelBender avatar Nov 14 '21 17:11 JoelBender

Hi @ankit-mabzone , I have a similar requirement. Have an MSTP client, using Misty library, don't need the console command. Wanted to know if you were able to figure it out. OR @JoelBender you could let us know if there is a way to explicitly disable the Command Console in BACpypes.

mohakbhalla7 avatar Aug 24 '22 10:08 mohakbhalla7

There are lots of sample applications in the bacpypes/samples directory that do not have a console, for example ReadObjectList.py is given a device instance number and its device address and reads all the object names from the object list.

JoelBender avatar Aug 24 '22 13:08 JoelBender