void OnUpdateTarget(GXDLMSObject value) { if (value != null && value.Parent != null && value.Parent.Parent is GXDLMSClient && (value.Parent.Parent as GXDLMSClient).Standard == Standard.Italy) { if (value.LogicalName == "0.0.21.0.1.255") { //If non-enrolled list. RemoveBtn.Visible = false; AddWhiteBtn.Visible = AddBlackBtn.Visible = true; } else if (value.LogicalName == "0.0.21.0.2.255" || value.LogicalName == "0.0.21.0.3.255") { //If white or black list. RemoveBtn.Visible = true; AddWhiteBtn.Visible = AddBlackBtn.Visible = false; } else { RemoveBtn.Visible = AddWhiteBtn.Visible = AddBlackBtn.Visible = false; } } else { RemoveBtn.Visible = AddWhiteBtn.Visible = AddBlackBtn.Visible = false; } target = (GXDLMSProfileGeneric)value; structures = false; GXDLMSObject obj; if (target != null) { UpdateCaptureObjects(); } else { ProfileGenericView.DataSource = null; } //Set initial values... ReadFromRB.Enabled = ReadLastRB.Enabled = ReadEntryBtn.Enabled = target.CaptureObjects.Count != 0; ReadFromRB.Checked = ReadLastRB.Checked = ReadEntryBtn.Checked = false; StartEntry.Value = Properties.Settings.Default.ProfileGenericIndex; EndEntry.Value = Properties.Settings.Default.ProfileGenericCount; ReadLastTB.Value = 0; DateTime tm; if (DateTime.TryParse(Properties.Settings.Default.ProfileGenericStartTime, out tm)) { if (tm != DateTime.MinValue) { try { StartPick.Checked = true; StartPick.Value = tm; } catch (Exception) { //It's ok if this fails. StartPick.Checked = false; } } else { StartPick.Checked = false; } } else { StartPick.Value = DateTime.Now; } if (DateTime.TryParse(Properties.Settings.Default.ProfileGenericEndTime, out tm)) { if (tm != DateTime.MaxValue) { try { ToPick.Checked = true; ToPick.Value = tm; } catch (Exception) { //It's ok if this fails. ToPick.Checked = false; } } else { ToPick.Checked = false; } } else { ToPick.Value = DateTime.Now; } if (!ReadFromRB.Enabled) { return; } obj = target.CaptureObjects[0].Key; if (target.AccessSelector == AccessRange.Entry) { StartEntry.Value = Convert.ToInt32(target.From); EndEntry.Value = Convert.ToInt32(target.To); ReadEntryBtn.Checked = true; } else if (target.AccessSelector == AccessRange.Last) { TimeSpan diff = (DateTime)target.To - (DateTime)target.From; ReadLastTB.Value = diff.Days - 1; ReadLastRB.Checked = true; } else if (target.AccessSelector == AccessRange.Range) { if ((DateTime)target.From == DateTime.MinValue) { StartPick.Checked = false; } else { StartPick.Value = (DateTime)target.From; } if ((DateTime)target.To == DateTime.MaxValue) { ToPick.Checked = false; } else { ToPick.Value = (DateTime)target.To; } ReadFromRB.Checked = true; } else //All is checked. { ReadAllRB.Checked = true; } }
public GXProfileGenericUpdater(GXDLMSServer server, GXDLMSProfileGeneric pg) { Server = server; Target = pg; }
/// <summary> /// Initialize server. /// </summary> /// <remarks> /// This must call after server objects are set. /// <param name="manually">If true, server handle objects and all data are updated manually.</param> public void Initialize(bool manually) { Initialized = true; if (manually) { return; } bool association = false; 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. UpdateShortNames(false); }
public void UpdateColumns(GXDLMSProfileGeneric item, GXManufacturer man) { if (Comm.parentForm.InvokeRequired) { try { Comm.parentForm.Invoke(new UpdateColumnsEventHandler(UpdateColumns), item, man); } catch (Exception ex) { MessageBox.Show(ex.Message); } return; } try { item.Buffer.Clear(); item.CaptureObjects.Clear(); List <GXKeyValuePair <GXDLMSObject, GXDLMSCaptureObject> > cols = null; List <DataColumn> columns = new List <DataColumn>(); try { Comm.GetProfileGenericColumns(item); if (Standard == Standard.Italy && item.CaptureObjects.Count == 0) { cols = GetColumns(Comm.client.Objects, Comm.client.CustomObisCodes, item.LogicalName, 0); GXDLMSConverter c = new GXDLMSConverter(Standard); foreach (var it in cols) { c.UpdateOBISCodeInformation(it.Key); } item.CaptureObjects.AddRange(cols); } } catch (GXDLMSException ex) { if (Standard == Standard.Italy) { GXDLMSData obj = Comm.client.Objects.FindByLN(ObjectType.Data, "0.0.96.1.3.255") as GXDLMSData; int type = 0; if (obj != null) { if (obj.Value == null) { try { Comm.ReadValue(obj, 2); type = Convert.ToInt16(obj.Value); } catch (Exception) { type = 0; } } else { type = Convert.ToInt16(obj.Value); } } cols = GetColumns(Comm.client.Objects, Comm.client.CustomObisCodes, item.LogicalName, type); item.CaptureObjects.Clear(); GXDLMSConverter c = new GXDLMSConverter(Standard); foreach (var it in cols) { c.UpdateOBISCodeInformation(it.Key); } item.CaptureObjects.AddRange(cols); } if (cols == null || cols.Count == 0) { throw ex; } } } catch (Exception ex) { MessageBox.Show(ex.Message); } }
/// <summary> /// Read object. /// </summary> /// <param name="InitialValues"></param> /// <param name="obj"></param> /// <param name="attribute">Attribute index to read.</param> /// <param name="forceRead">Force all attributes read.</param> public void Read(object sender, GXDLMSObject obj, int attribute, bool forceRead) { GXReplyData reply = new GXReplyData(); if (forceRead) { obj.ClearReadTime(); } foreach (int it in (obj as IGXDLMSBase).GetAttributeIndexToRead()) { reply.Clear(); if (obj is GXDLMSProfileGeneric && it == 2) { if (OnBeforeRead != null) { OnBeforeRead(obj, it); } try { byte[][] tmp; CurrentProfileGeneric = obj as GXDLMSProfileGeneric; OnDataReceived += new GXDLMSCommunicator.DataReceivedEventHandler(this.OnProfileGenericDataReceived); if (CurrentProfileGeneric.AccessSelector == AccessRange.Range || CurrentProfileGeneric.AccessSelector == AccessRange.Last) { GXDateTime start = CurrentProfileGeneric.From as GXDateTime; if (start == null) { start = Convert.ToDateTime(CurrentProfileGeneric.From); } GXDateTime end = CurrentProfileGeneric.To as GXDateTime; if (end == null) { end = Convert.ToDateTime(CurrentProfileGeneric.To); } tmp = client.ReadRowsByRange(CurrentProfileGeneric, start, end); ReadDataBlock(tmp, "Reading profile generic data", 1, reply); } else if (CurrentProfileGeneric.AccessSelector == AccessRange.Entry) { tmp = client.ReadRowsByEntry(CurrentProfileGeneric, Convert.ToInt32(CurrentProfileGeneric.From), Convert.ToInt32(CurrentProfileGeneric.To)); ReadDataBlock(tmp, "Reading profile generic data " + CurrentProfileGeneric.Name, 1, reply); } else //Read all. { tmp = client.Read(CurrentProfileGeneric, 2); ReadDataBlock(tmp, "Reading profile generic data " + CurrentProfileGeneric.Name, 1, reply); } } finally { if (OnAfterRead != null) { OnAfterRead(obj, it); } OnDataReceived -= new GXDLMSCommunicator.DataReceivedEventHandler(OnProfileGenericDataReceived); } continue; } else { if (OnBeforeRead != null) { OnBeforeRead(obj, it); } byte[] data = client.Read(obj.Name, obj.ObjectType, it)[0]; try { ReadDataBlock(data, "Read object type " + obj.ObjectType + " index: " + it, reply); } catch (GXDLMSException ex) { if (ex.ErrorCode == (int)ErrorCode.ReadWriteDenied || ex.ErrorCode == (int)ErrorCode.UndefinedObject || ex.ErrorCode == (int)ErrorCode.UnavailableObject || //Actaris returns access violation error. ex.ErrorCode == (int)ErrorCode.AccessViolated) { obj.SetAccess(it, AccessMode.NoAccess); continue; } else { throw ex; } } if (obj is IGXDLMSBase) { object value = reply.Value; DataType type; if (value is byte[] && (type = obj.GetUIDataType(it)) != DataType.None) { value = GXDLMSClient.ChangeType((byte[])value, type); } client.UpdateValue(obj, it, value); } if (OnAfterRead != null) { OnAfterRead(obj, it); } obj.SetLastReadTime(it, DateTime.Now); //If only selected attribute is read. if (attribute != 0) { break; } } } }
/// <summary> /// Generate random value for profile generic. /// </summary> /// <param name="args"></param> public override void PreGet(ValueEventArgs[] args) { foreach (ValueEventArgs e in args) { if (e.Target is GXDLMSProfileGeneric) { //We want to save values to the file right a way. GXDLMSProfileGeneric pg = (GXDLMSProfileGeneric)e.Target; //Get entries in use if not know yet. if (pg.EntriesInUse == 0) { pg.EntriesInUse = GetProfileGenericDataCount(pg); } string name = GetProfileGenericName(pg); object[] values = new object[pg.CaptureObjects.Count]; int pos = 0; lock (pg) { foreach (GXKeyValuePair <GXDLMSObject, GXDLMSCaptureObject> it in pg.CaptureObjects) { if (it.Key is GXDLMSClock && it.Value.AttributeIndex == 2) { GXDLMSClock c = (it.Key as GXDLMSClock); c.Time = c.Now(); } else if (it.Key == temperature && it.Value.AttributeIndex == 2) { //Get CPU temperature. UpdateTemperature(); } values[pos] = it.Key.GetValues()[it.Value.AttributeIndex - 1]; ++pos; } ++pg.EntriesInUse; //Remove first row if maximum row count is received. if (pg.ProfileEntries != 0 && pg.EntriesInUse >= pg.ProfileEntries) { RemoveRows(name, pg.EntriesInUse - pg.ProfileEntries); pg.EntriesInUse = pg.ProfileEntries; } using (var writer = File.AppendText(name)) { StringBuilder sb = new StringBuilder(); for (int c = 0; c != values.Length; ++c) { if (c != 0) { sb.Append(';'); } object col = values[c]; if (col is DateTime) { sb.Append(((DateTime)col).ToString(CultureInfo.InvariantCulture)); } else { sb.Append(Convert.ToString(col)); } } sb.AppendLine(""); writer.Write(sb.ToString()); } } e.Handled = true; } } }
protected override void PreWrite(ValueEventArgs[] args) { foreach (ValueEventArgs it in args) { if (it.Target is GXDLMSProfileGeneric) { //We do not want that buffer can be write here. if (it.Index == 2) { it.Error = ErrorCode.ReadWriteDenied; } else if (it.Index == 3) { //If user is updating capture objects. //We are expecting that first column is always clock object's date time. GXDLMSProfileGeneric pg = it.Target as GXDLMSProfileGeneric; List <GXKeyValuePair <GXDLMSObject, GXDLMSCaptureObject> > list = GXDLMSProfileGeneric.GetCaptureObjects(it.Value as object[]); if (list.Count != 0 && !(list[0].Key is GXDLMSClock && list[0].Value.AttributeIndex == 2)) { it.Error = ErrorCode.ReadWriteDenied; } } } System.Diagnostics.Debug.WriteLine("Writing " + it.Target.LogicalName); } }
/// <summary> /// Generic read handle for all servers. /// </summary> /// <param name="server"></param> /// <param name="e"></param> protected override void PreRead(ValueEventArgs[] args) { foreach (ValueEventArgs e in args) { //If user wants to know CPU temperature. if (e.Target == temperature && e.Index == 2) { UpdateTemperature(); } //Read only size of PDU at the memory at once. else if (e.Target is GXDLMSProfileGeneric) { //If buffer is read and we want to save memory. if (e.Index == 6) { //If client wants to know EntriesInUse. GXDLMSProfileGeneric p = (GXDLMSProfileGeneric)e.Target; p.EntriesInUse = GetProfileGenericDataCount(p); } if (e.Index == 2) { //Client reads buffer. GXDLMSProfileGeneric p = (GXDLMSProfileGeneric)e.Target; //If reading first time. if (e.RowEndIndex == 0) { if (e.Selector == 0) { e.RowEndIndex = GetProfileGenericDataCount(p); } else if (e.Selector == 1) { //Read by entry. GetProfileGenericDataByRange(e); } else if (e.Selector == 2) { //Read by range. e.RowBeginIndex = (UInt32)((object[])e.Parameters)[0]; e.RowEndIndex = e.RowBeginIndex + (UInt32)((object[])e.Parameters)[1]; //If client wants to read more data what we have. UInt16 cnt = GetProfileGenericDataCount(p); if (e.RowEndIndex - e.RowBeginIndex > cnt - e.RowBeginIndex) { e.RowEndIndex = cnt - e.RowBeginIndex; if (e.RowEndIndex < 0) { e.RowEndIndex = 0; } } } } UInt32 count = e.RowEndIndex - e.RowBeginIndex; //Read only rows that can fit to one PDU. if (e.RowToPdu != 0 && e.RowEndIndex - e.RowBeginIndex > e.RowToPdu) { count = e.RowToPdu; } GetProfileGenericDataByEntry(p, e.RowBeginIndex, count); } } } }
/// <summary> /// Return data using start and end indexes. /// </summary> /// <param name="p">ProfileGeneric</param> /// <param name="index">Row index.</param> /// <param name="count">Row count.</param> void GetProfileGenericDataByEntry(GXDLMSProfileGeneric p, UInt32 index, UInt32 count) { //Clear old data. It's already serialized. p.Buffer.Clear(); string name = GetProfileGenericName(p); if (count != 0) { lock (p) { if (!File.Exists(name)) { return; } using (var fs = File.OpenRead(name)) { using (var reader = new StreamReader(fs)) { while (!reader.EndOfStream) { string line = reader.ReadLine(); if (line.Length != 0) { //Skip row if (index > 0) { --index; } else { string[] values = line.Split(';'); object[] list = new object[values.Length]; for (int pos = 0; pos != values.Length; ++pos) { DataType t = p.CaptureObjects[pos].Key.GetUIDataType(p.CaptureObjects[pos].Value.AttributeIndex); if (t == DataType.DateTime) { list[pos] = new GXDateTime(values[pos]); } else if (t == DataType.Date) { list[pos] = new GXDate(values[pos]); } else if (t == DataType.Time) { list[pos] = new GXTime(values[pos]); } else { list[pos] = values[pos]; } } p.Buffer.Add(list); } if (p.Buffer.Count == count) { break; } } } } } } } }