• Recent
    • Tags
    • Popular
    • Register
    • Login
    1. Home
    2. joolz

    Please Note This forum exists for community support for the Mango product family and the Radix IoT Platform. Although Radix IoT employees participate in this forum from time to time, there is no guarantee of a response to anything posted here, nor can Radix IoT, LLC guarantee the accuracy of any information expressed or conveyed. Specific project questions from customers with active support contracts are asked to send requests to support@radixiot.com.

    Radix IoT Website Mango 3 Documentation Website Mango 4 Documentation Website Mango 5 Documentation Website
    J
    • Profile
    • Following 0
    • Followers 0
    • Topics 18
    • Posts 50
    • Best 1
    • Controversial 0
    • Groups 0

    joolz

    @joolz

    1
    Reputation
    1.1k
    Profile views
    50
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    joolz Unfollow Follow

    Best posts made by joolz

    • RE: Creating a Schedule Object in BACnet4j

      I have, but BACnet4j doesn't make it straight forward.

      First you need to subclass BACnetObject and make a Schedule object class.
      In that schedule object class, have a local variable for schedule default property.
      In the constructor, set the present value and schedule default properties with this value:
      new AmbiguousValue(new ByteQueue(new byte[]{0}))

      Then override the get() and set() methods, so that if the schedule default property is being set/retrieved, you get it from your local variable instead of the property map.

      posted in BACnet4J general discussion
      J
      joolz

    Latest posts made by joolz

    • Bug in Destination/DaysOfWeek class

      There is a bug in the way the Destination class determines whether or not the specified timestamp falls on a valid day.

      In com.serotonin.bacnet4j.type.constructed.Destination.java:

      public boolean isSuitableForEvent(TimeStamp timeStamp, EventState toState) {
          // Only check date fields if the timestamp is not a sequence number.
          if (!timeStamp.isSequenceNumber()) {
              // Check if the timestamp day of week is in the valid days of week list.
              if (!validDays.contains(timeStamp.getDateTime().getDate().getDayOfWeek().getId()))
                  return false;
      
              // Check if the timestamp is between the from and to times.
              if (timeStamp.getDateTime().getTime().before(fromTime) || timeStamp.getDateTime().getTime().after(toTime))
                  return false;
          }
      
          // Check if the destination is interested in this new event state.
          return transitions.contains(toState);
      }
      

      and com.serotonin.bacnet4j.type.constructed.DaysOfWeek.java

      public boolean contains(int day) {
          return getValue()[day];
      }
      

      timeStamp.getDateTime().getDate().getDayOfWeek().getId() returns a number from 1-7
      However, the DaysOfWeek class stores the days in a 0 indexed array 0-6, which means the wrong index is checked every time this function is called.

      posted in BACnet4J general discussion
      J
      joolz
    • Issue with the PriorityArray and multiple BACnet objects of the same type

      I have recently discovered that if you were to create two objects of the same type which have a priority array (e.g. BV), if you set the Priority at index 3 in BV1, it will also set it in BV2. This happens because in ObjectProperties.java, the static add() function creates a new PriorityArray instance which is then passed into all objects of the same type when they are created. This means the same PriorityArray object is used and passed into all BV instances when they are created.

      The solution to this is to after creating your BACnet object (AO, AV, BO, BV etc), call the setProperty() function, and create a new PriorityArray instance;
      I.E
      BACnetObject bv1 = new BACnetObject(.....);
      bv1.setProperty(PropertyIdentifier.priorityArray, new PriorityArray());

      posted in BACnet4J general discussion
      J
      joolz
    • RE: Creating a Schedule Object in BACnet4j

      I have, but BACnet4j doesn't make it straight forward.

      First you need to subclass BACnetObject and make a Schedule object class.
      In that schedule object class, have a local variable for schedule default property.
      In the constructor, set the present value and schedule default properties with this value:
      new AmbiguousValue(new ByteQueue(new byte[]{0}))

      Then override the get() and set() methods, so that if the schedule default property is being set/retrieved, you get it from your local variable instead of the property map.

      posted in BACnet4J general discussion
      J
      joolz
    • Creating a Schedule Object in BACnet4j

      I am trying to create a schedule object in BACnet4j using the following (simplified for clarity):

      
      import com.serotonin.bacnet4j.LocalDevice;
      import com.serotonin.bacnet4j.exception.BACnetServiceException;
      import com.serotonin.bacnet4j.npdu.ip.IpNetwork;
      import com.serotonin.bacnet4j.obj.BACnetObject;
      import com.serotonin.bacnet4j.transport.Transport;
      import com.serotonin.bacnet4j.type.enumerated.ObjectType;
      import com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier;
      import com.serotonin.bacnet4j.type.primitive.Enumerated;
      import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier;
      
      
      public class ScheduleTest
      {
      	public static void main(String[] args)
      	{
      		try
      		{
      			LocalDevice localDevice = new LocalDevice(21, new Transport(new IpNetwork("255.255.255.0")));
      			BACnetObject schedule = new BACnetObject(localDevice, new ObjectIdentifier(ObjectType.schedule, 0));
      
      			schedule.setProperty(PropertyIdentifier.scheduleDefault, new Enumerated(0));
      		}
      		catch (BACnetServiceException e)
      		{
      			e.printStackTrace();
      		}
      	}
      }
      ```However, when I run it, I get this:
      

      com.serotonin.bacnet4j.exception.BACnetServiceException: class=Property, code=Invalid data type, message=expected class com.serotonin.bacnet4j.type.AmbiguousValue, received=class com.serotonin.bacnet4j.type.primitive.Enumerated
      at com.serotonin.bacnet4j.obj.ObjectProperties.validateValue(ObjectProperties.java:154)
      at com.serotonin.bacnet4j.obj.BACnetObject.setProperty(BACnetObject.java:192)
      at ScheduleTest.main(ScheduleTest.java:21)

      posted in BACnet4J general discussion
      J
      joolz
    • RE: Creating a Schedule Object in BACnet4j

      I am trying to create a schedule object in BACnet4j using the following (simplified for clarity):

      
      import com.serotonin.bacnet4j.LocalDevice;
      import com.serotonin.bacnet4j.exception.BACnetServiceException;
      import com.serotonin.bacnet4j.npdu.ip.IpNetwork;
      import com.serotonin.bacnet4j.obj.BACnetObject;
      import com.serotonin.bacnet4j.transport.Transport;
      import com.serotonin.bacnet4j.type.enumerated.ObjectType;
      import com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier;
      import com.serotonin.bacnet4j.type.primitive.Enumerated;
      import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier;
      
      
      public class ScheduleTest
      {
      	public static void main(String[] args)
      	{
      		try
      		{
      			LocalDevice localDevice = new LocalDevice(21, new Transport(new IpNetwork("255.255.255.0")));
      			BACnetObject schedule = new BACnetObject(localDevice, new ObjectIdentifier(ObjectType.schedule, 0));
      
      			schedule.setProperty(PropertyIdentifier.scheduleDefault, new Enumerated(0));
      		}
      		catch (BACnetServiceException e)
      		{
      			e.printStackTrace();
      		}
      	}
      }
      ```However, when I run it, I get this:
      

      com.serotonin.bacnet4j.exception.BACnetServiceException: class=Property, code=Invalid data type, message=expected class com.serotonin.bacnet4j.type.AmbiguousValue, received=class com.serotonin.bacnet4j.type.primitive.Enumerated
      at com.serotonin.bacnet4j.obj.ObjectProperties.validateValue(ObjectProperties.java:154)
      at com.serotonin.bacnet4j.obj.BACnetObject.setProperty(BACnetObject.java:192)
      at ScheduleTest.main(ScheduleTest.java:21)

      posted in BACnet4J general discussion
      J
      joolz
    • Bug in LogData class

      According to the standard, BACnetLogData is a choice of log-status, log-data or time-change.

      However, looking at com.serotonin.bacnet4j.type.constructed.LogData.java:```
      public LogData(ByteQueue queue) throws BACnetException {
      logStatus = read(queue, LogStatus.class, 0);
      logData = readSequenceOfChoice(queue, classes, 1);
      timeChange = read(queue, Real.class, 2);
      }

      @Override
      public void write(ByteQueue queue) {
          write(queue, logStatus, 0);
          write(queue, logData, 1);
          write(queue, timeChange, 2);
      }
      
      
      By changing
      
      public LogData(ByteQueue queue) throws BACnetException {
          logStatus = read(queue, LogStatus.class, 0);
          logData = readSequenceOfChoice(queue, classes, 1);
          timeChange = read(queue, Real.class, 2);
      }
      
      public LogData(ByteQueue queue) throws BACnetException {
          int tag = peekTagNumber(queue);
          if (tag == 0)
          {
              logStatus = read(queue, LogStatus.class, 0);
              logData = null;
              timeChange = null;
          }
          else if (tag == 1)
          {
              logStatus = null;
              logData = readSequenceOfChoice(queue, classes, 1);
              timeChange = null;
          }
          else if (tag == 2)
          {
              logStatus = null;
              logData = null;
              timeChange = read(queue, Real.class, 2);
          }
          else
          {
              throw new BACnetErrorException(ErrorClass.property, ErrorCode.missingRequiredParameter);
          }
      }
      
      posted in BACnet4J general discussion
      J
      joolz
    • RE: Bug in LogData class

      According to the standard, BACnetLogData is a choice of log-status, log-data or time-change.

      However, looking at com.serotonin.bacnet4j.type.constructed.LogData.java:```
      public LogData(ByteQueue queue) throws BACnetException {
      logStatus = read(queue, LogStatus.class, 0);
      logData = readSequenceOfChoice(queue, classes, 1);
      timeChange = read(queue, Real.class, 2);
      }

      @Override
      public void write(ByteQueue queue) {
          write(queue, logStatus, 0);
          write(queue, logData, 1);
          write(queue, timeChange, 2);
      }
      
      
      By changing
      
      public LogData(ByteQueue queue) throws BACnetException {
          logStatus = read(queue, LogStatus.class, 0);
          logData = readSequenceOfChoice(queue, classes, 1);
          timeChange = read(queue, Real.class, 2);
      }
      
      public LogData(ByteQueue queue) throws BACnetException {
          int tag = peekTagNumber(queue);
          if (tag == 0)
          {
              logStatus = read(queue, LogStatus.class, 0);
              logData = null;
              timeChange = null;
          }
          else if (tag == 1)
          {
              logStatus = null;
              logData = readSequenceOfChoice(queue, classes, 1);
              timeChange = null;
          }
          else if (tag == 2)
          {
              logStatus = null;
              logData = null;
              timeChange = read(queue, Real.class, 2);
          }
          else
          {
              throw new BACnetErrorException(ErrorClass.property, ErrorCode.missingRequiredParameter);
          }
      }
      
      posted in BACnet4J general discussion
      J
      joolz
    • RE: Problems with start BACnet4j (java.lang.ClassNotFoundException)
      Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/lang3/ObjectUtils  
      

      You are missing a jar file (commons-lang3-3.0.jar) in your classpath

      posted in BACnet4J general discussion
      J
      joolz
    • Reading Trendlog LogBuffer property should return an error

      The BACnet standard states that any attempt to read the LogBuffer property of a Trendlog or Trendlog Multiple object with a ReadProperty-Request or a ReadPropertyMultiple-Request shall cause a a Result(-) response, with an Error class of PROPERTY, and an Error Code of READ_ACCESS_DENIED.
      Currently BACnet4j does not do this.
      I've created a couple of patches which I believe fix this:

      
      diff --git a/src/com/serotonin/bacnet4j/service/confirmed/ReadPropertyMultipleRequest.java b/src/com/serotonin/bacnet4j/service/confirmed/ReadPropertyMultipleRequest.java
      --- a/src/com/serotonin/bacnet4j/service/confirmed/ReadPropertyMultipleRequest.java
      +++ b/src/com/serotonin/bacnet4j/service/confirmed/ReadPropertyMultipleRequest.java
      @@ -44,6 +44,8 @@
       import com.serotonin.bacnet4j.type.constructed.ReadAccessResult.Result;
       import com.serotonin.bacnet4j.type.constructed.ReadAccessSpecification;
       import com.serotonin.bacnet4j.type.constructed.SequenceOf;
      +import com.serotonin.bacnet4j.type.enumerated.ErrorClass;
      +import com.serotonin.bacnet4j.type.enumerated.ErrorCode;
       import com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier;
       import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier;
       import com.serotonin.bacnet4j.type.primitive.OctetString;
      @@ -151,7 +153,10 @@
               else {
                   // Get the specified property.
                   try {
      -                results.add(new Result(pid, pin, obj.getPropertyRequired(pid, pin)));
      +            	if (pid.equals(PropertyIdentifier.logBuffer))
      +            		results.add(new Result(pid, pin, new BACnetError(ErrorClass.property, ErrorCode.readAccessDenied)));
      +            	else
      +            		results.add(new Result(pid, pin, obj.getPropertyRequired(pid, pin)));
                   }
                   catch (BACnetServiceException e) {
                       results.add(new Result(pid, pin, new BACnetError(e.getErrorClass(), e.getErrorCode())));
      
      

      diff --git a/src/com/serotonin/bacnet4j/service/confirmed/ReadPropertyMultipleRequest.java b/src/com/serotonin/bacnet4j/service/confirmed/ReadPropertyMultipleRequest.java
      --- a/src/com/serotonin/bacnet4j/service/confirmed/ReadPropertyMultipleRequest.java
      +++ b/src/com/serotonin/bacnet4j/service/confirmed/ReadPropertyMultipleRequest.java
      @@ -44,6 +44,8 @@
      import com.serotonin.bacnet4j.type.constructed.ReadAccessResult.Result;
      import com.serotonin.bacnet4j.type.constructed.ReadAccessSpecification;
      import com.serotonin.bacnet4j.type.constructed.SequenceOf;
      +import com.serotonin.bacnet4j.type.enumerated.ErrorClass;
      +import com.serotonin.bacnet4j.type.enumerated.ErrorCode;
      import com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier;
      import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier;
      import com.serotonin.bacnet4j.type.primitive.OctetString;
      @@ -151,7 +153,10 @@
      else {
      // Get the specified property.
      try {

      •            results.add(new Result(pid, pin, obj.getPropertyRequired(pid, pin)));
        
      •        	if (pid.equals(PropertyIdentifier.logBuffer))
        
      •        		results.add(new Result(pid, pin, new BACnetError(ErrorClass.property, ErrorCode.readAccessDenied)));
        
      •        	else
        
      •        		results.add(new Result(pid, pin, obj.getPropertyRequired(pid, pin)));
               }
               catch (BACnetServiceException e) {
                   results.add(new Result(pid, pin, new BACnetError(e.getErrorClass(), e.getErrorCode())));
        
      posted in BACnet4J general discussion
      J
      joolz
    • RE: Reading Trendlog LogBuffer property should return an error

      The BACnet standard states that any attempt to read the LogBuffer property of a Trendlog or Trendlog Multiple object with a ReadProperty-Request or a ReadPropertyMultiple-Request shall cause a a Result(-) response, with an Error class of PROPERTY, and an Error Code of READ_ACCESS_DENIED.
      Currently BACnet4j does not do this.
      I've created a couple of patches which I believe fix this:

      
      diff --git a/src/com/serotonin/bacnet4j/service/confirmed/ReadPropertyMultipleRequest.java b/src/com/serotonin/bacnet4j/service/confirmed/ReadPropertyMultipleRequest.java
      --- a/src/com/serotonin/bacnet4j/service/confirmed/ReadPropertyMultipleRequest.java
      +++ b/src/com/serotonin/bacnet4j/service/confirmed/ReadPropertyMultipleRequest.java
      @@ -44,6 +44,8 @@
       import com.serotonin.bacnet4j.type.constructed.ReadAccessResult.Result;
       import com.serotonin.bacnet4j.type.constructed.ReadAccessSpecification;
       import com.serotonin.bacnet4j.type.constructed.SequenceOf;
      +import com.serotonin.bacnet4j.type.enumerated.ErrorClass;
      +import com.serotonin.bacnet4j.type.enumerated.ErrorCode;
       import com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier;
       import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier;
       import com.serotonin.bacnet4j.type.primitive.OctetString;
      @@ -151,7 +153,10 @@
               else {
                   // Get the specified property.
                   try {
      -                results.add(new Result(pid, pin, obj.getPropertyRequired(pid, pin)));
      +            	if (pid.equals(PropertyIdentifier.logBuffer))
      +            		results.add(new Result(pid, pin, new BACnetError(ErrorClass.property, ErrorCode.readAccessDenied)));
      +            	else
      +            		results.add(new Result(pid, pin, obj.getPropertyRequired(pid, pin)));
                   }
                   catch (BACnetServiceException e) {
                       results.add(new Result(pid, pin, new BACnetError(e.getErrorClass(), e.getErrorCode())));
      
      

      diff --git a/src/com/serotonin/bacnet4j/service/confirmed/ReadPropertyMultipleRequest.java b/src/com/serotonin/bacnet4j/service/confirmed/ReadPropertyMultipleRequest.java
      --- a/src/com/serotonin/bacnet4j/service/confirmed/ReadPropertyMultipleRequest.java
      +++ b/src/com/serotonin/bacnet4j/service/confirmed/ReadPropertyMultipleRequest.java
      @@ -44,6 +44,8 @@
      import com.serotonin.bacnet4j.type.constructed.ReadAccessResult.Result;
      import com.serotonin.bacnet4j.type.constructed.ReadAccessSpecification;
      import com.serotonin.bacnet4j.type.constructed.SequenceOf;
      +import com.serotonin.bacnet4j.type.enumerated.ErrorClass;
      +import com.serotonin.bacnet4j.type.enumerated.ErrorCode;
      import com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier;
      import com.serotonin.bacnet4j.type.primitive.ObjectIdentifier;
      import com.serotonin.bacnet4j.type.primitive.OctetString;
      @@ -151,7 +153,10 @@
      else {
      // Get the specified property.
      try {

      •            results.add(new Result(pid, pin, obj.getPropertyRequired(pid, pin)));
        
      •        	if (pid.equals(PropertyIdentifier.logBuffer))
        
      •        		results.add(new Result(pid, pin, new BACnetError(ErrorClass.property, ErrorCode.readAccessDenied)));
        
      •        	else
        
      •        		results.add(new Result(pid, pin, obj.getPropertyRequired(pid, pin)));
               }
               catch (BACnetServiceException e) {
                   results.add(new Result(pid, pin, new BACnetError(e.getErrorClass(), e.getErrorCode())));
        
      posted in BACnet4J general discussion
      J
      joolz