Skip to content
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

No way to address specific deviceId #48

Open
djok opened this issue Aug 11, 2017 · 17 comments
Open

No way to address specific deviceId #48

djok opened this issue Aug 11, 2017 · 17 comments

Comments

@djok
Copy link

djok commented Aug 11, 2017

First, great work.

Currently read and write functions do addressing by IP, but there is a case when one IP address is a gateway to many deviceIds.

Sample whoIs output:
address: 10.10.10.100 - deviceId: 1603003 - maxAdpu: 1476 - segmentation: 3 - vendorId: 16
address: 10.10.10.100 - deviceId: 1603017 - maxAdpu: 1476 - segmentation: 3 - vendorId: 16
address: 10.10.10.100 - deviceId: 1603006 - maxAdpu: 1476 - segmentation: 3 - vendorId: 16
address: 10.10.10.100 - deviceId: 1603004 - maxAdpu: 1476 - segmentation: 3 - vendorId: 16
address: 10.10.10.100 - deviceId: 1603005 - maxAdpu: 1476 - segmentation: 3 - vendorId: 16
address: 10.10.10.100 - deviceId: 1603010 - maxAdpu: 1476 - segmentation: 3 - vendorId: 16
address: 10.10.10.100 - deviceId: 1603007 - maxAdpu: 1476 - segmentation: 3 - vendorId: 16

In this case there is no way to address specific deviceId for read/write operation.

Is there solution for this case?

vbr,

@fh1ch
Copy link
Owner

fh1ch commented Aug 12, 2017

Hi @djok

First, great work.

Thank you very much 😊

Am I right with the assumption that you're using BACNET BBMD routing in your network? This is an extension in the BACNET NPDU layer to send telegrams into another BACNET network via router. The special thing is that WhoIs/IAm telegrams are transparently forwarded to all subnets transparently (client doesn't have to implement anything) while all other services have to implement routing explicitly.

Node BACstack currently doesn't support routing as the implementation in the NPDU layer isn't finished yet and also exposing the network and device selection isn't exposed into the client API. I have currently also no setup to verify the implementation of this feature.

Does this info already help you? Would you be interested in testing a possible implementation of this feature?

Cheers

@ryanluton
Copy link

@fh1ch I would be happy to assist in the testing of this. I also might be able to set up a remote bbmd address for you to hit with some controllers behind it. Would be happy to chat more on the subject outside of github comments.

@fh1ch
Copy link
Owner

fh1ch commented Oct 19, 2017

@ryanluton awesome, thank you very much for this offer, I really appreciate this 👍

I sadly haven't found time lately to push this topic further, but should be able to come up with more progress in this topic in around a month.


Would be happy to chat more on the subject outside of github comments.

Sure, do you have a proposal regarding the format? Would Something like a Gitter channel for this project make sense?

@scottc385
Copy link

@fh1ch @ryanluton I ran into the same whois issue and I think I fixed one problem.

The whois function calls baNpdu.encode() with 'address' and address is expected to be a an object in the form of: { adr: 'xxx.xxx.xxx.xxx', net:0xffff }. However, the whois function later calls transport.send() with address and address is expected to be an ip address string.

I changed the call to transport.send() to pass address.adr and I pass an address object into the whois function. This allowed me to specify the bacnet network ID and find all of the devices on the subnet.

There seems to be an incomplete design regarding addresses. In some places it just wants the ip address string. In other place it wants an object that contains the ip address, bacnet address and (maybe) the deviceID.

I am no bacnet expert, but I would be happy to help with the development. But before I go messing things up, I would like understand the intent of the design. Let me know if you are interested in some help.

Scott

@fh1ch
Copy link
Owner

fh1ch commented Dec 27, 2017

Hi @scottc385

Thanks for your input.

