I have a task where I need to understand the technical feasibility to setup a remote monitoring scenario for a HVAC solution which uses Bacnet/IP. I need to setup a .NET client that gets the telemetry and sends it to Azure IoT Hub. My current concern is to understand how can I connect to a Bacnet/IP network.
I don't have that much information information about the hardware installed besides the fact that it has sensors for pressure and humidity on the network and a DDC controller (EBCON - Delta Controls). As I was told, I don't need to care about the actually sensors since they are sending the telemetry to the controller, so I only to care about the controller and connect to it.
Yet based on what I have read so far, I have some doubts about this information, but I don't have the technical knowledge to support it. It seems that based on the information that I have read Bacnet communication is done by UDP listening on a port (which seems to go against the above information that I need to connect to a controller), if this is true and I listen on a UDP port, will all devices broadcast the telemetry on the network and I only need to be listening? What is the controller role then? Can I ignore it?
Any explanation or pointers can could help me understand this from a programmer PoV would be appreciated.
BACnet does indeed communicate via UDP. The scenario you describe, while possible, is quite a dangerous approach. Very few BACnet products offer any sort of BACnet protocol security, so to make a secure connection you will need to VPN into your site. Once on the VPN, then the VPN itself will most likely block broadcasts, so you will need to use BACnet "Foreign Device Registration" to connect. However most VPNs do a NAT translation too, so the BACnet server on site will have to supply "BACnet BBMD with FD with NAT" support. Quite rare. An alternative is to get a box on your site supplying connectivity from the site to the Azure IoT site. There are a few companies that offer this type of product, but it seems you want to program your own. This will not be trivial, and then you will have to do the "BACnet Object" to "whatever-data-format-you-need-on-Azure" mapping, which will need a rather deep understanding of the BACnet specification, which, on paper, is about 2.5 inches thick. You could ignore the VPN approach, port forward port 47808 (BACnet default, but it can be different per site config) to the controller. This is how some rather large companies have had their HVAC systems hacked. If you do pursue this approach, you will still need a BACNet Client-to-Azure mapping/transfer agent. You have not chosen a trivial project here. ;) Or you could purchase an off-the-shelf product (box) that does this all already.
And just by the way, there is a FOSS C# BACnet Client you can use for reference: https://sourceforge.net/projects/yetanotherbacnetexplorer/
For the benefit of others, if not also for yourself; there is the more BACnet-ty aspect of your question that I don't think has been addressed.
You have to be a bit more proactive with BACnet - you might have the presence of new devices (or at least devices that have just come online again) broadcast to you, but otherwise you have to actively read all the properties (/telemetry) values - at least the ones of interest.
There is the facility for subscribing for CoV (Change of Value) changes/values but at least in the past (if still not now) the concern was that this could flood the network, as well as possibly burden the device in having to keep sending updates to possibly many clients or just too-too often (above & beyond its primary job of monitoring & controlling the building for comfort and health & safety).
The standard does provide an 'object list' (upon 'device'-type objects), and a 'property list' upon every object, but you'll probably find that the 'property-list' is never supported/implemented despite it been a mandatory property (!?!).
So this is where you have to take an interest in every physical device - at least it's IP address & possibly MAC address too, along with all it's (relevant) objects & object-properties, for which you'll most likely have to sit with one/two/more engineers first to agree & understand as to what information that will actively be exposed (for you to monitor) & how (- e.g. the measurement units that a value is conveyed in).
In some cases (- e.g. maybe for small buildings), you might have to talk to all the devices individually, but in other cases you'll have points (/point 'object's) upon a gateway device that will represent all the devices that sit behind it.
So all in all, whether you direct to up to say 300 devices, or you interrogate 300 objects upon a gateway device - each one representing a physical device, you still might have a few properties of interest that you're interested in - under the guise of your telemetry, so 300 x 3 (for example), it adds up quite quickly, and then there's the error handling and complexity of the standard as a whole (- an uphill learning curve / you have to buy-in to understanding the foundations at least).
I'd recommend you also take a look at the (advanced & free) VTS (Visual Test Shell) tool.
Not sure if this helps but it was worth pointing out; underestimate BACnet at your own peril (!!). ;)
Related
I have been reading up on the web and cannot find any information on working with a RS485 MultiDrop connection in c#
To give a bit of insight. I have written an application to communicate with a Serial device using the MODBUS RTU protocol. Now the client has informed me there devices may be hooked up using multidrop communications links. Being a novice when it comes to working with serial devices I am a bit lost here.
My question is simply: Where do I start? a Google search has thus far only produced hardware converters and wikipedia entries for different Serial Communication standards.
Thanks!
RS485 is a standard that defines the electrical characteristics of a particular multi-drop networking arrangement. I once used it as the internal bus for an instrument - the main control board drove various pumps which were arranged on an RS485 network.
You can get half-duplex and full duplex arrangements (half means that one device can talk at a time - full means send and receive can happen at the same time).
Really using it is not a whole lot different from using an RS232 or serial port, and as you've seen you can get serial to RS485 converters. You can use the serial port drivers in C# to use it.
SerialPort Class
Your main problem is that RS485 doesn't really address how it should be used - its a fairly low level electrical spec, it doesn't define how you should use it to make communication happen.
The main issue you need to consider is how you're going to coordinate all this. With RS232 - there are two things connected, which makes it easy - usually a computer and some device. With RS485, there are many things connected. So you need some way of addressing each device. You don't give any details about the 'device' referred to here - but if they are intended to be connected on RS485 - then there will be a way of addressing them. There are however several ways this could work - so I can't help you on specifics without more detail. With the system I developed, all communication was initiated by the 'master' device (i.e. my control board - or your c# application for example) and each message sent had the receiver's address on it - so the right pump knew that the instruction was intended for it.
I hope this is of some help. Really its not that complicated, but you need to think about what these devices do, how they are addressed, and think about the messages that you need to send back and forth. You can use the C# SerialPort classes to actually do the work.
The book referred to in the other answer looks great by the way. I really would consider buying it if this is all new to you. It covers serial port communications, and has a chapter on RS485.
I have not worked with RS485 but this book can be a help in understanding Serial port and USBs.
here is another link which discuss specs and here is another. I dont think they will be readily implemented in C# but could be.
Hi have a VB6 Windows application (old.exe) and a separate C# Winforms application (new.exe). They both run on the same Windows machine.
I have access to both the VB6 and the C# source code, but the apps need to remain separate.
If both are running and have knowledge of each other (process Id), what's the best way to send a message from one window to the other?
Update:
In this case, I'm only talking about very infrequent and small messages - e.g. change the tab you're looking at using a small message like, "Invoice 67"
Bi-directional messaging would be great, but VB6 to .Net is the most important.
Neither of the two prior answers consider the fact that this may be a multi-tentant environment or even span you domain. As you move into distributed systems you shold consider messaging as opposed to inter-process communication, which over time will limit scalability.
For on-premise solutions consider MSMQ, there is a multitude of documentation out there, demonstrating the simplicity of this messaging infrastructure.
for broader scenarios, you should consider Windows Azure Storage Queues, you get an almost identical usability, but with a broader accessibility and improved management tools.
MSMQ is domain-specific, by Azure spans the globe.
Agreed with Clay's comments.
However, I'll take a stab in the dark and go with the most obvious answer:
.NET (w/ WCF) supports both IPC and Named Pipes for local intra-process communications.
Here's a link on the topic using named pipes... but it's super old, and doesn't use WCF like it should... but the point is the same: http://www.switchonthecode.com/tutorials/interprocess-communication-using-named-pipes-in-csharp Updated version using WCF: http://www.switchonthecode.com/tutorials/wcf-tutorial-basic-interprocess-communication
Here is a more-or-less complete list of IPC alternatives for Windows.
http://msdn.microsoft.com/en-us/library/aa365574%28v=vs.85%29.aspx
Most of them can be utilized from VB6 and C# as well.
The solution that I have used for this very purpose is to have TCP communications between the processes. It allows for bidirectional communication. And as a bonus, should you ever move one of the applications to a different box, your apps will continue functioning with very little changes.
In .NET, you can use a plethora of classes for this purpose (ton of stuff from low-level to high-level in System.Net). In VB6, you could go with the Winsock control that ships with the IDE. I use Dart Winsock control (costs $$$), just because it is so much more flexible.
I set up both apps to send/receive XML fragments with a known schema. There is typically an attribute that tells the other app the type of message being received, along with the payload.
A basic solution (based on the info provided):
Create a dedicated folder for incoming and outgoing messages (the one applications incoming folder will be the others outgoing folder)
Write messages (or data) into text/xml or other format to the output folder (adding a Source field so the application knows where its from)
Read the messages, based on date, and import messages/data
This allows integration to/from any application.
The Ultimate Answer To This Question
VIRTUAL NULL MODEM:
http://en.wikipedia.org/wiki/Null_modem#Virtual_null_modem
From Wikipedia:
A virtual null modem is a
communication method to connect two
computer applications directly using a
virtual serial port. Unlike a null
modem cable, a virtual null modem is a
software solution which emulates a
hardware null modem within the
computer. All features of a hardware
null modem are available in a virtual
null modem as well. There are some
advantages to this:
Higher transmission speed of serial data (limited by computer performance
only). Virtual connection over network or Internet is possible, mitigating cable
length restrictions.
An unlimited number of virtual connections is possible.
No serial cable is needed.
The computer's physical serial ports remain free.
For instance, DOSBox has allowed older
DOS games to use virtual null modems.
Another common example consists of
unix pseudo terminals (pty) which
present a standard tty interface to
user applications, including virtual
serial controls. Two such ptys may
easily be linked together by an
application to form a virtual null
modem communication path.
With the HIGHLIGHT of this solution being: IT REQUIRES NO CABLES!!!
*Note; This is an attempt at humor. Forgive me if it's not funny.
We are looking to design a security application that does the following on laptops:
If the ethernet adapter is used (cable plugged in) disable/block all other network connections (wireless WIFI, mobile broadband (PPP), virtual VPN adapters etc)
When ethernet adapter is not being used again, all connections allowed.
Does anyone have any good suggestion on how to accomplish this?
We have looked in the WMI a lot but there are no good ways of doing this. Only disabling the network connection is not secure enough because most mobile broadband applications try to re-establish the connection. This should be an application that works on all laptop vendors without any user interaction (such as choosing interfaces etc..).
So any suggestions on how to accomplish this would be much appreciated.
The simplest method for doing this is by disabling the adapter. You say this won't work for you, but I suspect it will. You can detect if something tries to re-enable it and act appropriately.
If that isn't going to work for you, then the next easiest thing to do is to remove the device itself. I believe you will need to used some unmanaged calls to get this done. There is some sample code on codeproject.com that will point you in the right direction.
Keep in mind, if the user runs a check for devices, it will show up again. You can monitor for DBT_DEVICEARRIVAL to detect when this happens, and again act appropriately.
You might also try simply disabling the device. Usually though I have seen that when you disable a network connection, this is exactly what it does. It might depend on the card and OS. I haven't experimented with it.
I suggest you reconsider simply disabling the network interface rather than going to the device level. It is a much cleaner way of doing this, and you can always detect if the interface comes back up. Anything else you do is going to be a bit hackish.
The only other method I can think of would be to block traffic using the Windows Firewall API. Just keep in mind that not all network traffic is over IP.
Well, this might not be the optimal solution but... You could use the route command to disable the interfaces ability to reach any network. It will probably require a lot of tweaking and constant monitoring of the routing table, but would effectively prevent the interfaces ability to communicate with any other device.
There are different ways of doing this. As stated by others in this question it needs to be done on a lower level than what the WMI allows. There are some C++ examples around that addresses this issue. Check out the library NETCONLib by Microsoft.
I have a .NET 3.5 server application that usually has about 8 clients. I'm using System.Net.Sockets for all the networking.
I've been told that if a client is running on the same box, it should use localhost:<port> or 127.0.0.1:<port> instead of the machine's ip or name for better performance. Several people at work have said that this skips some layers of the tcp stack.
But I'm not able to see any performance difference at all in testing (timing how long it takes to get a ping packet from server to client using System.Diagnostics.Stopwatch).
Should there really be better performance in theory?
No, performance is same in both cases. If you are using your local device ip address, your operating system kernel don't transport your packets data to your network device and this data don't be was sended anywhere then you don't have any ISO layers calculations (encapsulation, decapsulation etc).
I belive the OS will see this is a local device and you treat it like it was 127.0.0.1. So in fact both will have the same effect.
I suppose it's possible that there will be an extremely tiny performance boost in using 127.0.0.1 (though I doubt it), but with 8 clients you'll never notice it. That performance difference would have to be aggregate over A LOT of traffic to become at all noticeable.
The larger concern would be which value is better from a maintenance perspective. If the application is always looking at localhost for external dependencies, it won't do well if run on another host. But if it's looking for a more universally understood address for those dependencies, it'll find them from anywhere on the network.
I'm thinking like the methods games like Counter Sstrike, WoW etc uses. In CS you often have just like 50 ping, is there any way to send information to an online MySQL database at that speed?
Currently I'm using an online PHP script which my program requests, but this is really slow, because the program first has to send headers and post-information to it, and then retrieve the result as an ordinary webpage.
There really have to be any easier, faster way of doing this? I've heard about TCP/IP, is this what I should use here? Is it possible for it to connect to the database in a faster way than indirectly via the PHP script?
TCP/IP is made up of three protocols:
TCP
UDP
ICMP
ICMP is what you are using when you ping another computer on a network.
Games, like CounterStrike, don't care about what you previously did. So there's no requirement for completeness, to be able to reconstruct what you did (which is why competitors have to tape what they are doing). This is what UDP is used for - there's no guarantee that data is delivered or received. Which is why lag can be such a problem - you're already dead, you just didn't know it.
TCP guarantees that data is sent and received. Slower than UDP.
There are numerous things to be aware of to have a fast connection - less hops, etc.
Client-to-server for latency-critical stuff? Use non-blocking UDP.
For reliable stuff that can be a little slower, if you use TCP make sure you do so in a non-blocking fashion (select(), non-blocking send, etc.).
The big reason to use UDP is if you have time-sensitive data - if the position of a critter gets dropped, you're better off ignoring it and sending the next position packet rather than re-sending the last one.
And I don't think any high-performance game has each and every call resolve to a call to the database. It's more common to (if a database is even used) persist data occasionally, or at important events.
You're not going to implement Counterstrike or anything similar on top of http.
Most games like the ones you cite use UDP for this (one of the TCP/IP suite of protocols.) UDP is chosen over TCP for this application since it's lighter weight allowing for better performance and TCP's reliability features aren't necessary.
Keep in mind though, those games have standalone clients and servers usually written in C or C++. If your application is browser-based and you're trying to do this over HTTP then use a long-lived connection and strip back the headers as much as possible, including cookies. The Tornado framework may be of interest to you there. You may also want to look into HTML5 WebSockets however widespread support is still a fair way off.
If you are targeting a browser-based plugin like Flash, Java, SilverLight then you may be able to use UDP but I don't know enough about those platforms to confirm.
Edit:
Also worth mentioning: once your networking code and protocol is sufficiently optimized there are still things you can do to improve the experience for players with high pings.