bacpytes started 笔记

http://bacpypes.sourceforge.net/gettingstarted/gettingstarted001.html

Device Identifier

Every BACnet device will have a unique identifier, a 22-bit unsigned non-zero value. It is critical that this be unique for every device and most large customers will have someone or a group responsible for maintaining device identifiers across the site. Keep track of the device identifier for the test device, assume that it is 1000 and you are going to pick 1001 for your workstation.

Device Name

Every BACnet device on a BACnet network has a unique name which is a character string. There is nothing on a BACnet network that enforces this uniqueness, but it is a real headache for integrators when it isn’t followed. You will need to pick a name for your workstation. My collegues and I use star names so the sample congiuration files will have “Betelgeuse”.

At some point you will probably running both “client” and “server” applications on your workstation, so you will want separate configuration files for them. Keep in mind that BACnet devices communicate as peers, so it is not unusual for an application to act as both a client and a server at the same time.

UDP Communications Issues

There are two types of UDP messages;
unicast which is a message from one specific IP address and port to another one,
and broadcast which is received and processed by all devices that have the port open.
BACnet uses both types of messages and your workstation will need to receive both types.

unicast (单播):在客户端与媒体服务器之间需要建立一个单独的数据通道,从一台服务器送出的每个数据包只能传送给一个客户机,这种传送方式称为单播。指网络中从源向目的地转发单播流量的过程。单播流量地址唯一。

根据unicast.h中的官方注释理解如下:单播模块发送一个数据包到一个确定的单跳邻居节点。单播原语使用标识广播原语,并将单跳接收节点的地址属性添加到传出的数据包中。当接收节点收到数据包后,单播模块会检查单跳的接收地址属性,如果数据包中的接收地址属性与本节点地址不匹配则丢弃该数据包。

《unicast, multicast, broadcast的区别》

1

The BACpypes.ini file has an address parameter which is an IP address in CIDR notation and can be followed by a port number. For example, 192.168.0.11/16 specifies both the IP address and the number of bits in the network portion, which in turn implies a subnet mask, in this case 255.255.0.0. Unicast messages will be sent to the IP address, and broadcast messages will be sent to the broadcast address 192.168.255.255 which is the network portion of the configuration value will all 1’s in the host portion.

To receive both unicast and broadcast addresses, BACpypes will open two sockets, one for unicast traffic and one that only listens for broadcast messages. The operating system will typically not allow two applications to open the same socket at the same time so to run two BACnet applciations at the same time they need to be configured with different ports.

The BACnet protocol has port 47808 (hex 0xBAC0) assigned to it by the Internet Assigned Numbers Authority, and sequentially higher numbers are used in many applications. There are some BACnet routing and networking isseus with this, but that is for antoher tutorial.

Starting An Application

objectName
modelName

application-software-version

protocol-revision
protocol-revision

iAmDeviceIdentifier = (‘device’, 599)

objectIdentifier: 599

Now to confirm that the workstation can receive the messages that the test device sends out, generate a Who-Is request. This one will be “unconstrained” which means that every device will respond. Do not generate these types of unconstrained requests on a large network because it will create a lot of traffic that can cause conjestion

BACnet网络讲义.doc
在这里插入图片描述

debug

code 1

tLogAA.py

#!/usr/bin/python

import sys

from bacpypes.debugging import bacpypes_debugging, ModuleLogger



# some debugging
_debug = 0
_log = ModuleLogger(globals())


@bacpypes_debugging
class tLogAA:
    pass

    def __init__(self):
        if _debug: tLogAA._debug("tLogAA __init__ MMMMMMMMMM")

code2

testDebugLog.py

#!/usr/bin/python

import sys

from bacpypes.debugging import bacpypes_debugging, ModuleLogger



# some debugging
_debug = 0
_log = ModuleLogger(globals())


@bacpypes_debugging
class testDebugLog:
    pass

    def __init__(self):
        if _debug: testDebugLog._debug("testDebugLog __init__ EEEEEEEEEEEEE")


code3:

testBacnet.py

#!/usr/bin/python

"""
This application presents a 'console' prompt to the user asking for read commands
which create ReadPropertyRequest PDUs, then lines up the coorresponding ReadPropertyACK
and prints the value.
"""
#### 111
import sys

from bacpypes.debugging import bacpypes_debugging, ModuleLogger
from bacpypes.consolelogging import ConfigArgumentParser
from bacpypes.consolecmd import ConsoleCmd

from bacpypes.core import run

from bacpypes.pdu import Address
from bacpypes.app import LocalDeviceObject, BIPSimpleApplication
from bacpypes.object import get_object_class, get_datatype

from bacpypes.apdu import ReadPropertyRequest, Error, AbortPDU, ReadPropertyACK
from bacpypes.primitivedata import Unsigned
from bacpypes.constructeddata import Array
from bacpypes.basetypes import ServicesSupported

import testDebugLog
import tLogAA


# some debugging
_debug = 0
_log = ModuleLogger(globals())

# globals
this_device = None
this_application = None
this_console = None

