diff --git a/BACnet.csproj b/BACnet.csproj
index a55cfe3..ed6de28 100644
--- a/BACnet.csproj
+++ b/BACnet.csproj
@@ -58,6 +58,7 @@
+
@@ -100,6 +101,7 @@
+
diff --git a/Base/BacnetDailySchedule.cs b/Base/BacnetDailySchedule.cs
new file mode 100644
index 0000000..be492a7
--- /dev/null
+++ b/Base/BacnetDailySchedule.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.IO.BACnet.Serialize;
+using System.Linq;
+using System.Text;
+
+namespace System.IO.BACnet
+{
+ public struct BacnetDailySchedule : ASN1.IEncode, ASN1.IDecode
+ {
+ public List DaySchedule;
+
+
+
+ public int Decode(byte[] buffer, int offset, uint count)
+ {
+ int len = 0;
+ DaySchedule = new List();
+ //begin of daily sched
+ if (ASN1.IS_OPENING_TAG(buffer[offset + len]))
+ {
+ len++;
+ //end of daily sched
+ while (!ASN1.IS_CLOSING_TAG(buffer[offset + len]) )
+ {
+ len++; //ignore apptag time ?
+ len += ASN1.decode_bacnet_time(buffer, offset + len, out DateTime time);
+
+
+ var tagLen = ASN1.decode_tag_number_and_value(buffer, offset + len, out BacnetApplicationTags tagNumber, out uint lenValueType);
+ BacnetValue value;
+ if (tagLen > 0)
+ {
+ len += tagLen;
+ var decodeLen = ASN1.bacapp_decode_data(buffer, offset + len, offset + len + 1, tagNumber, lenValueType, out value);
+ len += decodeLen;
+ }
+ else
+ {
+ value = new BacnetValue(BacnetApplicationTags.BACNET_APPLICATION_TAG_NULL, null);
+ }
+
+
+ DaySchedule.Add(new BacnetTimeValue(new BacnetGenericTime(time, BacnetTimestampTags.TIME_STAMP_TIME), value));
+
+ }
+ //closing tag
+ len++;
+ }
+
+ return len;
+ }
+
+ public void Encode(EncodeBuffer buffer)
+ {
+ ASN1.encode_opening_tag(buffer, 0);
+
+ if (DaySchedule != null)
+ {
+ foreach (var dayItem in DaySchedule)
+ {
+
+ ASN1.encode_tag(buffer, (byte)BacnetApplicationTags.BACNET_APPLICATION_TAG_TIME, false, 4);
+ ASN1.encode_bacnet_time(buffer, dayItem.Time.Time);
+
+ ASN1.bacapp_encode_application_data(buffer, dayItem.Value);
+ }
+ }
+ ASN1.encode_closing_tag(buffer, 0);
+ }
+
+ public override string ToString()
+ {
+ return $"DaySchedule Len: {DaySchedule?.Count()}";
+ }
+
+ }
+}
diff --git a/Base/BacnetTimeValue.cs b/Base/BacnetTimeValue.cs
new file mode 100644
index 0000000..ecdf8b2
--- /dev/null
+++ b/Base/BacnetTimeValue.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace System.IO.BACnet
+{
+ public struct BacnetTimeValue
+ {
+ public BacnetGenericTime Time;
+ public BacnetValue Value;
+
+ public BacnetTimeValue(BacnetGenericTime time, BacnetValue value)
+ {
+ Time = time;
+ Value = value;
+ }
+
+ public override string ToString()
+ {
+ return $"{Time} = {Value}";
+ }
+ }
+}
diff --git a/Base/BacnetValue.cs b/Base/BacnetValue.cs
index 1be34c2..962379f 100644
--- a/Base/BacnetValue.cs
+++ b/Base/BacnetValue.cs
@@ -45,6 +45,8 @@ public BacnetApplicationTags TagFromType(Type t)
return BacnetApplicationTags.BACNET_APPLICATION_TAG_ERROR;
if (t == typeof(BacnetDeviceObjectPropertyReference))
return BacnetApplicationTags.BACNET_APPLICATION_TAG_OBJECT_PROPERTY_REFERENCE;
+ if (t == typeof(BacnetDailySchedule[]))
+ return BacnetApplicationTags.BACNET_APPLICATION_TAG_WEEKLY_SCHEDULE;
if (t.IsEnum)
return BacnetApplicationTags.BACNET_APPLICATION_TAG_ENUMERATED;
diff --git a/Serialize/ASN1.cs b/Serialize/ASN1.cs
index 3e1cc03..9869099 100644
--- a/Serialize/ASN1.cs
+++ b/Serialize/ASN1.cs
@@ -483,6 +483,19 @@ public static void bacapp_encode_application_data(EncodeBuffer buffer, BacnetVal
throw new ArgumentException($"Unsupported destination value '{value.Value}' (type {value.GetType()})");
}
break;
+ case BacnetApplicationTags.BACNET_APPLICATION_TAG_WEEKLY_SCHEDULE:
+ if(value.Value is BacnetDailySchedule[] dayArr && dayArr.Length == 7)
+ {
+ for (int i = 0; i < 7; i++)
+ {
+ dayArr[i].Encode(buffer);
+ }
+ }
+ else
+ {
+ throw new ArgumentException("Value has to be array of 7 of daily schedule ");
+ }
+ break;
default:
//context specific
if (value.Value is byte[] arr)
@@ -2033,6 +2046,19 @@ public static int bacapp_decode_context_application_data(BacnetAddress address,
return len;
}
+ if(propertyId == BacnetPropertyIds.PROP_WEEKLY_SCHEDULE)
+ {
+ //has to be an array of 7
+ var schedule = new BacnetDailySchedule[7];
+ for (int i = 0; i < 7; i++)
+ {
+ schedule[i] = new BacnetDailySchedule();
+ len += schedule[i].Decode(buffer, offset + len, (uint)maxOffset);
+ }
+ value.Value = schedule;
+ value.Tag = BacnetApplicationTags.BACNET_APPLICATION_TAG_WEEKLY_SCHEDULE;
+ return len;
+ }
value.Tag = BacnetApplicationTags.BACNET_APPLICATION_TAG_CONTEXT_SPECIFIC_DECODED;
var list = new List();
@@ -2418,6 +2444,7 @@ public static int decode_property_state(byte[] buffer, int offset, out BacnetPro
return len + sectionLength;
}
+
public static int decode_context_bitstring(byte[] buffer, int offset, byte tagNumber, out BacnetBitString value)
{
@@ -2466,5 +2493,8 @@ public static int decode_context_unsigned(byte[] buffer, int offset, byte tagNum
var len = decode_tag_number_and_value(buffer, offset, out _, out var lenValue);
return len + decode_unsigned(buffer, offset + len, lenValue, out value);
}
+
+
+
}
}