From 44a8023718a36a8aec940df2d58de723ff6c3333 Mon Sep 17 00:00:00 2001 From: Joel Bender Date: Wed, 22 Apr 2020 19:02:34 -0400 Subject: [PATCH] split out the release notes --- 0.17.0-Release-Notes.md | 108 ++++++++++ 0.17.1-Release-Notes.md | 73 +++++++ 0.17.2-Release-Notes.md | 8 + 0.17.3-Release-Notes.md | 33 +++ 0.17.5-Release-Notes.md | 73 +++++++ 0.17.7-Release-Notes.md | 102 +++++++++ 0.18.0-Release-Notes.md | 30 +++ 0.18.1-Release-Notes.md | 14 +- Release-Notes.md | 444 ---------------------------------------- 9 files changed, 439 insertions(+), 446 deletions(-) create mode 100644 0.17.0-Release-Notes.md create mode 100644 0.17.1-Release-Notes.md create mode 100644 0.17.2-Release-Notes.md create mode 100644 0.17.3-Release-Notes.md create mode 100644 0.17.5-Release-Notes.md create mode 100644 0.17.7-Release-Notes.md create mode 100644 0.18.0-Release-Notes.md diff --git a/0.17.0-Release-Notes.md b/0.17.0-Release-Notes.md new file mode 100644 index 0000000..ed8271a --- /dev/null +++ b/0.17.0-Release-Notes.md @@ -0,0 +1,108 @@ +This release contains a number of new features that will break existing code. + +### New ListOf Classes + +> Change `SequenceOf` to `ListOf` for property definitions and values + +The object class definitions started out being generated from the ASN.1 +descriptions of objects in Annex C which has since been deleted. That notation +used forms like this: +``` + active-vt-sessions [5] SEQUENCE OF BACnetVTSession OPTIONAL, +``` +which were translated into BACpypes definitions like this: +``` + OptionalProperty('activeVtSessions', SequenceOf(VTSession)) +``` +But the standard changed to definitions like this (and no longer in an Annex): +``` + Active_VT_Sessions BACnetLIST of BACnetVTSession +``` +So BACpypes now uses definitions like this: +``` + OptionalProperty('activeVtSessions', ListOf(VTSession)) +``` + +### New RouterInfoCache + +> No change to BACpypes applications unless `NetworkServiceAccessPoint` has been subclassed + +The network service layer consisting of `NetworkAdapter`, `NetworkServiceAccessPoint`, +and the `NetworkServiceElement` had no mechanism for a BACpypes application to +provide the address of a router, all of the path information it gathered by +inspecting upstream packets. It also did not suspend application layer requests +to try and find a path, it simply broadcast the request, which is incorrect. + +There is a new `RouterInfoCache` class that can be subclassed and provided to +the network layer and it is similar to the `DeviceInfoCache` at the application +layer. A well-known set of functions are called for finding out routing paths +for downstream packets and updating paths for upstream packets. + +There is a queue of APDU's waiting path discovery in `pending_nets`. There is +(currently) no signal back to the application when the discovery process times +out. + +### LocalDeviceObject moved + +The LocalDeviceObject is used to create a `DeviceObject` in an application that +automatically returns the system date and time when the `localDate` and `localTime` +properties are read. This class was in the `bacpypes.service.device` module +and it has been moved to the new `bacpypes.local.device` module. + +BACpypes applications must change from this: +``` +from bacpypes.service.device import LocalDeviceObject +``` +to this: +``` +from bacpypes.local.device import LocalDeviceObject +``` + +Similarly, the `CurrentPropertyList` class that was in the `bacpypes.service.object` +module is now in the `bacpypes.local.object` module because it belongs with +local implementations of objects. + +### Local File Objects Moved + +The `LocalRecordAccessFileObject` and `LocalStreamAccessFileObject` classes +have moved to the `bacpypes.local.file` module. + +### New LocalScheduleObject Class + +There is an implementation of a `LocalScheduleObject` in the `bacpypes.local.sched` +module. It includes a companion class, an "interpreter" that is a task that +keeps the present value current. It does not support writing to or overriding +objects outside of the local device context. + +### Automatic Protocol Services Supported + +All of the sample applications that have a full stack had code that computed +the protocol services supported and set that in the device object. +``` + # get the services supported + services_supported = this_application.get_services_supported() + if _debug: _log.debug(" - services_supported: %r", services_supported) + + # let the device object know + this_device.protocolServicesSupported = services_supported.value +``` +This functionality has been rolled into the `LocalDeviceObject` so this code +must be removed. + +### Traffic Log + +There is a new `traffic_log` attribute in the VLAN networking that can reference +a function to call to log each of the PDUs that the network will process. This +was added to make debugging tests easier. + +### Sample Applications + +All of the sample applications have been updated with the changes listed above. + +There is a new `LocalScheduleObject.py` sample application that tests for +specific dates and times in a variety of schedule objects. The sample schedules +could be used for additional, more detailed, and better coverage tests. + +The `ReadWriteProperty.py` sample application has a funky interpreter for making +sure values being written can be coerced into appropriate values. + diff --git a/0.17.1-Release-Notes.md b/0.17.1-Release-Notes.md new file mode 100644 index 0000000..d4f80d6 --- /dev/null +++ b/0.17.1-Release-Notes.md @@ -0,0 +1,73 @@ +### Simplified Configuration of Local Device Object + +The number and types of optional parameters to the DeviceObject that could be +defined in keyword arguments or in an INI file was driving me crazy. There +is a new simple way that is reflected in the sample applications where +you can go from this: +``` + # 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), + ) +``` +to this: +``` + this_device = LocalDeviceObject(ini=args.ini) + if _debug: _log.debug(" - this_device: %r", this_device) +``` + +### Device Information Cache + +The expectations of the DeviceInfoCache have changed to make it closer to what +would be expected if it had a database backend. + +* the `get_device_info()` function no longer returns a mocked up DeviceInfo + record if one doesn't exist + +* there are new `acquire()` and `release()` functions that signal when a + DeviceInfo record is being used by a state machine. + +* a new `device_info_class` parameter is used when constructing new DeviceInfo + objects so both the DeviceInfoCache and DeviceInfo can be subclassed. + +### Segmented APDUs + +The segmentation state machine classes have been significantly worked over to +respect the APCI header fields and is no longer as tightly dependant on the +device information cache. + +### APDU Retry Count Fixed + +The retry count is now correct, it was a vicious off-by-one error. + +### Foreign Device Communications + +The restrictions on what can be sent and received by an unregistered foreign +device have been relaxed. + +### Unrecognized Services + +The recept of a request for an unrecognized service is now rejected. + +### Other Minor Changes + +The functions for encoding and decoding the maximum segments accepted and +the maximum APDU length accepted have changed to more accurately reflect +unknown or unspecified values. To carry the correct sematics into the +client and server segmentation state machines the `apduMaxSegs` and `apduMaxResp` +fields in the APCI are now the values in the PDU rather than the encoded/decoded +versions. + +The task manager now executes tasks that were scheduled for the same time +in the same order they were scheduled. When *A* and *B* are both scheduled +at time _t_, it was the case that *B* could be executed before *A* and it +made unit tests harder than necessary. + +In the `bacpypes.vlan` module, `IPNetworks` can be given a name which can +help with debugging test traffic through `IPRouterNode` objects. + + diff --git a/0.17.2-Release-Notes.md b/0.17.2-Release-Notes.md new file mode 100644 index 0000000..c580752 --- /dev/null +++ b/0.17.2-Release-Notes.md @@ -0,0 +1,8 @@ +There is a bug in the `NetworkServiceElement` when it is responding to a +`WhoIsRouterToNetwork` the router will respond requests from a directly +connected, even when those requests were on the same adapter. For example, +a router between network 1 and 2 would respond as a router to network 1 for +requests like "who is router to network 1" from devices on network 1, which +is an error. + + diff --git a/0.17.3-Release-Notes.md b/0.17.3-Release-Notes.md new file mode 100644 index 0000000..dd7eccd --- /dev/null +++ b/0.17.3-Release-Notes.md @@ -0,0 +1,33 @@ +This release cleans up lots of loose ends, most of the effort has been +in the COV subscription/notification code. + +### COV Server Notifications Fail + +When a COV initiates a subscription request which is acknowlegded by the +server the server is suppoed to immediately send out a notification to the +client with the current values of the monitored properties. This was +inadvertantly omitted from the service processing. + +The real story is in the changes to the state_machine and time_machine to +make it easier to build tests for this issue and to start the process of +testing the rest of the algorithms for the different point types. There +are a lot of point types and it's going to take a whlie to write tests for +all of them, but at least there is some existing code to copy/paste the +test steps. + +And it's easier to start with running code! + +### Communications Switch + +There is a new class in the `bacpypes.comm` module for "switching" components +in and out of the stack, both at the top, in the middle and at the bottom. +This is in response to being able to start the application in one mode (like +a simple BACnet/IP node) and be able to switch to being a foreign device or +a BBMD. + +### Routing Loopback Reappears + +The problem I thought I fixed in 0.17.2 persisted, there is a spurious +`IAmRouterToNetwork` message going out every once in a while that I finally +hunted down. + diff --git a/0.17.5-Release-Notes.md b/0.17.5-Release-Notes.md new file mode 100644 index 0000000..12eaf91 --- /dev/null +++ b/0.17.5-Release-Notes.md @@ -0,0 +1,73 @@ +### Object Identifier Strings + +The `ObjectIdentifier` can now be given a string in the form **type:instance** +where **type** is a name like **analogInput** or an unsigned integer, and +**instance** is an unsigned integer. This is a quite simple change except +**_all the sample applications have been updated to use the new syntax_**. +For example, the `ReadProperty.py` sample application took commands like this: +``` +> read 123:45 analogInput 67 presentValue +``` +It now takes commands like this: +``` +> read 123:45 analogInput:67 presentValue +``` + +### What-Is-Network-Number/Network-Number-Is + +The network layer nows supports these two relatively new NPDUs for discovering +the local topology. When a Network Service Access Point is bound to a network +stack (like a BACnet/IP BVLL stack or a VLAN node) and the network number is +`None` it can be learned. The adapater object has an additional attribute +that matches the 'flag' in the Network-Number-Is, zero (0) is learned and one +(1) is configured. + +Note that there is a chance that the local adapter learns the network number +to which it is connected and the `adapter.adapterNet` will seem to mysteriously +change from `None` to a network number. Applications should not rely on +`nsap.adapters[None]` always referencing the local adapter, +use `nsap.local_adapter` instead. The `WhoIsRouter.py` sample application +has been updated to reflect this change. + +As it stands now, you cannot build a router between two completely unknown +networks, you have to have at least one of them known. This limitation might +be lifted in the future. + +You can use the new `what_is_network_number()` function to ask about all the +networks you don't know about, or pass it an adapter to learn about a +specific downstream connection. You can pass it an additional optional +destination for a unicast request. + +Similarly, the new `network_number_is()` function sends out local broadcast +messages about configured networks (and routers should call this function +at startup). If a specific adapter parameter is given, it will send out a +local broadcast about a "learned" network. + +### I-Am-Router-To-Network Helper + +There is a new `i_am_router_to_network()` function (and routers should call +this function at startup) which announces its network topology information. + +### COV Period + +The `covPeriod` property is now supported for the `PulseConverterObject`. + +### Fixed Size Arrays + +There is now support for fixed length arrays. The `ArrayOf()` function, +which returns a class that is a subclass of `Array`, now has two additional +parameters, a `fixed_length` with constrains the array to a specific number +of elements and a `prototype` for initializing array elements. + +The simplest example is an `ArrayOf(Integer, fixed_length=3)` which is just +what it looks like. The `PriorityArray` is a little more interesting because +each element of the array is a `PriorityValue` which is a `Choice`. So in that +case, since the array elements cannot be `None`, the prototype is cloned into +new array elements. + +The `prototype` parameter is also used for variable length arrays, so when the +array is extended (by increasing the length, writing to array index zero which +are BACnet array semantics) the additional elements are deep copies of the +prototype. + + diff --git a/0.17.7-Release-Notes.md b/0.17.7-Release-Notes.md new file mode 100644 index 0000000..384a7ed --- /dev/null +++ b/0.17.7-Release-Notes.md @@ -0,0 +1,102 @@ +There is a new way of handling strange topology problems, a `settings` module +for gathering information from the environment in a more generic way, the +network layer and router information cache has been overhauled, and lots of +other smaller improvements along with additional sample applications. + +### Route Aware Addresses + +Using remote station address like "10:20" implies that the router to network 10 +can be found by doing a local broadcast Who-Is-Router-To-Network. Occassionally +there are times when the client is not _really_ on the BACnet network, just +lurking nearby. Unicast messages work fine because servers respond to +the address that sent the request. + +This *route aware* address format is extends the usual format with an additional +suffix, **net:addr@route** where **route** is the address of the router to +network **net**. For example, sending a request from 192.168.0.12 to +"10:20@10.168.0.15" bypasses the request to look for the router to network 10 +and simply sends it on as a unicast message to 10.168.0.15. When the reply from +the device is received by the router, the DNET/DLEN/DADR will have the source +network in it and the router will assume that 192.168.0.12 is an acceptable +address. + +At the application layer of the client, the address will be presented with the +address of router, which is normally abstracted away in the network layer. In +this case the network topology information in the network layer is not updated. + +To use this format the **route_aware** setting must be set, from the +environmental variable BACPYPES\_ROUTE\_AWARE or from some other configuration +information. + +### Settings + +There is a new `settings` module that contains the debug and route_aware +settings for applications. When applications start up they can provide +their own initialization information from the built-in `os` module, or can +come from other sources like an INI or JSON file. + +To make the settings names and the environmental variable names more consistent +with each other the BACPYPES\_DEBUG\_FILE, BACPYPES\_MAX\_BYTES, and +BACPYPES\_BACKUP\_COUNT have been renamed with underscores. + +To take advantage of this new set of configuration options, there is a new +`JSONArgumentParser` argument parser that mirrors the existing +`ConfigArgumentParser` but uses a `--json` parameter rather than an `--ini` +parameter. JSON files can contain much richer content than INI files. + +### Commandable (#224) + +In the `bacpypes.local.object` module there are now "commandable" classes +that implement the side effects of writing to a priority array. Some of the +possible classes like `BinaryLightingOutputCmdObject` and `ChannelCmdObject` +still need implementations. + +### Router Info Cache (#213) + +The routing information cache which contains the relationship between local +station addresses and the reachable networks through a router has been +significantly changed. It's a small data structure change from a dictionary of +path information to a cross reference of routers and networks. + +The `NetworkServiceElement` now has a startup function that builds a list of +reachable networks for each adapter and calls `i_am_router_to_network()` to +send them out. + +The function `add_router_references()` changed to `update_router_references()` + +For some reason lots in the sands of time, the `BIPNetworkApplication` passed +a *true* for `noBroacast` which means that applications that were for browsing +around a network couldn't receive I-Am-Router-To-Network broadcasts. This has +been changed. + +### Other Issues + +Issue (#286) supports disabling COV for specific objects. + +Issue (#283) fixes a bug handles socket error bindings. + +Issue (#273) skips the propertyList property returning all properties for +a ReadPropertyMultiple request. + +Support Python3.7 using the same Python3.4 code base until "bacpypes3" is +released. The new library will be based on async/await for Python3.6+ and will +require Python3.7+ and websockets for BACnet/SC which requires TLS 1.3. + +### Sample Applications + +* **mini_device.py** is an application that supports many core services that + applications need to present data on a BACnet network. It supports Who-Is + and I-Am for device binding, Read and Write Property, Read and Write + Property Multiple, and COV subscriptions. + +* **OpenWeatherServer.py** is an application that uses the + https://openweathermap.org/ service to get weather data and make it available + over BACnet. + +* **WhoIsIAmVLAN.py** is a router from BACnet/IP to a VLAN with devices that + support Who-Is and I-Am. + +* **RecurringWriteProperty.py** application demonstrates writing a series of + values at a regular interval. + + diff --git a/0.18.0-Release-Notes.md b/0.18.0-Release-Notes.md new file mode 100644 index 0000000..f7b9675 --- /dev/null +++ b/0.18.0-Release-Notes.md @@ -0,0 +1,30 @@ +### Python 3.8 + +Python3.8 is now listed as a supported version because there has been some +success with it. Work continues on a **bacpypes3** replacement that is based +on async/await but it has not been released yet. + +### Module Updates + +* **app** - add additional "guard" so that applications have to provide an IOCB + when making confirmed service requests. +* **appservice** - fixe a segmentation bug with the initial sequence number. +* **basetypes** - floating and integer scales. +* **core** - stop supressing output. +* **object** - fixed length arrays for event message properties +* **service/cov** - fix an array encoding bug + +### HTTP Server Sample + +This sample application has been updated to work on Python3+ that moved the +locations of various libraries. + +### Read Property Redis Sample + +In the sandbox there is a sample application that reads a list of points and +saves them in a [Redis](https://redis.io/) key-value store and also publishes +the value to a [Redis Stream](https://redis.io/topics/streams-intro). This +sample application has a JSON file for settings. + +Redis streams are an excellent alternative to [Apache Kafka](https://kafka.apache.org/). + diff --git a/0.18.1-Release-Notes.md b/0.18.1-Release-Notes.md index 75b01c5..adc3961 100644 --- a/0.18.1-Release-Notes.md +++ b/0.18.1-Release-Notes.md @@ -1,3 +1,13 @@ -# 0.18.1 Release Notes - This is placeholder text. + +- added a check installation script +- (#325) +- (#295) +- (#330) +- (#327) +- (#323) +- (#307) +- additional auto-discover application +- additional local schedule object application +- updated tests + diff --git a/Release-Notes.md b/Release-Notes.md index 564f526..3cbb9c5 100644 --- a/Release-Notes.md +++ b/Release-Notes.md @@ -1,447 +1,3 @@ # Release Notes -## 0.18.0 - -### Python 3.8 - -Python3.8 is now listed as a supported version because there has been some -success with it. Work continues on a **bacpypes3** replacement that is based -on async/await but it has not been released yet. - -### Module Updates - -* **app** - add additional "guard" so that applications have to provide an IOCB - when making confirmed service requests. -* **appservice** - fixe a segmentation bug with the initial sequence number. -* **basetypes** - floating and integer scales. -* **core** - stop supressing output. -* **object** - fixed length arrays for event message properties -* **service/cov** - fix an array encoding bug - -### HTTP Server Sample - -This sample application has been updated to work on Python3+ that moved the -locations of various libraries. - -### Read Property Redis Sample - -In the sandbox there is a sample application that reads a list of points and -saves them in a [Redis](https://redis.io/) key-value store and also publishes -the value to a [Redis Stream](https://redis.io/topics/streams-intro). This -sample application has a JSON file for settings. - -Redis streams are an excellent alternative to [Apache Kafka](https://kafka.apache.org/). - -## 0.17.7 - -There is a new way of handling strange topology problems, a `settings` module -for gathering information from the environment in a more generic way, the -network layer and router information cache has been overhauled, and lots of -other smaller improvements along with additional sample applications. - -### Route Aware Addresses - -Using remote station address like "10:20" implies that the router to network 10 -can be found by doing a local broadcast Who-Is-Router-To-Network. Occassionally -there are times when the client is not _really_ on the BACnet network, just -lurking nearby. Unicast messages work fine because servers respond to -the address that sent the request. - -This *route aware* address format is extends the usual format with an additional -suffix, **net:addr@route** where **route** is the address of the router to -network **net**. For example, sending a request from 192.168.0.12 to -"10:20@10.168.0.15" bypasses the request to look for the router to network 10 -and simply sends it on as a unicast message to 10.168.0.15. When the reply from -the device is received by the router, the DNET/DLEN/DADR will have the source -network in it and the router will assume that 192.168.0.12 is an acceptable -address. - -At the application layer of the client, the address will be presented with the -address of router, which is normally abstracted away in the network layer. In -this case the network topology information in the network layer is not updated. - -To use this format the **route_aware** setting must be set, from the -environmental variable BACPYPES\_ROUTE\_AWARE or from some other configuration -information. - -### Settings - -There is a new `settings` module that contains the debug and route_aware -settings for applications. When applications start up they can provide -their own initialization information from the built-in `os` module, or can -come from other sources like an INI or JSON file. - -To make the settings names and the environmental variable names more consistent -with each other the BACPYPES\_DEBUG\_FILE, BACPYPES\_MAX\_BYTES, and -BACPYPES\_BACKUP\_COUNT have been renamed with underscores. - -To take advantage of this new set of configuration options, there is a new -`JSONArgumentParser` argument parser that mirrors the existing -`ConfigArgumentParser` but uses a `--json` parameter rather than an `--ini` -parameter. JSON files can contain much richer content than INI files. - -### Commandable (#224) - -In the `bacpypes.local.object` module there are now "commandable" classes -that implement the side effects of writing to a priority array. Some of the -possible classes like `BinaryLightingOutputCmdObject` and `ChannelCmdObject` -still need implementations. - -### Router Info Cache (#213) - -The routing information cache which contains the relationship between local -station addresses and the reachable networks through a router has been -significantly changed. It's a small data structure change from a dictionary of -path information to a cross reference of routers and networks. - -The `NetworkServiceElement` now has a startup function that builds a list of -reachable networks for each adapter and calls `i_am_router_to_network()` to -send them out. - -The function `add_router_references()` changed to `update_router_references()` - -For some reason lots in the sands of time, the `BIPNetworkApplication` passed -a *true* for `noBroacast` which means that applications that were for browsing -around a network couldn't receive I-Am-Router-To-Network broadcasts. This has -been changed. - -### Other Issues - -Issue (#286) supports disabling COV for specific objects. - -Issue (#283) fixes a bug handles socket error bindings. - -Issue (#273) skips the propertyList property returning all properties for -a ReadPropertyMultiple request. - -Support Python3.7 using the same Python3.4 code base until "bacpypes3" is -released. The new library will be based on async/await for Python3.6+ and will -require Python3.7+ and websockets for BACnet/SC which requires TLS 1.3. - -### Sample Applications - -* **mini_device.py** is an application that supports many core services that - applications need to present data on a BACnet network. It supports Who-Is - and I-Am for device binding, Read and Write Property, Read and Write - Property Multiple, and COV subscriptions. - -* **OpenWeatherServer.py** is an application that uses the - https://openweathermap.org/ service to get weather data and make it available - over BACnet. - -* **WhoIsIAmVLAN.py** is a router from BACnet/IP to a VLAN with devices that - support Who-Is and I-Am. - -* **RecurringWriteProperty.py** application demonstrates writing a series of - values at a regular interval. - -## 0.17.6 - -Placeholder. - -## 0.17.5 - -### Object Identifier Strings - -The `ObjectIdentifier` can now be given a string in the form **type:instance** -where **type** is a name like **analogInput** or an unsigned integer, and -**instance** is an unsigned integer. This is a quite simple change except -**_all the sample applications have been updated to use the new syntax_**. -For example, the `ReadProperty.py` sample application took commands like this: -``` -> read 123:45 analogInput 67 presentValue -``` -It now takes commands like this: -``` -> read 123:45 analogInput:67 presentValue -``` - -### What-Is-Network-Number/Network-Number-Is - -The network layer nows supports these two relatively new NPDUs for discovering -the local topology. When a Network Service Access Point is bound to a network -stack (like a BACnet/IP BVLL stack or a VLAN node) and the network number is -`None` it can be learned. The adapater object has an additional attribute -that matches the 'flag' in the Network-Number-Is, zero (0) is learned and one -(1) is configured. - -Note that there is a chance that the local adapter learns the network number -to which it is connected and the `adapter.adapterNet` will seem to mysteriously -change from `None` to a network number. Applications should not rely on -`nsap.adapters[None]` always referencing the local adapter, -use `nsap.local_adapter` instead. The `WhoIsRouter.py` sample application -has been updated to reflect this change. - -As it stands now, you cannot build a router between two completely unknown -networks, you have to have at least one of them known. This limitation might -be lifted in the future. - -You can use the new `what_is_network_number()` function to ask about all the -networks you don't know about, or pass it an adapter to learn about a -specific downstream connection. You can pass it an additional optional -destination for a unicast request. - -Similarly, the new `network_number_is()` function sends out local broadcast -messages about configured networks (and routers should call this function -at startup). If a specific adapter parameter is given, it will send out a -local broadcast about a "learned" network. - -### I-Am-Router-To-Network Helper - -There is a new `i_am_router_to_network()` function (and routers should call -this function at startup) which announces its network topology information. - -### COV Period - -The `covPeriod` property is now supported for the `PulseConverterObject`. - -### Fixed Size Arrays - -There is now support for fixed length arrays. The `ArrayOf()` function, -which returns a class that is a subclass of `Array`, now has two additional -parameters, a `fixed_length` with constrains the array to a specific number -of elements and a `prototype` for initializing array elements. - -The simplest example is an `ArrayOf(Integer, fixed_length=3)` which is just -what it looks like. The `PriorityArray` is a little more interesting because -each element of the array is a `PriorityValue` which is a `Choice`. So in that -case, since the array elements cannot be `None`, the prototype is cloned into -new array elements. - -The `prototype` parameter is also used for variable length arrays, so when the -array is extended (by increasing the length, writing to array index zero which -are BACnet array semantics) the additional elements are deep copies of the -prototype. - -## 0.17.4 - -This section unintentionally left blank. - -## 0.17.3 - -This release cleans up lots of loose ends, most of the effort has been -in the COV subscription/notification code. - -### COV Server Notifications Fail - -When a COV initiates a subscription request which is acknowlegded by the -server the server is suppoed to immediately send out a notification to the -client with the current values of the monitored properties. This was -inadvertantly omitted from the service processing. - -The real story is in the changes to the state_machine and time_machine to -make it easier to build tests for this issue and to start the process of -testing the rest of the algorithms for the different point types. There -are a lot of point types and it's going to take a whlie to write tests for -all of them, but at least there is some existing code to copy/paste the -test steps. - -And it's easier to start with running code! - -### Communications Switch - -There is a new class in the `bacpypes.comm` module for "switching" components -in and out of the stack, both at the top, in the middle and at the bottom. -This is in response to being able to start the application in one mode (like -a simple BACnet/IP node) and be able to switch to being a foreign device or -a BBMD. - -### Routing Loopback Reappears - -The problem I thought I fixed in 0.17.2 persisted, there is a spurious -`IAmRouterToNetwork` message going out every once in a while that I finally -hunted down. - -## 0.17.2 - -There is a bug in the `NetworkServiceElement` when it is responding to a -`WhoIsRouterToNetwork` the router will respond requests from a directly -connected, even when those requests were on the same adapter. For example, -a router between network 1 and 2 would respond as a router to network 1 for -requests like "who is router to network 1" from devices on network 1, which -is an error. - -## 0.17.1 - -### Simplified Configuration of Local Device Object - -The number and types of optional parameters to the DeviceObject that could be -defined in keyword arguments or in an INI file was driving me crazy. There -is a new simple way that is reflected in the sample applications where -you can go from this: -``` - # 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), - ) -``` -to this: -``` - this_device = LocalDeviceObject(ini=args.ini) - if _debug: _log.debug(" - this_device: %r", this_device) -``` - -### Device Information Cache - -The expectations of the DeviceInfoCache have changed to make it closer to what -would be expected if it had a database backend. - -* the `get_device_info()` function no longer returns a mocked up DeviceInfo - record if one doesn't exist - -* there are new `acquire()` and `release()` functions that signal when a - DeviceInfo record is being used by a state machine. - -* a new `device_info_class` parameter is used when constructing new DeviceInfo - objects so both the DeviceInfoCache and DeviceInfo can be subclassed. - -### Segmented APDUs - -The segmentation state machine classes have been significantly worked over to -respect the APCI header fields and is no longer as tightly dependant on the -device information cache. - -### APDU Retry Count Fixed - -The retry count is now correct, it was a vicious off-by-one error. - -### Foreign Device Communications - -The restrictions on what can be sent and received by an unregistered foreign -device have been relaxed. - -### Unrecognized Services - -The recept of a request for an unrecognized service is now rejected. - -### Other Minor Changes - -The functions for encoding and decoding the maximum segments accepted and -the maximum APDU length accepted have changed to more accurately reflect -unknown or unspecified values. To carry the correct sematics into the -client and server segmentation state machines the `apduMaxSegs` and `apduMaxResp` -fields in the APCI are now the values in the PDU rather than the encoded/decoded -versions. - -The task manager now executes tasks that were scheduled for the same time -in the same order they were scheduled. When *A* and *B* are both scheduled -at time _t_, it was the case that *B* could be executed before *A* and it -made unit tests harder than necessary. - -In the `bacpypes.vlan` module, `IPNetworks` can be given a name which can -help with debugging test traffic through `IPRouterNode` objects. - -## 0.17.0 - -This release contains a number of new features that will break existing code. - -### New ListOf Classes - -> Change `SequenceOf` to `ListOf` for property definitions and values - -The object class definitions started out being generated from the ASN.1 -descriptions of objects in Annex C which has since been deleted. That notation -used forms like this: -``` - active-vt-sessions [5] SEQUENCE OF BACnetVTSession OPTIONAL, -``` -which were translated into BACpypes definitions like this: -``` - OptionalProperty('activeVtSessions', SequenceOf(VTSession)) -``` -But the standard changed to definitions like this (and no longer in an Annex): -``` - Active_VT_Sessions BACnetLIST of BACnetVTSession -``` -So BACpypes now uses definitions like this: -``` - OptionalProperty('activeVtSessions', ListOf(VTSession)) -``` - -### New RouterInfoCache - -> No change to BACpypes applications unless `NetworkServiceAccessPoint` has been subclassed - -The network service layer consisting of `NetworkAdapter`, `NetworkServiceAccessPoint`, -and the `NetworkServiceElement` had no mechanism for a BACpypes application to -provide the address of a router, all of the path information it gathered by -inspecting upstream packets. It also did not suspend application layer requests -to try and find a path, it simply broadcast the request, which is incorrect. - -There is a new `RouterInfoCache` class that can be subclassed and provided to -the network layer and it is similar to the `DeviceInfoCache` at the application -layer. A well-known set of functions are called for finding out routing paths -for downstream packets and updating paths for upstream packets. - -There is a queue of APDU's waiting path discovery in `pending_nets`. There is -(currently) no signal back to the application when the discovery process times -out. - -### LocalDeviceObject moved - -The LocalDeviceObject is used to create a `DeviceObject` in an application that -automatically returns the system date and time when the `localDate` and `localTime` -properties are read. This class was in the `bacpypes.service.device` module -and it has been moved to the new `bacpypes.local.device` module. - -BACpypes applications must change from this: -``` -from bacpypes.service.device import LocalDeviceObject -``` -to this: -``` -from bacpypes.local.device import LocalDeviceObject -``` - -Similarly, the `CurrentPropertyList` class that was in the `bacpypes.service.object` -module is now in the `bacpypes.local.object` module because it belongs with -local implementations of objects. - -### Local File Objects Moved - -The `LocalRecordAccessFileObject` and `LocalStreamAccessFileObject` classes -have moved to the `bacpypes.local.file` module. - -### New LocalScheduleObject Class - -There is an implementation of a `LocalScheduleObject` in the `bacpypes.local.sched` -module. It includes a companion class, an "interpreter" that is a task that -keeps the present value current. It does not support writing to or overriding -objects outside of the local device context. - -### Automatic Protocol Services Supported - -All of the sample applications that have a full stack had code that computed -the protocol services supported and set that in the device object. -``` - # get the services supported - services_supported = this_application.get_services_supported() - if _debug: _log.debug(" - services_supported: %r", services_supported) - - # let the device object know - this_device.protocolServicesSupported = services_supported.value -``` -This functionality has been rolled into the `LocalDeviceObject` so this code -must be removed. - -### Traffic Log - -There is a new `traffic_log` attribute in the VLAN networking that can reference -a function to call to log each of the PDUs that the network will process. This -was added to make debugging tests easier. - -### Sample Applications - -All of the sample applications have been updated with the changes listed above. - -There is a new `LocalScheduleObject.py` sample application that tests for -specific dates and times in a variety of schedule objects. The sample schedules -could be used for additional, more detailed, and better coverage tests. - -The `ReadWriteProperty.py` sample application has a funky interpreter for making -sure values being written can be coerced into appropriate values.