mirror of
https://github.com/JoelBender/bacpypes
synced 2025-09-28 22:15:23 +08:00
split out the release notes
parent
b7427b1ae8
commit
44a8023718
108
0.17.0-Release-Notes.md
Normal file
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
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
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
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
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
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
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
|
||||
|
||||
|
|
444
Release-Notes.md
444
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.
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user