// Copy the Present value into each reference properties value protected virtual void DoDispatchValue() { if ((m_PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES.references == null) || (Mydevice == null)) { return; } foreach (object obj in m_PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES.references) { BacnetDeviceObjectPropertyReference reference = (BacnetDeviceObjectPropertyReference)obj; // reference.deviceIndentifier.type is not set to OBJECT_DEVICE for local object reference if (reference.deviceIndentifier.type != BacnetObjectTypes.OBJECT_DEVICE) // local object { BaCSharpObject bcs = Mydevice.FindBacnetObject(reference.objectIdentifier); if (bcs != null) { BacnetPropertyValue value = new BacnetPropertyValue(); if (m_PROP_PRIORITY == 0) { value.priority = (byte)16; } else { value.priority = (byte)m_PROP_PRIORITY; } value.property = new BacnetPropertyReference((uint)reference.propertyIdentifier, reference.arrayIndex); value.value = new BacnetValue[] { new BacnetValue(m_PROP_PRESENT_VALUE) }; bcs.WritePropertyValue(value, false); } } else { KeyValuePair <BacnetClient, BacnetAddress>?recipient = null; try { // SuroundingDevices is updated with Iam messages recipient = Mydevice.SuroundingDevices[reference.deviceIndentifier.instance]; } catch { } if (recipient == null) { return; } BacnetValue[] value = new BacnetValue[] { new BacnetValue(m_PROP_PRESENT_VALUE) }; uint wp = m_PROP_PRIORITY; System.Threading.ThreadPool.QueueUserWorkItem((o) => { recipient.Value.Key.WritePriority = wp; recipient.Value.Key.BeginWritePropertyRequest(recipient.Value.Value, reference.objectIdentifier, (BacnetPropertyIds)reference.propertyIdentifier, value, false); } , null); } } }
private void IntrinsicReportingManagement() { if (Mydevice == null) { return; } if (m_PROP_LIMIT_ENABLE.value[0] == 0) { Last_PRESENT_VALUE = m_PROP_PRESENT_VALUE; return; } // T type must be convertible to double of course double pv = Convert.ToDouble(m_PROP_PRESENT_VALUE); double hl = Convert.ToDouble(m_PROP_HIGH_LIMIT); double ll = Convert.ToDouble(m_PROP_LOW_LIMIT); double db = Convert.ToDouble(m_PROP_DEADBAND); bool LimitEnabledHigh = (m_PROP_LIMIT_ENABLE.value[0] & (uint)BacnetEventNotificationData.BacnetLimitEnable.EVENT_HIGH_LIMIT_ENABLE) != 0; bool LimitEnabledLow = (m_PROP_LIMIT_ENABLE.value[0] & (uint)BacnetEventNotificationData.BacnetLimitEnable.EVENT_LOW_LIMIT_ENABLE) != 0; bool EventToOffNormal = (m_PROP_EVENT_ENABLE.value[0] & (uint)BacnetEventNotificationData.BacnetEventEnable.EVENT_ENABLE_TO_OFFNORMAL) != 0; bool EventToNormal = (m_PROP_EVENT_ENABLE.value[0] & (uint)BacnetEventNotificationData.BacnetEventEnable.EVENT_ENABLE_TO_NORMAL) != 0; bool NotifyState = false; uint fromState = m_PROP_EVENT_STATE; int toState = -1; switch (fromState) { case (uint)BacnetEventNotificationData.BacnetEventStates.EVENT_STATE_NORMAL: /* If LimitHigh flag is enabled and Present_Value exceed the High_Limit and Event to Offnormal is enabled then * the notification must be done */ if ((pv > hl) && LimitEnabledHigh) { toState = (int)BacnetEventNotificationData.BacnetEventStates.EVENT_STATE_HIGH_LIMIT; NotifyState = EventToOffNormal; } /* If LowLimit flag is enabled and Present_Value exceed the Low_Limit and Event to Offnormal is enabled then * the notification must be done */ if ((pv < ll) & LimitEnabledLow) { toState = (int)BacnetEventNotificationData.BacnetEventStates.EVENT_STATE_LOW_LIMIT; NotifyState = EventToOffNormal; } break; case (uint)BacnetEventNotificationData.BacnetEventStates.EVENT_STATE_HIGH_LIMIT: /* Present_Value fall below the High_Limit - Deadband ? */ if (pv < (hl - db)) { toState = (int)BacnetEventNotificationData.BacnetEventStates.EVENT_STATE_NORMAL; NotifyState = EventToNormal; } /* Present_Value fall below the Low_Limit ? */ if ((pv < ll) && LimitEnabledLow) { toState = (int)BacnetEventNotificationData.BacnetEventStates.EVENT_STATE_LOW_LIMIT; if (!NotifyState) { NotifyState = EventToOffNormal; } } break; case (uint)BacnetEventNotificationData.BacnetEventStates.EVENT_STATE_LOW_LIMIT: /* Present_Value exceed the Low_Limit + Deadband ? */ if (pv > (ll + db)) { toState = (int)BacnetEventNotificationData.BacnetEventStates.EVENT_STATE_NORMAL; NotifyState = EventToNormal; } /* Present_Value exceed the High_Limit ? */ if ((pv > hl) && LimitEnabledHigh) { toState = (int)BacnetEventNotificationData.BacnetEventStates.EVENT_STATE_HIGH_LIMIT; if (!NotifyState) { NotifyState = EventToOffNormal; } } break; } if (toState != -1) { // Update Event_State m_PROP_EVENT_STATE = (uint)toState; BacnetGenericTime stamp = new BacnetGenericTime(DateTime.Now, BacnetTimestampTags.TIME_STAMP_DATETIME); // Update EVENT_TIME_STAMPS, 1 is for FAULT (not used) if (toState == 0) { m_PROP_EVENT_TIME_STAMPS[2] = new BacnetValue(BacnetApplicationTags.BACNET_APPLICATION_TAG_TIMESTAMP, stamp); // Normal } else { m_PROP_EVENT_TIME_STAMPS[1] = new BacnetValue(BacnetApplicationTags.BACNET_APPLICATION_TAG_TIMESTAMP, stamp); // Limit } } Last_PRESENT_VALUE = m_PROP_PRESENT_VALUE; if (NotifyState == false) { return; } // look for the related notification class object NotificationClass nc = (NotificationClass)Mydevice.FindBacnetObject(new BacnetObjectId(BacnetObjectTypes.OBJECT_NOTIFICATION_CLASS, m_PROP_NOTIFICATION_CLASS)); if (nc != null) { nc.SendIntrinsectEvent( m_PROP_OBJECT_IDENTIFIER, (BacnetEventNotificationData.BacnetNotifyTypes)m_PROP_NOTIFY_TYPE, BacnetEventNotificationData.BacnetEventTypes.EVENT_CHANGE_OF_VALUE, (BacnetEventNotificationData.BacnetEventStates)fromState, (BacnetEventNotificationData.BacnetEventStates)toState); } }