#
#   ReadPropertyApplication
#

@bacpypes_debugging
class ReadPropertyApplication(BIPSimpleApplication):

    def __init__(self, *args):
        if _debug: ReadPropertyApplication._debug("__init__ %r", args)
        BIPSimpleApplication.__init__(self, *args)

        # keep track of requests to line up responses
        self._request = None

    def request(self, apdu):
        if _debug: ReadPropertyApplication._debug("request %r", apdu)

        # save a copy of the request
        self._request = apdu

        # forward it along
        BIPSimpleApplication.request(self, apdu)

    def confirmation(self, apdu):
        if _debug: ReadPropertyApplication._debug("confirmation %r", apdu)

        if isinstance(apdu, Error):
            sys.stdout.write("error: %s\n" % (apdu.errorCode,))
            sys.stdout.flush()

        elif isinstance(apdu, AbortPDU):
            apdu.debug_contents()

        elif (isinstance(self._request, ReadPropertyRequest)) and (isinstance(apdu, ReadPropertyACK)):
            # find the datatype
            datatype = get_datatype(apdu.objectIdentifier[0], apdu.propertyIdentifier)
            if _debug: ReadPropertyApplication._debug("    - datatype: %r", 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: ReadPropertyApplication._debug("    - value: %r", value)

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

#
#   ReadPropertyConsoleCmd
#

@bacpypes_debugging
class ReadPropertyConsoleCmd(ConsoleCmd):

    def do_read(self, args):
        """read <addr> <type> <inst> <prop> [ <indx> ]"""
        args = args.split()
        if _debug: ReadPropertyConsoleCmd._debug("do_read %r", args)

        try:
            addr, obj_type, obj_inst, prop_id = args[:4]

            if obj_type.isdigit():
                obj_type = int(obj_type)
            elif not get_object_class(obj_type):
                raise ValueError, "unknown object type"

            obj_inst = int(obj_inst)

            datatype = get_datatype(obj_type, prop_id)
            if not datatype:
                raise ValueError, "invalid property for object type"

            # build a request
            request = ReadPropertyRequest(
                objectIdentifier=(obj_type, obj_inst),
                propertyIdentifier=prop_id,
                )
            request.pduDestination = Address(addr)

            if len(args) == 5:
                request.propertyArrayIndex = int(args[4])
            if _debug: ReadPropertyConsoleCmd._debug("    - request: %r", request)

            # give it to the application
            this_application.request(request)

        except Exception, e:
            ReadPropertyConsoleCmd._exception("exception: %r", e)

#
#   __main__
#

try:
    # parse the command line arguments
    args = ConfigArgumentParser(description=__doc__).parse_args()


    if _debug: _log.debug("initialization")
    if _debug: _log.debug("    - args: %r", args)

    print '++++++++++++++++++++++++++++++++++++++++'

    a= testDebugLog.testDebugLog()

    b = tLogAA.tLogAA()

    _log.debug("initialization AAAAAAAAAAAAAAAAAAA")
    print '----------------------------------------'
    # make a device object
    this_device = LocalDeviceObject(
        objectName=args.ini.objectname,
        objectIdentifier=int(args.ini.objectidentifier),
        maxApduLengthAccepted=int(args.ini.maxapdulengthaccepted),
        segmentationSupported=args.ini.segmentationsupported,
        vendorIdentifier=int(args.ini.vendoridentifier),
        )

    # build a bit string that knows about the bit names
    pss = ServicesSupported()
    pss['whoIs'] = 1
    pss['iAm'] = 1
    pss['readProperty'] = 1
    pss['writeProperty'] = 1

    # set the property value to be just the bits
    this_device.protocolServicesSupported = pss.value

    # make a simple application
    this_application = ReadPropertyApplication(this_device, args.ini.address)
    this_console = ReadPropertyConsoleCmd()

    _log.debug("running")

    run()

except Exception, e:
    _log.exception("an error has occurred: %s", e)
finally:
    _log.debug("finally")

运行程序:

(venv) [caipeng@localhost samples]$ python testBacnet.py --debug testDebugLog
++++++++++++++++++++++++++++++++++++++++
DEBUG:testDebugLog.testDebugLog:testDebugLog __init__ EEEEEEEEEEEEE
----------------------------------------
> exit
Exiting...
(venv) [caipeng@localhost samples]$
(venv) [caipeng@localhost samples]$
(venv) [caipeng@localhost samples]$ python testBacnet.py --debug testDebugLog tLogAA
++++++++++++++++++++++++++++++++++++++++
DEBUG:testDebugLog.testDebugLog:testDebugLog __init__ EEEEEEEEEEEEE
DEBUG:tLogAA.tLogAA:tLogAA __init__ MMMMMMMMMM
----------------------------------------
> exit
Exiting...

–debug testDebugLog tLogAA
–degug后面的参数testDebugLog 表示这个文件的名字,而不是里面的类的名字

python bacnet_server.py --debug bacnet_stack_utils

(稍后补充)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值