-
Notifications
You must be signed in to change notification settings - Fork 98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for BBMD messages and COV pushing #127
base: master
Are you sure you want to change the base?
Conversation
Added a few improvements, squashed commits, sync with master branch |
9de615d
to
fb082a0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@adam-nielsen a big thanks for those awesome contributions and sorry, that it took a while to start the review 💯 🎉
I still haven't managed to review all the code and will continue during the next days and will also do some testing against real devices. I might also cherry-pick the commits, which are unrelated to the BBMD part but are already good to go, into master.
@@ -13,7 +13,7 @@ describe('bacstack - BVLC layer', () => { | |||
len: 4, | |||
func: 10, | |||
msgLength: 1482, | |||
forwardedFrom: null, | |||
originatingIP: null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the reason for the rename here? In the case of null
, this seems to be semantically wrong (no forwardedFrom
-> message not forwarded).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found it confusing when you are generating a new packet and you have to specify forwardedFrom
as your own (device) IP address, when you aren't the one forwarding it (the BBMD is).
If you are writing a BBMD, you find the sender's IP in the forwardedFrom
when you haven't forwarded it yet, which is also confusing to me.
I still use forwardedFrom
where it makes sense, in client.js
when you have received a packet from a BBMD.
If you have any other suggestions for a name let me know, but anything with "forwarded" in it can be misleading in my opinion.
@@ -704,19 +704,19 @@ class Client extends EventEmitter { | |||
* } | |||
* ); | |||
*/ | |||
confirmedCOVNotification(address, monitoredObject, subscribeId, initiatingDeviceId, lifetime, values, options, next) { | |||
confirmedCOVNotification(receiver, monitoredObject, subscribeId, initiatingDeviceId, lifetime, values, options, next) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the rename here?
- Using
receiver
seems a bit too generic to me (how to address a receiver?). - The parameter for addressing devices should be in-line trough-out all client functions and not only change for a single one.
- The change should be reflected in the JSDoc comment above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was simply for consistency. I found address
confusing when working with BBMD code (is it your address, the sender's address, or the recipient's address?) so I used 'receiver' as this word was already used by other functions (e.g. readPropertyResponse
). You are welcome to use a different word but the important part is that they are all the same (better not to mix address
and receiver
as exists in the current master
branch.)
I am not sure what you mean by the parameter being in-line, as this change makes receiver
behave the same for all functions, and it can be a string as before.
@@ -3,6 +3,7 @@ | |||
// Util Modules | |||
const EventEmitter = require('events').EventEmitter; | |||
const debug = require('debug')('bacstack'); | |||
debug.trace = require('debug')('bacstack:trace'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be a global variable. Please stick to debug
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to have two different types of debugging messages, because the trace
ones are very verbose. By doing it this way you can choose to hide the bacstack:trace
messages, so you only see the more important bacstack
debug messages. For example, like this:
DEBUG='*,-bacstack:trace' node index.js
If these are all changed to be only bacstack
then it becomes difficult to see important messages as they are lost amongst the trace.
In my environment the trace
messages are extremely useful to ensure firewall rules are working and when debugging why messages are being ignored, but once the code is working there are pages of them every few seconds so they need to be disabled in order to view the normal debug messages.
I am happy to do this another way, but I think it is very important to have the two different levels of messages so that one can be disabled while leaving the other active.
* ); | ||
* console.log(s); // "PRESENT_VALUE(85)" | ||
*/ | ||
module.exports.getEnumName = function(group, value) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The enum file should only contain type definitions and no utility functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where would you suggest putting the utility function? I had it in client.js
originally but since it's only related to enums I thought enum.js
would be a better fit.
I am using enum.js
in another module so it is nice that I can get the enum utility function without including any additional node-bacstack code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually this is part of PR #134 instead, so if you want to resolve this issue over there then I can rebase this one to pick up the fix.
lib/npdu.js
Outdated
@@ -2,6 +2,7 @@ | |||
|
|||
const baEnum = require('./enum'); | |||
|
|||
const DEFAULT_HOP_COUNT = 255; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The BACNET Standard (135-2016 - 6.2.3) defines the default value as 0xFF
, as it was before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My mistake, will fix this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one is also part of PR #134 so I will apply the fix over there. If you are happy to merge that one then I will rebase this one to pick up the changes.
lib/bvlc.js
Outdated
originatingIP = buffer.slice(4, 8).join('.'); | ||
|
||
// Only add the port if it's not the usual one. | ||
if (port != DefaultBACnetPort) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be !==
… device BREAKING CHANGE: whoIs and other functions now require a destination address, but it can be null to broadcast as before BREAKING CHANGE: addresses are no longer strings but are now objects, so that they can contain both the target IP and the remote node behind a BBMD
Many thanks for your review, and apologies for my own delayed reply, as I have been away for a few weeks. I've pushed some changes and left comments explaining my reasoning for others, so I hope this helps. Feel free to cherry-pick or edit as necessary. I tried to structure the PRs so that you can merge the other non-BBMD ones (e.g. #128 and #134) without too much hassle, so hopefully you won't need to cherry pick these ones. Both #128 and #134 are included here, as I based the BBMD patch on top of those two. |
This is great! @adam-nielsen would you mind updating this on top of the latest master? |
I believe it has already been merged into the fork at https://github.com/BiancoRoyal/node-bacstack along with a bunch of other fixes, as this one appears to be abandoned now. So I'd probably suggest trying that one first. |
Checklist
What does this Pull Request do
This adds support for a couple of BACnet messages useful when implementing a client device. It allows the device to appear as a BBMD (sort of a BACnet proxy server), which is useful for some systems (such as Johnson Controls Metasys) which can only talk to BBMD proxies and cannot talk to remote BACnet devices directly.
It also adds the ability to send COV notifications. A remote BACnet system can already subscribe to a data element provided by a device based on this library, however without this addition there is no way to make use of this subscription to push updates to the remote system as they occur.