ela-compil / bacnet Goto Github PK
View Code? Open in Web Editor NEWBACnet protocol library for .NET :satellite:
Home Page: https://www.nuget.org/packages/bacnet/
License: MIT License
BACnet protocol library for .NET :satellite:
Home Page: https://www.nuget.org/packages/bacnet/
License: MIT License
It would be a good solution to have a Net Standard version of the SDK. I think the only problem will be with serial port. One nice solution would be to have a base DLL compiled with Net Standard, and a Net 4.0 DLL based on that solution, adding the Serial Port MSTP implementation.
It could allow the Bacnet IP implementation on Linux, Mac, Xamarin, etc.
Are VMAC addresses up to length 6 currently supported? It does not currently seem to be the case based on looking at the BacnetAddress class. The devices we need to talk to which have VMACs of length 6 are going through a Siemens bacnet router. Is there a recommended way to use this library for these types of devices?
Happy to help provide support where I can.
I got an exception unhandled when I was trying to write a value to multi-state-value. It say "System.Exception: 'Error from device: ERROR_CLASS_PROPERTY - ERROR_CODE_INVALID_DATA_TYPE'"
Here is my code.
uint bacnetinstaid = Convert.ToUInt32(changemode.Bacnet_Instance_ID); int bacnetid = Convert.ToInt32(changemode.Bacnet_Instance_ID); WriteScalarValue(deviceid, new BacnetObjectId(BacnetObjectTypes.OBJECT_MULTI_STATE_VALUE, bacnetinstaid), BacnetPropertyIds.PROP_PRESENT_VALUE,new BacnetValue(2) );
What am I doing wrong here? also what does invalid data type mean?
I use BACnet package with dotnet core 2.2 and the code works fine with linux-arm runtime, my code (F#) is quite simple
let bacnetClient = new BacnetClient(new BacnetIpUdpProtocolTransport(0xBAC0, false))
bacnetClient.Start()
However, it always runs on eth0, I want it to run on eth1 (an usb-lan adapter), is there a way to do so? Thanks
Hi,
I'm getting a exception, probably caused by segmentation.
there is a timeline for the implementation of segmentation ?
System.Transactions Critical: 0 : http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/UnhandledUnhandled exceptionBacnetConsoleApp.exeSystem.NotSupportedException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089Specified method is not supported. at System.IO.BACnet.BacnetTransportBase.set_MaxInfoFrames(Byte value)
at System.IO.BACnet.BacnetClient.<>c__DisplayClass270_0.<HandleSegmentationResponse>b__0(Object o)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()System.NotSupportedException: Specified method is not supported.
at System.IO.BACnet.BacnetTransportBase.set_MaxInfoFrames(Byte value)
at System.IO.BACnet.BacnetClient.<>c__DisplayClass270_0.<HandleSegmentationResponse>b__0(Object o)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
Hello I tried to create a bacnetAdress with MSTP protocol but there are bacnetAdress only for IP and Ethernet , any idea?
public BacnetAddress(BacnetAddressTypes addressType, string address = null, ushort network = 0)
: this(addressType, network)
{
if (address == null)
return;
switch (type)
{
case BacnetAddressTypes.IP:
adr = new byte[6];
var addressParts = address.Split(':');
var addressBytes = IPAddress.Parse(addressParts[0]).GetAddressBytes();
Array.Copy(addressBytes, adr, addressBytes.Length);
var portBytes = BitConverter.GetBytes(addressParts.Length > 1
? ushort.Parse(addressParts[1])
: (ushort)0xBAC0);
if (BitConverter.IsLittleEndian)
portBytes = portBytes.Reverse().ToArray();
Array.Copy(portBytes, 0, adr, addressBytes.Length, portBytes.Length);
break;
case BacnetAddressTypes.Ethernet:
adr = PhysicalAddress.Parse(address).GetAddressBytes();
break;
default:
throw new NotSupportedException("String format is not supported for address type " + type);
}
}
I'm able to read properties and values from the object list without issue until I try to read the priority array.
Code below and screenshot of console output attached.
public BacnetDevice ReadDeviceProperties(BacnetDevice objDevice)
{
Bacnet_client.ReadPropertyRequest(objDevice.Address, new BacnetObjectId(BacnetObjectTypes.OBJECT_DEVICE, objDevice.InstanceId), BacnetPropertyIds.PROP_OBJECT_LIST, out IList<BacnetValue> value_list);
LinkedList<BacnetObjectId> object_list = new LinkedList<BacnetObjectId>();
StringBuilder strOut = new StringBuilder();
foreach (BacnetValue value in value_list)
{
if (Enum.IsDefined(typeof(BacnetObjectTypes), ((BacnetObjectId)value.Value).Type))
object_list.AddLast((BacnetObjectId)value.Value);
}
foreach (BacnetObjectId object_id in object_list)
{
//read all properties
IList<BacnetValue> values = null;
IList<BacnetValue> priority = null;
IList<BacnetValue> names = null;
bool listProps = true;
try
{
if (!Bacnet_client.ReadPropertyRequest(objDevice.Address, object_id, BacnetPropertyIds.PROP_OBJECT_NAME, out names))
{
}
if (!Bacnet_client.ReadPropertyRequest(objDevice.Address, object_id, BacnetPropertyIds.PROP_PRESENT_VALUE, out values))
{
}
strOut.AppendLine("Device id:" + objDevice.InstanceId + " Property Name:" + names[0] + " Value:" + values[0]);
if (!Bacnet_client.ReadPropertyRequest(objDevice.Address, object_id, BacnetPropertyIds.PROP_PRIORITY_ARRAY, out priority))
{
}
if (listProps)
foreach (BacnetValue v in priority)
{
strOut.AppendLine("Priority: " + v);
}
continue;
}
catch (Exception ex)
{
strOut.AppendLine("Exception:" + ex.Message);
//perhaps the 'present value' is non existing - ignore
continue;
}
}
Console.Write(strOut.ToString());
return objDevice;
}
Hi,
I am using this library.
When I use it as: BacnetIpUdpProtocolTransport udp_transport = new BacnetIpUdpProtocolTransport(c_bacnetPort,false) it works perfect but the problem is that I have 2 network cards on my PC and sometimes it sends the data through the wrong card.
I tried: BacnetIpUdpProtocolTransport udp_transport = new BacnetIpUdpProtocolTransport(c_bacnetPort,false,false,1472,bacnet_IP); here the data is sent on the specified card (mentioned in bacnet_IP) however it is reserving the network card (i am not able to launch the BacShark to check the result, I can see it via the yabe application, but I have to use BACShark...).
c_bacnetPort is always equal to 47808
bacnet_IP is the IP of my PC, let's say "10.110.45.20"
the other network card IP is: 2.1.1.1
Any help to get out of this please ?
Thank you
Rony
We have BACnet implemented in a .NET core application running in Docker.
BACnet runs on port 47808 on the host machine. So when I want to discover devices I use the IP of the host machine. But when I do that, it returns an error. When I check the IP and port with NMap (from within the Docker container), it shows that the port is available with service "BACnet" behind it.`
I recieve the following error:
{
"ClassName": "System.Net.Sockets.SocketException",
"Message": "Cannot assign requested address",
"Data": null,
"InnerException": null,
"HelpURL": null,
"StackTraceString": " at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, String callerName)\n at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)\n at System.Net.Sockets.Socket.Bind(EndPoint localEP)\n at System.IO.BACnet.BacnetIpUdpProtocolTransport.Open()\n at System.IO.BACnet.BacnetIpUdpProtocolTransport.Start()\n at System.IO.BACnet.BacnetClient.Start()\n at AgentCore.Services.BACnetDiscoveryService.Discover() in /app/AgentCore/Services/BACnetDiscoveryService.cs:line 41\n at AgentApi.Controllers.DevicesController.Get() in /app/AgentApi/Controllers/DevicesController.cs:line 30",
"RemoteStackTraceString": null,
"RemoteStackIndex": 0,
"ExceptionMethod": null,
"HResult": -2147467259,
"Source": "System.Net.Sockets",
"WatsonBuckets": null,
"NativeErrorCode": 99
}
Can someone enlighten me and point me in the right direction? Or is it just not possible with the library to use another ipaddress than 0.0.0.0?
I created a console app that runs from a docker container.
I have 2 bacnet gateways, one that doesn't require useExclusivePort & dontFragment, and it works fine, but the other one does require useExclusivePort & dontFragment to be set to true, and I keep getting the error "No response within 00:00:01".
I have no idea where to look, any suggestion appreciated!
Hi,
Each time I run the application i have a new random source port while the destination port is always 47808.
How can I fix the source port ? I need it to be 47808 as well.
Thank you
Hi,
We keep reciving System.ObjectDisposedException that is not caught by try catch for some reason, causing our whole application to crash (as this runs on a separate thread). Looking at the OnReceiveData function, it's pretty much completely wrapped in try catch with should catch it. Except the first line:
"private void OnReceiveData(IAsyncResult asyncResult)
{
var connection = (UdpClient)asyncResult.AsyncState;"
Which from documentation and trying my self to make it throw the exception doesn't seem to be the cause.
We have only got this error from compiled code from a client, and haven't been able to cause/catch it ourselves.
Any idรฉas?
Stacktrace below:
Description: The process was terminated due to an unhandled exception.
Exception Info: System.ObjectDisposedException
at System.Net.Sockets.UdpClient.BeginReceive(System.AsyncCallback, System.Object)
at System.IO.BACnet.BacnetIpUdpProtocolTransport.OnReceiveData(System.IAsyncResult)
at System.Net.LazyAsyncResult.Complete(IntPtr)
at System.Net.ContextAwareResult.CompleteCallback(System.Object)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Net.ContextAwareResult.Complete(IntPtr)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(System.Object, IntPtr)
at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
Hello!
I have bacnet client (192.168.5.80) and bacnet server (192.168.5.81).
Bacnet client sends subscribe COV request with params: SubscribeCOVRequest(..., cancel = false, issueConfirmedNotifications=false, lifetime = 600) one a minute, life time 10 minutes.
After client send 'write property', bacnet server sends response and then many the same unconfirmed messages. Sometimes 5, sometimes 10 or 20, 30.
For client and server i use the same library (BACnet).
Attached wireshark file in zip format.
Test_BacNet.zip
Hi
I am using Bacnet client dll ver 1.1.4.0. Bacnet devices not discovering in yabe and BDT (Bacnet Discovery tool) on different Networks.
It is working for the same networks.
e.g
Please do the needful.
For a couple of devices a try to talk with, I get the following error when using the ReadPropertyRequest function: "Abort from device: 4". I looked the byte up and I saw that it means: Invalid APDU in this state.
Can I adjust this state in the driver?
As mentioned in issue #9, here is my first stab in an attempt to decode the notification values, I used the bacnet-stack C library implementation as a direct conversion. The modification of BacnetPropetyState
causes a breaking change for bacapp_encode_property_state
.
Any help, ideas, suggestions appreciated to take this forward.
Services.cs
/* tag 12 - event values */
switch (eventData.notifyType)
{
case BacnetNotifyTypes.NOTIFY_ALARM:
case BacnetNotifyTypes.NOTIFY_EVENT:
if (ASN1.decode_is_opening_tag_number(buffer, offset + len, 12))
len++;
else
return -1;
if (ASN1.decode_is_opening_tag_number(buffer, offset + len, (byte)eventData.eventType))
len++;
else
return -1;
switch (eventData.eventType)
{
case BacnetEventTypes.EVENT_CHANGE_OF_STATE:
len += ASN1.bacapp_decode_context_property_state(buffer, offset + len, 0, out var changeOfState_newState);
break;
// and many more cases... :(
}
break;
//In cases other than alarm and event
//there's no data, so do not return an error
//but continue normally
case BacnetNotifyTypes.NOTIFY_ACK_NOTIFICATION:
default:
break;
}
ASN1.cs
public static int bacapp_decode_context_property_state(byte[] buffer, int offset, byte tagNumber, out BacnetPropetyState value)
{
int len = 0;
int sectionLength;
value = new BacnetPropetyState();
if (decode_is_opening_tag_number(buffer, offset + len, tagNumber))
{
len++;
sectionLength = bacapp_decode_property_state(buffer, offset + len, out value);
if (sectionLength == -1)
{
len = -1;
}
else
{
len += sectionLength;
if (decode_is_closing_tag_number(buffer, offset + len, tagNumber))
{
len++;
}
else
{
len = -1;
}
}
}
else
{
len = -1;
}
return len;
}
private static int bacapp_decode_property_state(byte[] buffer, int offset, out BacnetPropetyState value)
{
int len = 0;
uint len_value_type;
int section_length;
uint enumValue;
byte tagnum;
value.tag = 0;
value.state = new BacnetPropetyState.State();
section_length = decode_tag_number_and_value(buffer, offset + len, out tagnum, out len_value_type);
if (section_length == -1)
{
return -1;
}
value.tag = 0;
value.tag = (BacnetPropetyState.BacnetPropertyStateTypes)tagnum;
len += section_length;
switch (value.tag)
{
case BacnetPropetyState.BacnetPropertyStateTypes.BOOLEAN_VALUE:
value.state.boolean_value = len_value_type == 1 ? true : false;
break;
case BacnetPropetyState.BacnetPropertyStateTypes.BINARY_VALUE:
section_length = decode_enumerated(buffer, offset + len, len_value_type, out enumValue);
if (section_length == -1)
{
return -1;
}
value.state.binaryValue = (BacnetPropetyState.BACNET_BINARY_PV)enumValue;
break;
case BacnetPropetyState.BacnetPropertyStateTypes.EVENT_TYPE:
section_length = decode_enumerated(buffer, offset + len, len_value_type, out enumValue);
if (section_length == -1)
{
return -1;
}
value.state.eventType = (BacnetEventTypes)enumValue;
break;
case BacnetPropetyState.BacnetPropertyStateTypes.STATE:
section_length = decode_enumerated(buffer, offset + len, len_value_type, out enumValue);
if (section_length == -1)
{
return -1;
}
value.state.state = (BacnetEventStates)enumValue;
break;
case BacnetPropetyState.BacnetPropertyStateTypes.UNSIGNED_VALUE:
section_length = decode_unsigned(buffer, offset + len, len_value_type, out value.state.unsignedValue);
if (section_length == -1)
{
return -1;
}
break;
default:
return -1;
}
len += section_length;
return len;
}
BacnetPropertyState.cs
public struct BacnetPropetyState
{
public enum BacnetPropertyStateTypes
{
BOOLEAN_VALUE,
BINARY_VALUE,
EVENT_TYPE,
POLARITY,
PROGRAM_CHANGE,
PROGRAM_STATE,
REASON_FOR_HALT,
RELIABILITY,
STATE,
SYSTEM_STATUS,
UNITS,
UNSIGNED_VALUE,
LIFE_SAFETY_MODE,
LIFE_SAFETY_STATE
}
public enum BACNET_BINARY_PV
{
MIN_BINARY_PV = 0, /* for validating incoming values */
BINARY_INACTIVE = 0,
BINARY_ACTIVE = 1,
MAX_BINARY_PV = 1, /* for validating incoming values */
BINARY_NULL = 255 /* our homemade way of storing this info */
}
public BacnetPropertyStateTypes tag;
public State state; // !!!BREAKING CHANGE!!!! for encoding bacapp_encode_property_state
public struct State
{
public bool boolean_value;
public BACNET_BINARY_PV binaryValue;
public BacnetEventTypes eventType;
public BacnetEventStates state;
public uint unsignedValue;
}
public override string ToString()
{
return $"{tag}:{state}";
}
}
I tried everything (including setting an event enrollment with a notification class) but cannot figure out how to trigger event notification
bacnet_client.OnEventNotify += new BacnetClient.EventNotificationCallbackHandler(handler_OnEventNotify);
Is this the right way to use it? Any help is greatly appreciated and thanks for this great library!
The Microsoft .Net extension Microsoft.Extensions.Logging seems to be the logical successor to the Common.Logging library. Since the extension is actively being developed in my opinion that is the better (future proof) solution
Hello!
How can I make a query with one command of all the Tag.
Now for each Tag, I call ReadPropertyRequest ().
Hi, I am not so good in BACnet. But here is the problem.
We have a PLC which is trying to subscribe AnalogValue parameters from a Windows service which is based on this library. The problem is that the server decodes an error after bacnetClient.Notify function. The error comes in this function in BacnetClient class:
private void OnRecieve(IBacnetTransport sender, byte[] buffer, int offset, int msgLength, BacnetAddress remoteAddress)
The buffer[] contains the following data:
[0] 129
{1] 10
[2] 0
[3] 13
[4] 1
[5] 0
[6] 80
[7] 1
[8] 1
[9] 145
[10] 5
[11] 145
[12] 7
The offset parameter is 6 which points to 80 => Error
The subscribing works with Yabe.. but not with the PLC because this error.
I have two threads in a same program, each thread is executed every seconds, they call ReadPropertyRequest function.
First thread get a BinaryValue (0 or 1), second thread get an AnalogValue (between 20 and 30).
Sometimes ReadPropertyRequest of BinaryValue return the AnalogValue!
Can someone have a solution of my problem?
PS: i call ReadPropertyRequest because COV does'nt seem to work for me
I didn't see any examples for read/write MSTP devices including the ip address, network number, MAC address, and instance id.
Can you create an example?
Hi
We have configured Windows failover clustered network IP, Bacnet Client API is not discovering in yabe explorer.
Please Suggest any changes to be done in Bacnet client dll.
Please do the needful
Using stable version 1.0.13, I can discover my bacnet server from the controller panel and upload objects. However with the latest version from master branch (at the time of posting this) there seems to be a bug.
I can discover the device (whois, iam packets look fine) but I get the error that the device is offline and cant upload the objects (or communicate with the device). Not sure what might be causing this but just dropping this here so you can investigate.
I will try to provide more details.
I downloaded bacnet.core 1.0.30 version from nuget and wrote simple codes to send whois.
But When I compile the code I faced the error message below.
The type or namespace name 'BACnet' does not exist in the namespace 'System.IO' (are you missing an assembly reference?)
Of course I added the code "using System.IO.BACnet;"
I think it's namespace collision. How do I solve this problem.
on BIP the standard way to handle multiple device objects internal to one physical server device seems to be to have a router and set the source/destination fields appropriately. In particular packets sourced from the device holds a SOURCE field in the NPDU header and coming into the device the DESTINATION field in the NPDU header tells which device to route to (the router device itself reacts to an empty destination and fills in an empty source).
To access messages properly then I need access to the destination field on incoming messages; but I don't seem to have that. F Chaxel added the incoming SOURCE address to the BacnetAddress structure (as the RoutedSource) and I'm proposing you do similar for the incoming DESTINATION address. E.g add a RoutedDestination field in the BacnetAddress structure, and initialize it at the same time the RoutedSource field is initialized. Then I can use the destination address to do the appropriate routing.
Technically speaking there may be further issues with actually sending the source on various messages (e.g. I'm not sure if I can specify a SOURCE for functions like SimpleAck or ComplexAck). But I'm not so worried about that as I can do simple workarounds for those kinds of issues at least in the short term.
It would be really helpful though if you could add something like a RoutedDestination field to the BacnetAddress structure, then I think I would have enough to be able to make a switch to the nuget package.
I am facing issue while connecting and reading Bacnet device objects through BBMD configuration. Though i get response of complex-Ack i am not able to read any object values. Please check the code below what i have used to read the bacnet object and wireshark packet details.
public void ReadBacnetObject()
{
IList<BacnetValue> Value;
BacnetIpUdpProtocolTransport bacnetIpUdpProtocolTransport = new BacnetIpUdpProtocolTransport(0xBAC0, true);
bacnetIpUdpProtocolTransport.Start();
bacnetIpUdpProtocolTransport.Bvlc.AddBBMDPeer(new IPEndPoint(IPAddress.Parse("10.155.60.3"), 47808), IPAddress.Parse("255.255.255.255"));
bacnet_client = new BacnetClient(bacnetIpUdpProtocolTransport);
bacnet_client.OnIam += new BacnetClient.IamHandler(handler_OnIam);
//bacnet_client.RegisterAsForeignDevice("10.155.60.3", 30);
//bacnet_client.RemoteWhoIs("10.155.60.3");
//Thread.Sleep(20);
if (bacnet_client.ReadPropertyRequest(new BacnetAddress(BacnetAddressTypes.IP, "10.155.60.23:47808"), new BacnetObjectId(BacnetObjectTypes.OBJECT_DEVICE, 2000001), BacnetPropertyIds.PROP_OBJECT_LIST, out Value) == false)
{
foreach (var item in Value)
{
Console.WriteLine($"Able to read data {item.Tag} + {item.Value} ");
}
}
}
Kindly request check if anything went wrong?
Hello,
my requirements include reading trend log data starting from a certain point in time onwards. I can't use the ReadRangeRequest()
method as I don't know from which index on I have to read data.
Therefore, I would like to ask if you could provide a method overload of the ReadRangeRequest()
method, taking a DateTime from
parameter? Seems like EncodeReadRange
already supports RR_BY_TIME, so it would basically be necessary to propagate this enum to the method signature.
Furthermore, I'd like to ask if there is any documentation regarding this library available? I've seen some examples, but those do not represent a proper documentation.
Best regards,
Hi @gralin, I have a question to ask you, If the BACnet server is closed, through the BacnetClient object with propertys or events to know that the server has been closed?
With BacnetClient I have used OnEventNotify event, but it seems that it is never called. However, OnUnconfirmedServiceRequest does work.
I have used "AnotherStorageImplementation" example which is sending those events.
I think the problem lies in Serialize\Services.cs DecodeEventNotifyData method.
Create new C# console, install BACnet.Core via NuGet.
Write code, such as:
class Program
{
static void Main(string[] args)
{
BacnetClient client = new BacnetClient();
client.OnIam += Client_OnIam;
client.OnEventNotify += Client_OnEventNotify;
client.OnUnconfirmedServiceRequest += Client_OnUnconfirmedServiceRequest;
client.Start();
Console.ReadLine();
}
private static void Client_OnUnconfirmedServiceRequest(BacnetClient sender, BacnetAddress adr, BacnetPduTypes type, BacnetUnconfirmedServices service, byte[] buffer, int offset, int length)
{
Console.WriteLine("Client_OnUnconfirmedServiceRequest");
}
private static void Client_OnEventNotify(BacnetClient sender, BacnetAddress adr, byte invokeId, BacnetEventNotificationData eventData, bool needConfirm)
{
Console.WriteLine("Client_OnEventNotify");
}
private static void Client_OnIam(BacnetClient sender, BacnetAddress adr, uint deviceId, uint maxAPDU, BacnetSegmentations segmentation, ushort vendorId)
{
Console.WriteLine("Got I am.");
}
}
And now test it with "AnotherStorageImplementation" example.
Client_OnEventNotify is never called.
Edit:
It seems like there is a problem in the part where it is "tag 12 - event values".
ASN1.decode_is_closing_tag_number is false, and then it returns -1.
in my compuer whois return UnicastAddresses 255.255.255.255
and i send the correct who is length is 54 bug it is 50
In the following code it is possible for the event handlers, in my case, it was the OnSimpleAck to be called before the instantiation of the ManualResetEvent.
This results in the possibility of a NullReferenceException, and can be fixed by moving the creation of the ManualResetEvent prior to event registration.
public BacnetAsyncResult(BacnetClient comm, BacnetAddress adr, byte invokeId,
byte[] transmitBuffer, int transmitLength, bool waitForTransmit, TimeSpan transmitTimeout)
{
_transmitTimeout = transmitTimeout;
Address = adr;
_waitForTransmit = waitForTransmit;
_transmitBuffer = transmitBuffer;
_transmitLength = transmitLength;
_comm = comm;
_waitInvokeId = invokeId;
_comm.OnComplexAck += OnComplexAck;
_comm.OnError += OnError;
_comm.OnAbort += OnAbort;
_comm.OnReject += OnReject;
_comm.OnSimpleAck += OnSimpleAck;
_comm.OnSegment += OnSegment;
_waitHandle = new ManualResetEvent(false);
}
Hello, I implemented EventNotificationCallbackHandler and registered it under BacnetClient's OnEventNotify to recieve notifications about alarms, but I nevere recieved one. I know that I should be notified about this event, becouase Yabe is but my app is not. How can I fix this?
Thank you
Hello, first of all thank you for your provide BACnet for C#,I met problem in use process, would you please help me to look at. I use OBJECT_BINARY_VALUE write data happen error: Error from device: ERROR_CLASS_PROPERTY - ERROR_CODE_INVALID_DATA_TYPE, thank you very much!
BacnetObjectId oBacnetObjectId = new BacnetObjectId(); oBacnetObjectId.Type = BacnetObjectTypes.OBJECT_BINARY_VALUE; oBacnetObjectId.Instance = 123456; bool bIsWrite = oBacnetClient.WritePropertyRequest(oBacnetAddress, oBacnetObjectId, BacnetPropertyIds.PROP_PRESENT_VALUE, new List<BacnetValue> { new BacnetValue(true) });
The current code expects a bool to be returned, presumably indicating success, however EndConfirmedNotify in this instance seems to only exit when an exception is thrown.
This results in false always being returned for confirmed notifications.
using (var result = BeginConfirmedNotify(address, subscriberProcessIdentifier, initiatingDeviceIdentifier, monitoredObjectIdentifier, timeRemaining, values, true))
EndConfirmedNotify(result);
return false;
vs.
using (var result = BeginConfirmedNotify(address, subscriberProcessIdentifier, initiatingDeviceIdentifier, monitoredObjectIdentifier, timeRemaining, values, true))
{
// the only way this should not be a success is if an exception is thrown
EndConfirmedNotify(result);
return result.Error != null ? false : true;
}
Hi,
I'm trying to update the value of a Schedule Object but I'm experiencing an issue.
This is the code snippet:
Client.WritePropertyRequest(new BacnetAddress(BacnetAddressTypes.IP, bacnetServer.Url+":"+bacnetServer.Port),
bacnetSchedulerIdentifier, BacnetPropertyIds.PROP_WEEKLY_SCHEDULE, valueWeeklyScheduleList);
the thrown Exception says "I cannot encode this".
Looking at source code it looks like this kind of objects are not managed, am I wrong? Have you ever worked with schedule objects before?
Thanks
I tried to run the RP example with Mono, and with .Net Core 2.2 Both trials return similar message at this line
bacnet_client.Start();
platform not supported exception socket.iocontrol, handles Windows-specific control codes and is not supported on this platform.
I'd like to use Newtonsoft.Json to serialize and then deserialize a List
I can serialize it, but I can't deserialize it. Why doesn't BacnetAddress have a default constructor? Can it? :)
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
---> Newtonsoft.Json.JsonSerializationException: Unable to find a constructor to use for type System.IO.BACnet.BacnetAddress. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path '[0].Address.net', line 1, position 19.
Code worked perfectly with BacNet protocol 6.0
Customer changed device to protocol 7.2, and could not retrieve properties anymore.
Any idea what could be the reason, is the package not supported for 7.2?
A negative integer value of 3 bytes in length (for example -8336180) is incorrectly decoded from BACnet. That values are decoding in C# to an integer type (32 bit), but the highest 8 bits are not set to TRUE. That's necessary to get a negative 2's complement integer value.
Original code in ASN1.cs (starting at line 1176):
public static int decode_signed24(byte[] buffer, int offset, out int value)
{
value = (buffer[offset + 0] << 16) & 0x00ff0000;
value |= (buffer[offset + 1] << 8) & 0x0000ff00;
value |= buffer[offset + 2] & 0x000000ff;
return 3;
}
Modified code that should be work:
public static int decode_signed24(byte[] buffer, int offset, out int value)
{
value = (buffer[offset + 0] << 16) & 0x00ff0000;
if ((value & 0x800000) != 0)
unchecked { value |= (int)0xff000000; }
value |= (buffer[offset + 1] << 8) & 0x0000ff00;
value |= buffer[offset + 2] & 0x000000ff;
return 3;
}
static void StartActivity(int? bacNetServerId, out BacnetClient bacnet_client)
{
var port = Convert.ToInt32(bacNetServerId.ToString());
// Bacnet on UDP/IP/Ethernet
bacnet_client = new BacnetClient(new BacnetIpUdpProtocolTransport(port, false));
try
{
bacnet_client.Start();
// go
// Send WhoIs in order to get back all the Iam responses :
bacnet_client.OnIam += new BacnetClient.IamHandler(handler_OnIam);
bacnet_client.WhoIs();
}
catch(Exception ex)
{
new WebServiceDataAccess().logger.LogError(ex, "StartActivity");
}
}
How to stop this activity?(Start()/WhoIs/WhoIs())
How to dispose bacnet_client object? I am getting port permissions denied error.
In ASN1.cs (@ line 1989):
if (propertyId == BacnetPropertyIds.PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES ||
propertyId == BacnetPropertyIds.PROP_LOG_DEVICE_OBJECT_PROPERTY ||
propertyId == BacnetPropertyIds.PROP_OBJECT_PROPERTY_REFERENCE)
{
tagLen = decode_device_obj_property_ref(buffer, offset, maxOffset, out var v);
if (tagLen < 0) return -1;
value.Tag = BacnetApplicationTags.BACNET_APPLICATION_TAG_OBJECT_PROPERTY_REFERENCE;
value.Value = v;
return tagLen;
}
Would not be BACNET_APPLICATION_TAG_DEVICE_OBJECT_PROPERTY_REFERENCE the right one?
Has anyone been able to successfully read properties from devices on a BACNET IP router?
I am able to read properties of the BACNET router and I can pull the PROP_OBJECT_LIST which returns all the instance ids of the devices on the router. However, when I try to read properties with the instance Ids of the devices from the PROP_OBJECT_LIST I get unknown property errors.
Am I doing something wrong? How do you read from devices attached to bacnet router?
I'm starting to go round in circles with ReadPropertyMultipleRequest
...
My understanding is that I need to pass in a BacnetAddress
and a List<BacnetReadAccessSpecification>
. Each BacnetReadAccessSpecification
has a BacnetObjectId
and a List<BacnetPropertyReference>
. And a BacnetPropertyReference
is a bacnet property ID (a uint
, e.g. 85 for PRESENT_VALUE
) and an array index.
So, as an example, if I wanted to get PROP_PRESENT_VALUE
, PROP_DESCRIPTION
, PROP_UNITS
for some ANALOG_VALUE
of instance 0
I think I should do this:
var adr = new BacnetAddress(BacnetAddressTypes.IP, "192.168.0.123:47808");
var objId = new BacnetObjectId(BacnetObjectTypes.OBJECT_ANALOG_VALUE, 0);
var propRefs = new List<BacnetPropertyReference>();
propRefs.Add(new BacnetPropertyReference(85, 0)); // PROP_PRESENT_VALUE
propRefs.Add(new BacnetPropertyReference(28, 1)); // PROP_DESCRIPTION
propRefs.Add(new BacnetPropertyReference(117, 2)); // PROP_UNITS
var spec = new BacnetReadAccessSpecification(objId, propRefs);
var specs = new List<BacnetReadAccessSpecification>();
specs.Add(spec);
IList<BacnetReadAccessResult> results;
bacnet_client.ReadPropertyMultipleRequest(adr, specs, out results);
This is always giving me an error ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY
. I'm probably interpreting the purpose of the various objects the wrong way.
Can someone help out?
I am trying to write a value to the Room Controller simulator, but am not getting it to work. It returns false all the time.
This is my code:
public bool WriteScalarValue(int deviceId, int typeId, int instanceId, BacnetPropertyIds property, double value)
{
BacnetObjectId bacnetObject = new BacnetObjectId((BacnetObjectTypes)typeId, (uint)instanceId);
BacnetValue bacnetValue = new BacnetValue(Convert.ToSingle(value));
// Looking for the device
Device device = _deviceService.GetByName(deviceId.ToString(), _currentNetwork);
if (device == null)
{
return false; // not found
}
BacnetAddress bacnetAddress = new BacnetAddress(BacnetAddressTypes.IP, device.Ip + ":" + device.Port);
// Property Write
BacnetValue[] NoScalarValue = { bacnetValue };
if (bacnet_client.WritePropertyRequest(bacnetAddress, bacnetObject, property, NoScalarValue) == false)
{
return false;
}
return true;
}
The BacnetObjectId I am trying to write to is OBJECT_ANALOG_VALUE:0, which results in the Setpoint.value property.
Am I missing something?
Hi,
When I use a trend log object and I try to read the data I'm getting weekday errors. In wireshark you can see that sunday is given day 0 instead of 7.
I have changed something in the Serialize/ASN1.cs, encode_bacnet_date
public static void encode_bacnet_date(EncodeBuffer buffer, DateTime value)
{
if (value == new DateTime(1, 1, 1)) // this is the way decode do for 'Date any' = DateTime(0)
{
buffer.Add(0xFF);
buffer.Add(0xFF);
buffer.Add(0xFF);
buffer.Add(0xFF);
return;
}
/* allow 2 digit years */
if (value.Year >= 1900)
buffer.Add((byte)(value.Year - 1900));
else if (value.Year < 0x100)
buffer.Add((byte)value.Year);
else
throw new Exception("Date is rubbish");
buffer.Add((byte)value.Month);
buffer.Add((byte)value.Day);
int DayOfWeek = (int)value.DayOfWeek;
if (DayOfWeek == 0) DayOfWeek = 7;
buffer.Add((byte)DayOfWeek);
}
After I changed this I still cannot read a trendlog (only with YABE it works) , but my weekday errors are gone
We have a device that has over a thousand objects and we get an overflow when trying to detect them using the code provided in the ObjectBrowseSample example.
Unhandled exception. System.Exception: Abort from device, reason: BUFFER_OVERFLOW
at System.IO.BACnet.BacnetClient.ReadPropertyRequest(BacnetAddress adr, BacnetObjectId objectId, BacnetPropertyIds propertyId, IList`1& valueList, Byte invokeId, UInt32 arrayIndex)
at System.IO.BACnet.BacnetClient.<>c__DisplayClass215_0.<ReadPropertyAsync>b__0()
at System.Threading.Tasks.Task`1.InnerInvoke()
at System.Threading.Tasks.Task.<>c.<.cctor>b__274_0(Object obj)
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location where exception was thrown ---
at Discover.Program.OnIAm(BacnetClient sender, BacnetAddress adr, UInt32 deviceid, UInt32 maxapdu, BacnetSegmentations segmentation, UInt16 vendorid) in C:\Sources\Tests\BacnetTests\Discover\Program.cs:line 27
at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__139_1(Object state)
at System.Threading.QueueUserWorkItemCallbackDefaultContext.Execute()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
Here "C:\Sources\Tests\BacnetTests\Discover\Program.cs:line 27" refers to this line
I'm no BACnet expert so I have no idea what to do, any suggestion will be appreciated ๐
Thanks!
How can we change network number in the code
Now that we started to add tests, we should add more. Currently, DotCover reports the following coverage:
It should be relatively easy to improve on this with back to back tests (like in EventNotificationTests/should_raise_oneventnotify_when_sending_changeoflifesafety_data) which provides much coverage with little effort.
To make sure that we are complying with the standard, more tests like ServiceTests/should_encode_logrecord_according_to_ashrae_example should be added - which can only be done by people having access to the documents.
Any takers? I'll work on additional tests for EventNotifications
, covering other EventValues
next. I'd suggest to comment here who is working on what to coordinate our efforts, but @gralin may have a better idea?! ๐
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.