internal static GXSNInfo FindSNObject(GXDLMSObjectCollection items, int sn) { GXSNInfo i = new GXSNInfo(); int offset, count; foreach (GXDLMSObject it in items) { if (sn >= it.ShortName) { //If attribute is accessed. if (sn < it.ShortName + (it as IGXDLMSBase).GetAttributeCount() * 8) { i.IsAction = false; i.Item = it; i.Index = ((sn - i.Item.ShortName) / 8) + 1; break; } else { //If method is accessed. GXDLMS.GetActionInfo(it.ObjectType, out offset, out count); if (sn < it.ShortName + offset + (8 * count)) { i.Item = it; i.IsAction = true; i.Index = (sn - it.ShortName - offset) / 8 + 1; break; } } } } return(i); }
/// <summary> /// Update short names. /// </summary> private void UpdateShortNames(bool force) { //Arrange items by Short Name. int sn = 0xA0; int offset, count; if (!this.UseLogicalNameReferencing) { foreach (GXDLMSObject it in Items) { if (!(it is GXDLMSAssociationShortName)) { //Generate Short Name if not given. if (force || it.ShortName == 0) { it.ShortName = (ushort)sn; //Add method index addresses. GXDLMS.GetActionInfo(it.ObjectType, out offset, out count); if (count != 0) { sn += offset + (8 * count); } else //If there are no methods. { //Add attribute index addresses. sn += 8 * (it as IGXDLMSBase).GetAttributeCount(); } } } } } }
///<summary> /// Find Short Name object. ///</summary> ///<param name="sn"> ///Short name to find. ///</param> private GXSNInfo FindSNObject(int sn) { GXSNInfo info = new GXSNInfo(); foreach (KeyValuePair <ushort, GXDLMSObject> it in SortedItems) { int aCnt = ((IGXDLMSBase)it.Value).GetAttributeCount(); if (sn >= it.Key && sn <= (it.Key + (8 * aCnt))) { info.IsAction = false; info.Item = it.Value; info.Index = ((sn - info.Item.ShortName) / 8) + 1; Debug.WriteLine(string.Format("Reading {0:D}, attribute index {1:D}", info.Item.Name, info.Index)); break; } else if (sn >= it.Key + aCnt && ((IGXDLMSBase)it.Value).GetMethodCount() != 0) { // Check if action. // Convert DLMS data to object type. int value2, count; GXDLMS.GetActionInfo(it.Value.ObjectType, out value2, out count); if (sn <= it.Key + value2 + (8 * count)) { info.Item = it.Value; info.IsAction = true; info.Index = (sn - it.Value.ShortName - value2) / 8 + 1; break; } } } if (info.Item == null) { info.Item = FindObject(ObjectType.None, sn, null); } if (info.Item == null) { throw new System.ArgumentException("Invalid SN Command."); } return(info); }
/// <summary> /// Initialize server. /// </summary> /// <remarks> /// This must call after server objects are set. /// </remarks> public void Initialize() { bool association = false; Initialized = true; for (int pos = 0; pos != Items.Count; ++pos) { GXDLMSObject it = Items[pos]; if (this.UseLogicalNameReferencing && (string.IsNullOrEmpty(it.LogicalName) || it.LogicalName.Split('.').Length != 6)) { throw new Exception("Invalid Logical Name."); } it.Start(this); if (it is GXDLMSProfileGeneric) { GXDLMSProfileGeneric pg = it as GXDLMSProfileGeneric; foreach (var obj in pg.CaptureObjects) { if (obj.Value.AttributeIndex < 1) { throw new Exception("Invalid attribute index. SelectedAttributeIndex is not set for " + obj.Key.Name); } } } else if (it is GXDLMSAssociationShortName && !this.UseLogicalNameReferencing) { if ((it as GXDLMSAssociationShortName).ObjectList.Count == 0) { (it as GXDLMSAssociationShortName).ObjectList.AddRange(this.Items); } association = true; } else if (it is GXDLMSAssociationLogicalName && this.UseLogicalNameReferencing) { if ((it as GXDLMSAssociationLogicalName).ObjectList.Count == 0) { (it as GXDLMSAssociationLogicalName).ObjectList.AddRange(this.Items); } association = true; } else if (it is GXDLMSHdlcSetup) { hdlcSetup = it as GXDLMSHdlcSetup; } else if (!(it is IGXDLMSBase))//Remove unsupported items. { Debug.WriteLine(it.ObjectType.ToString() + " not supported."); Items.RemoveAt(pos); --pos; } } if (!association) { if (UseLogicalNameReferencing) { GXDLMSAssociationLogicalName it = new GXDLMSAssociationLogicalName(); it.ObjectList = this.Items; Items.Add(it); } else { GXDLMSAssociationShortName it = new GXDLMSAssociationShortName(); it.ObjectList = this.Items; Items.Add(it); } } //Arrange items by Short Name. int sn = 0xA0; int offset, count; if (!this.UseLogicalNameReferencing) { foreach (GXDLMSObject it in Items) { //Generate Short Name if not given. if (it.ShortName == 0) { it.ShortName = (ushort)sn; //Add method index addresses. GXDLMS.GetActionInfo(it.ObjectType, out offset, out count); if (count != 0) { sn += offset + (8 * count); } else //If there are no methods. { //Add attribute index addresses. sn += 8 * (it as IGXDLMSBase).GetAttributeCount(); } } } } }