1
0
mirror of https://github.com/JoelBender/bacpypes synced 2025-09-28 22:15:23 +08:00

split out the release notes

Joel Bender 2020-04-22 19:02:34 -04:00
parent b7427b1ae8
commit 44a8023718
9 changed files with 439 additions and 446 deletions

108
0.17.0-Release-Notes.md Normal file

@ -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.

73
0.17.1-Release-Notes.md Normal file

@ -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.

8
0.17.2-Release-Notes.md Normal file

@ -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.

33
0.17.3-Release-Notes.md Normal file

@ -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.

73
0.17.5-Release-Notes.md Normal file

@ -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.

102
0.17.7-Release-Notes.md Normal file

@ -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.

30
0.18.0-Release-Notes.md Normal file

@ -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/).

@ -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

@ -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.