Yes, I'm aware of this problem, since the issue you describing was implemented somewhat on purpose, since didn't really have a use-case for BBMD routing, but still liked to have the NPDU layer as complete as possible and leave room for future implementation of it (still haven't found the time tough 😄). Therefore, yes the design and implementation is indeed incomplete.

I would be more than happy to get some help on this topic, one doesn't have to be a BACNET expert at all. Especially if you have a network with BACNET routing at your hands (for verification purpose), it would be awesome to get some support. 👍

Cheers

@fh1ch fh1ch self-assigned this Dec 27, 2017
@shortyishere
Copy link

Hi fh1ch

I am somewhat a bacnet expert and have multiple ip routable devices at hand and would love to test and help with this and also am a somewhat programmer. Can we start doing this?

@NateZimmer
Copy link

I'm going to take a stab at implementing this for this is some vital functionality. The library is fairly well written for this expansion. I've been able to get read/write/whois working with IP + deviceId addressing. However, fixing segmentation is going take a bit of work. Hopefully on completion the author may have a bit of time to merge it back in.

@shortyishere
Copy link

shortyishere commented Jan 14, 2019 via email

@NateZimmer
Copy link

@shortyishere if you could test my release once I send it out, that would be cool. Right now i'm trying to muddle my way through the release & testing of this repo for i'm not amazing with node.

Regarding segmentation, some companies use it fairly frequently. Segmentation is fairly simple to implement and it allows one to send & assemble large packets. For example, an object list(77) or all properties(8) could be a rather large packet and segmentation makes transmitting those packets feasible. Library wise, in this case, its just a bit more to implement.

@shortyishere
Copy link

shortyishere commented Jan 15, 2019 via email

@shortyishere
Copy link

Also yes some do and some do not at all...it depends how big a network is..and what you are moving around. I can see cases for each segmentation type.

@NateZimmer
Copy link

NateZimmer commented Jan 15, 2019

Going to be awhile before I can try to pull it in & clean it up.
Source: https://github.com/NateZimmer/node-bacstack/
NPM: https://www.npmjs.com/package/natezimmer_bacstack

Basically address/ip can either be a string: e.g. '192.168.0.23' or an object {ip:'192.168.0.23', net:2001, adr: [5]}. Only use the object in the MSTP/router cases and specify an ip, net and adr. Note, adr is not required for whois.

First try to do whoIs to see if you can find your new devices:

 client.whoIs({'address':{'net':0xFFFF,'ip':'255.255.255.255'}});

Note, sometimes devices are picky and want an address like: 192.168.0.255 <-- where only last 3 are 255.

Here is a readProperty example:

client.readProperty( {'ip':'192.168.1.166','net':2000,'adr':[9]} , {type: 8, instance: 532663}, 85, (err, value) => {
  console.log('value: ', value);
});

I tested this for whois, rp, rpm, wp, and wpm. Also should work with segmentation.

@adam-nielsen
Copy link

I'm a bit late to this discussion, but I've almost finished a more functional BBMD support which I think will address this issue.

The problem is that you cannot have multiple BACnet device IDs on the same IP address, on the same port. The example in the first post above is when talking to a BBMD (BACnet proxy server) and in this case each response comes back as a "forwarded NPDU", which includes the remote IP address of the node that owns that IP address (which is currently ignored by this library). So technically the device IDs are not on the same IP address, as you have the unique remote IP address for each device ID, along with the IP of the proxy server you need to communicate with in order to access those remote nodes.

So when you want to address one of those IDs, you send the packet to the BBMD's IP address, but you send it as a FORWARDED_NPDU with the target node's IP address you found from your original whoIs request. The BBMD then forwards the packet on to the IP address you specified.

For example:

  • Send: whoIs
  • Recv: 1.1.1.1 iAm device 222 forwarded from 2.2.2.2
  • Recv: 1.1.1.1 iAm device 333 forwarded from 3.3.3.3
  • Send: readProperty to 1.1.1.1 ask to forward to 2.2.2.2 (message will go to device 222)
  • Send: readProperty to 1.1.1.1 ask to forward to 3.3.3.3 (message will go to device 333)

Unfortunately I didn't end up using the code from @NateZimmer as I didn't realise that I was working toward the same goal until after I had finished! However my focus was more on creating a BACnet server rather than a client. It does look like we went about the issue in a similar way, by changing the IP address so that it is no longer a string but rather an object. However I had to do things like modify the iAmResponse function to take an address parameter, as you need to be able to send that message to a BBMD if you are responding to a remote node's whoIs - you can't just reply with a broadcast like normal.

I don't have any devices that use segmentation that I can find, so I will have a look at the code from @NateZimmer to see what I have to do to get that working, as I've omitted that for the moment.

The code in question is in the master branch in my fork if anyone is interested: https://github.com/adam-nielsen/node-bacstack

@SamuelToh
Copy link

I managed to get some results off @adam-nielsen 's work.
Great job guys.

@NateZimmer I'm a bacnet 1 day old newbie. Care to enlighten me what is this array adr for?

@Apollon77
Copy link

These changes should also be incorporated int https://github.com/BiancoRoyal/node-bacstack, please try this package and open issues at https://github.com/BiancoRoyal/node-bacstack/issues if it does not work as expected

@NubeDev
Copy link

NubeDev commented Jun 3, 2020

I managed to get some results off @adam-nielsen 's work.
Great job guys.

@NateZimmer I'm a bacnet 1 day old newbie. Care to enlighten me what is this array adr for?

MAC address – On MS/TP networks, this is the eight bit address used to identify devices on a single RS-485 subnet.
More info here http://www.bacnet.org/Bibliography/ES-1-97/ES-1-97.htm

Code example for that works on this branch through an IP ro MS/TP router
https://github.com/BiancoRoyal/node-bacstack

bacnetClient.whoIs({'net':3});
// read a point through a router to an MSTP device
bacnetClient.readProperty({address: '192.168.15.137',net:3,adr:[6]} , {type: 1, instance: 1}, 85, (err, value) => {
  console.log('value: ', value);
  console.log('err: ', err);
});

@heidimao
Copy link

heidimao commented Oct 4, 2023

Hello,
We also have similar issue that we need to specify address, net and maxSegments, maxApdu to work with some vendors.
We use @NateZimmer's fork successfully, thanks.
Is there any plan to implement this feature in the near future?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests