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

(稍后补充)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MCAL是Microcontroller Abstraction Layer的缩写,是一种用于微控制器开发的软件层。MCAL Getting Started Tutorial介绍了如何在MCAL平台上开始进行开发。 首先,在开始MCAL开发之前,我们需要了解MCAL的基本概念和特性。MCAL提供了一套抽象的API(应用程序编程接口),用于对底层硬件进行访问和控制。它的目的是将底层硬件和上层应用程序解耦,使得应用程序可以更方便地进行开发和移植。 接下来,我们需要安装所需的开发工具和环境。根据MCAL的厂商和平台的不同,安装过程也会有所差异。通常,我们需要安装MCAL的开发库、编译器、调试工具等。 安装完成后,我们可以开始编写第一个MCAL应用程序。在MCAL Getting Started Tutorial中,通常会提供一些示例代码和演示用例,以帮助我们理解MCAL的使用方法。我们可以按照教程的步骤来进行代码编写、编译和调试。 在编写MCAL应用程序时,我们需要了解MCAL提供的API和功能库。这些API和功能库包括了对GPIO、UART、SPI、I2C等外设的访问和配置接口,以及中断、时钟管理、内存管理等系统级功能。 最后,在编写和调试完成应用程序之后,我们可以将其下载到目标硬件上进行运行。为了确保应用程序的稳定性和性能,我们还可以进行性能分析和优化。 总的来说,MCAL Getting Started Tutorial为我们提供了一个学习和入门MCAL开发的入口。通过这个教程,我们可以掌握MCAL的基本概念、使用方法和开发流程,从而在微控制器开发中更高效地使用MCAL。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值