byte[] IGXDLMSBase.Invoke(GXDLMSSettings settings, ValueEventArgs e) { DateTimeOffset tm = this.Time.Value; // Resets the value to the default value. // The default value is an instance specific constant. if (e.Index == 1) { int minutes = tm.Minute; if (minutes < 8) { minutes = 0; } else if (minutes < 23) { minutes = 15; } else if (minutes < 38) { minutes = 30; } else if (minutes < 53) { minutes = 45; } else { minutes = 0; tm = tm.AddHours(1); } tm = tm.AddMinutes(-tm.Minute + minutes); tm = tm.AddSeconds(-tm.Second); tm = tm.AddMilliseconds(-tm.Millisecond); this.Time.Value = tm; } // Sets the meter's time to the nearest minute. else if (e.Index == 3) { tm = this.Time.Value; int s = tm.Second; if (s > 30) { tm = tm.AddMinutes(1); } tm = tm.AddSeconds(-tm.Second); tm = tm.AddMilliseconds(-tm.Millisecond); this.Time.Value = tm; } // Presets the time to a new value (preset_time) and defines // avalidity_interval within which the new time can be activated. else if (e.Index == 5) { GXDateTime presetTime = (GXDateTime)GXDLMSClient.ChangeType((byte[])((List <object>)e.Parameters)[0], DataType.DateTime, settings.UseUtc2NormalTime); GXDateTime validityIntervalStart = (GXDateTime)GXDLMSClient.ChangeType((byte[])((List <object>)e.Parameters)[1], DataType.DateTime, settings.UseUtc2NormalTime); GXDateTime validityIntervalEnd = (GXDateTime)GXDLMSClient.ChangeType((byte[])((List <object>)e.Parameters)[2], DataType.DateTime, settings.UseUtc2NormalTime); this.Time.Value = presetTime.Value; } // Shifts the time. else if (e.Index == 6) { int shift = Convert.ToInt32(e.Parameters); tm = tm.AddSeconds(shift); this.Time.Value = tm; } else { e.Error = ErrorCode.ReadWriteDenied; } return(null); }
byte[][] IGXDLMSBase.Invoke(object sender, int index, Object parameters) { DateTime tm = this.Time.Value; // Resets the value to the default value. // The default value is an instance specific constant. if (index == 1) { int minutes = tm.Minute; if (minutes < 8) { minutes = 0; } else if (minutes < 23) { minutes = 15; } else if (minutes < 38) { minutes = 30; } else if (minutes < 53) { minutes = 45; } else { minutes = 0; tm = tm.AddHours(1); } tm = tm.AddMinutes(-tm.Minute + minutes); tm = tm.AddSeconds(-tm.Second); tm = tm.AddMilliseconds(-tm.Millisecond); this.Time.Value = tm; } // Sets the meter’s time to the nearest minute. else if (index == 3) { tm = this.Time.Value; int s = tm.Second; if (s > 30) { tm = tm.AddMinutes(1); } tm = tm.AddSeconds(-tm.Second); tm = tm.AddMilliseconds(-tm.Millisecond); this.Time.Value = tm; } // Presets the time to a new value (preset_time) and defines // avalidity_interval within which the new time can be activated. else if (index == 5) { GXDateTime presetTime = (GXDateTime)GXDLMSClient.ChangeType((byte[])((Object[])parameters)[0], DataType.DateTime); GXDateTime validityIntervalStart = (GXDateTime)GXDLMSClient.ChangeType((byte[])((Object[])parameters)[1], DataType.DateTime); GXDateTime validityIntervalEnd = (GXDateTime)GXDLMSClient.ChangeType((byte[])((Object[])parameters)[2], DataType.DateTime); this.Time.Value = presetTime.Value; } // Shifts the time. else if (index == 6) { int shift = Convert.ToInt32(parameters); tm = tm.AddSeconds(shift); this.Time.Value = tm; } else { throw new ArgumentException("Invoke failed. Invalid attribute index."); } return(null); }
/// <summary> /// Constructor. /// </summary> public GXDLMSClock() : base(ObjectType.Clock, "0.0.1.0.0.255", 0) { Time = new GXDateTime(DateTime.MinValue); }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { LogicalName = GXCommon.ToLogicalName(e.Value); } else if (e.Index == 2) { PushObjectList.Clear(); if (e.Value is object[]) { foreach (object it in e.Value as object[]) { object[] tmp = it as object[]; ObjectType type = (ObjectType)Convert.ToUInt16(tmp[0]); string ln = GXCommon.ToLogicalName(tmp[1]); GXDLMSObject obj = settings.Objects.FindByLN(type, ln); if (obj == null) { obj = GXDLMSClient.CreateObject(type); obj.LogicalName = ln; } GXDLMSCaptureObject co = new GXDLMSCaptureObject(Convert.ToInt32(tmp[2]), Convert.ToInt32(tmp[3])); PushObjectList.Add(new KeyValuePair <GXDLMSObject, GXDLMSCaptureObject>(obj, co)); } } } else if (e.Index == 3) { if (e.Value is object[] tmp) { Service = (ServiceType)Convert.ToInt32(tmp[0]); //LN can be used with HDLC if (((byte[])tmp[1]).Length == 6 && ((byte[])tmp[1])[5] == 0xFF) { Destination = GXCommon.ToLogicalName((byte[])tmp[1]); } else { Destination = (string)GXDLMSClient.ChangeType((byte[])tmp[1], DataType.String, settings.UseUtc2NormalTime); } Message = (MessageType)Convert.ToInt32(tmp[2]); } } else if (e.Index == 4) { CommunicationWindow.Clear(); if (e.Value is object[]) { foreach (object it in e.Value as object[]) { object[] tmp = it as object[]; GXDateTime start = GXDLMSClient.ChangeType((byte[])tmp[0], DataType.DateTime, settings.UseUtc2NormalTime) as GXDateTime; GXDateTime end = GXDLMSClient.ChangeType((byte[])tmp[1], DataType.DateTime, settings.UseUtc2NormalTime) as GXDateTime; CommunicationWindow.Add(new KeyValuePair <GXDateTime, GXDateTime>(start, end)); } } } else if (e.Index == 5) { RandomisationStartInterval = (ushort)e.Value; } else if (e.Index == 6) { NumberOfRetries = (byte)e.Value; } else if (e.Index == 7) { RepetitionDelay = (ushort)e.Value; } else { e.Error = ErrorCode.ReadWriteDenied; } }
/// <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; } } } } } } } }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { switch (e.Index) { case 1: LogicalName = GXCommon.ToLogicalName(e.Value); break; case 2: TotalAmountPaid = (Int32)e.Value; break; case 3: ChargeType = (ChargeType)Convert.ToByte(e.Value); break; case 4: Priority = (byte)e.Value; break; case 5: SetUnitCharge(UnitChargeActive, e.Value); break; case 6: SetUnitCharge(UnitChargePassive, e.Value); break; case 7: if (e.Value is GXDateTime) { UnitChargeActivationTime = (GXDateTime)e.Value; } else if (e.Value is byte[]) { UnitChargeActivationTime = (GXDateTime)GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime, settings != null && settings.UseUtc2NormalTime); } else if (e.Value is string) { UnitChargeActivationTime = new GXDateTime((string)e.Value); } else { UnitChargeActivationTime = null; } break; case 8: Period = (UInt32)e.Value; break; case 9: ChargeConfiguration = (ChargeConfiguration)Convert.ToInt32(e.Value); break; case 10: if (e.Value is GXDateTime) { LastCollectionTime = (GXDateTime)e.Value; } else if (e.Value is DateTime) { LastCollectionTime = (DateTime)e.Value; } else if (e.Value is byte[]) { LastCollectionTime = (GXDateTime)GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime, settings != null && settings.UseUtc2NormalTime); } else if (e.Value is string) { LastCollectionTime = new GXDateTime(e.Value as string); } else { LastCollectionTime = null; } break; case 11: LastCollectionAmount = (Int32)e.Value; break; case 12: TotalAmountRemaining = (Int32)e.Value; break; case 13: Proportion = (UInt16)e.Value; break; default: e.Error = ErrorCode.ReadWriteDenied; break; } }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { LogicalName = GXCommon.ToLogicalName(e.Value); } else if (e.Index == 2) { if (e.Value is byte[] v) { if (IsSec() || !GXByteBuffer.IsAsciiString(v)) { CalendarNameActive = GXCommon.ToHex(v, false); } else { CalendarNameActive = ASCIIEncoding.ASCII.GetString(v); } } else { CalendarNameActive = Convert.ToString(e.Value); } } else if (e.Index == 3) { SeasonProfileActive = SetSeasonProfile(settings, e.Value); } else if (e.Index == 4) { WeekProfileTableActive = SetWeekProfileTable(settings, e.Value); } else if (e.Index == 5) { DayProfileTableActive = SetDayProfileTable(settings, e.Value); } else if (e.Index == 6) { if (e.Value is byte[] v) { if (IsSec() || !GXByteBuffer.IsAsciiString(v)) { CalendarNamePassive = GXCommon.ToHex(v, false); } else { CalendarNamePassive = ASCIIEncoding.ASCII.GetString(v); } } else { CalendarNamePassive = Convert.ToString(e.Value); } } else if (e.Index == 7) { SeasonProfilePassive = SetSeasonProfile(settings, e.Value); } else if (e.Index == 8) { WeekProfileTablePassive = SetWeekProfileTable(settings, e.Value); } else if (e.Index == 9) { DayProfileTablePassive = SetDayProfileTable(settings, e.Value); } else if (e.Index == 10) { if (e.Value is byte[]) { Time = (GXDateTime)GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime, settings.UseUtc2NormalTime); } else { Time = new GXDateTime(Convert.ToDateTime(e.Value)); } } else { e.Error = ErrorCode.ReadWriteDenied; } }
private void SetBuffer(GXDLMSSettings settings, ValueEventArgs e) { List <GXKeyValuePair <GXDLMSObject, GXDLMSCaptureObject> > cols = null; if (e.Parameters is List <GXKeyValuePair <GXDLMSObject, GXDLMSCaptureObject> > ) { cols = (List <GXKeyValuePair <GXDLMSObject, GXDLMSCaptureObject> >)e.Parameters; } if (cols == null) { cols = CaptureObjects; } if (e.Value != null && (e.Value as object[]).Length != 0) { int index2 = 0; DateTime lastDate = DateTime.MinValue; foreach (object[] row in (e.Value as object[])) { if (cols.Count != 0) { if ((row as object[]).Length != cols.Count) { throw new Exception("The number of columns does not match."); } for (int pos = 0; pos != row.Length; ++pos) { if (cols == null) { index2 = 0; } else { index2 = cols[pos].Value.AttributeIndex; } DataType type; //Actaris SL 7000 and ACE 6000 returns 0. if (index2 > 0) { type = cols[pos].Key.GetUIDataType(index2); } else { type = DataType.None; } if (row[pos] is byte[]) { if (type != DataType.None && row[pos] is byte[]) { row[pos] = GXDLMSClient.ChangeType(row[pos] as byte[], type, settings.UseUtc2NormalTime); if (row[pos] is GXDateTime) { GXDateTime dt = (GXDateTime)row[pos]; lastDate = dt.Value.LocalDateTime; } } } else if (type == DataType.DateTime && row[pos] == null && CapturePeriod != 0) { if (lastDate == DateTime.MinValue && Buffer.Count != 0) { lastDate = ((GXDateTime)Buffer[Buffer.Count - 1].GetValue(pos)).Value.LocalDateTime; } if (lastDate != DateTime.MinValue) { lastDate = lastDate.AddSeconds(CapturePeriod); row[pos] = new GXDateTime(lastDate); } } else if (type == DataType.DateTime && row[pos] is UInt32) { row[pos] = GXDateTime.FromUnixTime(((UInt32)row[pos])); } if (cols[pos].Key is GXDLMSRegister && index2 == 2) { double scaler = (cols[pos].Key as GXDLMSRegister).Scaler; if (scaler != 1) { try { row[pos] = Convert.ToDouble(row[pos]) * scaler; } catch { //Skip error } } } else if (cols[pos].Key is GXDLMSDemandRegister && (index2 == 2 || index2 == 3)) { double scaler = (cols[pos].Key as GXDLMSDemandRegister).Scaler; if (scaler != 1) { try { row[pos] = Convert.ToDouble(row[pos]) * scaler; } catch { //Skip error } } } else if (cols[pos].Key is GXDLMSRegister && index2 == 3) { try { GXDLMSRegister r = new GXDLMSRegister(); ValueEventArgs v = new ValueEventArgs(r, 3, 0, null); v.Value = row[pos]; (r as IGXDLMSBase).SetValue(null, v); row[pos] = new object[] { r.Scaler, r.Unit }; } catch { //Skip error } } } } Buffer.Add(row); } EntriesInUse = Buffer.Count; } }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { switch (e.Index) { case 1: LogicalName = GXCommon.ToLogicalName(e.Value); break; case 2: if (e.Value is byte[]) { if (GXByteBuffer.IsAsciiString((byte[])e.Value)) { CalendarName = ASCIIEncoding.ASCII.GetString((byte[])e.Value); } else { CalendarName = GXCommon.ToHex((byte[])e.Value, true); } } else { CalendarName = Convert.ToString(e.Value); } break; case 3: Enabled = Convert.ToBoolean(e.Value); break; case 4: { if (e.Value is object[]) { object[] it = e.Value as object[]; Plan.DefaultTariffBand = Convert.ToByte(it[0]); UpdateSeason(Plan.WinterSeason, (it[1] as object[])[0] as object[]); UpdateSeason(Plan.SummerSeason, (it[1] as object[])[1] as object[]); Plan.WeeklyActivation = Convert.ToString(it[2]); List <UInt16> days = new List <ushort>(); foreach (UInt16 v in (object[])it[3]) { days.Add(v); } Plan.SpecialDays = days.ToArray(); } break; } case 5: { if (e.Value is object[]) { object[] it = e.Value as object[]; GXDateTime time = (GXDateTime)it[0]; time.Skip &= ~(DateTimeSkips.Year | DateTimeSkips.Month | DateTimeSkips.Day | DateTimeSkips.DayOfWeek); GXDateTime date = (GXDateTime)it[1]; date.Skip &= ~(DateTimeSkips.Hour | DateTimeSkips.Minute | DateTimeSkips.Second | DateTimeSkips.Ms); ActivationTime = new DLMS.GXDateTime(date); ActivationTime.Value = ActivationTime.Value.AddHours(time.Value.Hour); ActivationTime.Value = ActivationTime.Value.AddMinutes(time.Value.Minute); ActivationTime.Value = ActivationTime.Value.AddSeconds(time.Value.Second); ActivationTime.Skip = date.Skip | time.Skip; } else if (e.Value is string) { ActivationTime = new GXDateTime((string)e.Value); } else { ActivationTime = new GXDateTime(DateTime.MinValue); } break; } default: e.Error = ErrorCode.ReadWriteDenied; break; } }
private async void DoWork(object state) { _logger.LogWarning("Timed Background Service is working."); try { DateTime now = DateTime.Now; ListSchedulesResponse list = null; using (System.Net.Http.HttpResponseMessage response = await Helpers.client.PostAsJsonAsync(Startup.ServerAddress + "/api/schedule/ListSchedules", new ListSchedules())) { Helpers.CheckStatus(response); list = await response.Content.ReadAsAsync <ListSchedulesResponse>(); } List <GXTask> tasks = new List <GXTask>(); foreach (GXSchedule it in list.Schedules) { GXDateTime dt = new GXDateTime(it.Start); if (it.ExecutionTime == DateTime.MinValue) { it.ExecutionTime = now; } if (Equals(dt, now)) { _logger.LogTrace("+"); foreach (GXObject obj in it.Objects) { foreach (GXAttribute a in obj.Attributes) { GXTask t = new GXTask() { Object = obj, TaskType = TaskType.Read, Index = a.Index }; tasks.Add(t); } } it.ExecutionTime = now; UpdateScheduleExecutionTime us = new UpdateScheduleExecutionTime(); us.Id = it.Id; us.Time = now; using (System.Net.Http.HttpResponseMessage response = await Helpers.client.PostAsJsonAsync(Startup.ServerAddress + "/api/schedule/UpdateScheduleExecutionTime", us)) { Helpers.CheckStatus(response); UpdateScheduleExecutionTime r = await response.Content.ReadAsAsync <UpdateScheduleExecutionTime>(); } } else if (now.Minute == 0) { Console.WriteLine(dt.ToFormatString()); Console.WriteLine(now.ToString()); } } if (tasks.Count != 0) { AddTask at = new AddTask(); at.Actions = tasks.ToArray(); using (System.Net.Http.HttpResponseMessage response = await Helpers.client.PostAsJsonAsync(Startup.ServerAddress + "/api/task/AddTask", at)) { Helpers.CheckStatus(response); } } } catch (Exception ex) { _logger.LogInformation(ex.Message); } }
void IGXDLMSBase.Save(GXXmlWriter writer) { if (Buffer != null) { writer.WriteStartElement("Buffer"); GXDateTime lastdt = null; int add = CapturePeriod; //Some meters are returning 0 if capture period is one hour. if (add == 0) { add = 60; } foreach (object[] row in Buffer) { writer.WriteStartElement("Row"); int pos = 0; foreach (object it in row) { //If capture objects is not read. if (CaptureObjects.Count > pos) { GXKeyValuePair <GXDLMSObject, GXDLMSCaptureObject> c = CaptureObjects[pos]; ++pos; if (CaptureObjects != null && c.Key is GXDLMSClock && c.Value.AttributeIndex == 2) { if (it != null) { lastdt = (c.Key as GXDLMSClock).Time; } else if (lastdt != null) { lastdt = new GXDateTime(lastdt.Value.AddMinutes(add)); writer.WriteElementObject("Cell", lastdt, false); continue; } else { writer.WriteElementObject("Cell", DateTime.MinValue, false); } } } writer.WriteElementObject("Cell", it, false); } writer.WriteEndElement(); } writer.WriteEndElement(); } if (CaptureObjects != null) { writer.WriteStartElement("CaptureObjects"); foreach (GXKeyValuePair <GXDLMSObject, GXDLMSCaptureObject> it in CaptureObjects) { writer.WriteStartElement("Item"); writer.WriteElementString("ObjectType", (int)it.Key.ObjectType); writer.WriteElementString("LN", it.Key.LogicalName); writer.WriteElementString("Attribute", it.Value.AttributeIndex); writer.WriteElementString("Data", it.Value.DataIndex); writer.WriteEndElement(); } writer.WriteEndElement(); } writer.WriteElementString("CapturePeriod", CapturePeriod); writer.WriteElementString("SortMethod", (int)SortMethod); if (SortObject != null) { writer.WriteStartElement("SortObject"); writer.WriteElementString("ObjectType", (int)SortObject.ObjectType); writer.WriteElementString("LN", SortObject.LogicalName); writer.WriteEndElement();//SortObject } writer.WriteElementString("EntriesInUse", EntriesInUse); writer.WriteElementString("ProfileEntries", ProfileEntries); }
/// <summary> /// Read data from the meter. /// </summary> private static void ReadMeter(object parameter) { GXDLMSReader reader = null; System.Net.Http.HttpClient httpClient = Helpers.client; using (GXNet media = (GXNet)parameter) { try { var config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: true) .Build(); ListenerOptions listener = config.GetSection("Listener").Get <ListenerOptions>(); GXDLMSObjectCollection objects = new GXDLMSObjectCollection(); GXDLMSSecureClient client = new GXDLMSSecureClient(listener.UseLogicalNameReferencing, listener.ClientAddress, listener.ServerAddress, (Authentication)listener.Authentication, listener.Password, (InterfaceType)listener.Interface); reader = new GXDLMSReader(client, media, _logger); GXDLMSData ldn = new GXDLMSData("0.0.42.0.0.255"); ldn.SetUIDataType(2, DataType.String); reader.InitializeConnection(); reader.Read(ldn, 2); Console.WriteLine("Meter connected: " + ldn.Value); //Find device. GXDevice dev = null; ListDevicesResponse devs = null; { using (System.Net.Http.HttpResponseMessage response = httpClient.PostAsJsonAsync(Startup.ServerAddress + "/api/device/ListDevices", new ListDevices() { Name = (string)ldn.Value }).Result) { Helpers.CheckStatus(response); devs = response.Content.ReadAsAsync <ListDevicesResponse>().Result; } //If device is unknown. if (devs.Devices.Length == 0) { if (listener.DefaultDeviceTemplate == 0) { string str = "Unknown Meter try to connect to the Gurux.DLMS.AMI server: " + ldn.Value; Console.WriteLine(str); AddSystemError info = new AddSystemError(); info.Error = new GXSystemError() { Error = str }; using (System.Net.Http.HttpResponseMessage response = httpClient.PostAsJsonAsync(Startup.ServerAddress + "/api/SystemError/AddSystemError", info).Result) { Helpers.CheckStatus(response); } return; } ListDeviceTemplates lt = new ListDeviceTemplates() { Ids = new UInt64[] { listener.DefaultDeviceTemplate } }; using (System.Net.Http.HttpResponseMessage response = httpClient.PostAsJsonAsync(Startup.ServerAddress + "/api/template/ListDeviceTemplates", lt).Result) { Helpers.CheckStatus(response); ListDeviceTemplatesResponse ret = response.Content.ReadAsAsync <ListDeviceTemplatesResponse>().Result; if (ret.Devices.Length != 1) { throw new Exception("DefaultDeviceTemplate value is invalid: " + listener.DefaultDeviceTemplate); } dev = new GXDevice(); GXDevice.Copy(dev, ret.Devices[0]); dev.Name = Convert.ToString(ldn.Value); dev.TemplateId = listener.DefaultDeviceTemplate; dev.Manufacturer = ret.Devices[0].Name; } dev.Dynamic = true; UpdateDevice update = new UpdateDevice(); update.Device = dev; using (System.Net.Http.HttpResponseMessage response = httpClient.PostAsJsonAsync(Startup.ServerAddress + "/api/device/UpdateDevice", update).Result) { Helpers.CheckStatus(response); UpdateDeviceResponse r = response.Content.ReadAsAsync <UpdateDeviceResponse>().Result; dev.Id = r.DeviceId; } using (System.Net.Http.HttpResponseMessage response = httpClient.PostAsJsonAsync(Startup.ServerAddress + "/api/device/ListDevices", new ListDevices() { Ids = new UInt64[] { dev.Id } }).Result) { Helpers.CheckStatus(response); devs = response.Content.ReadAsAsync <ListDevicesResponse>().Result; } } else if (devs.Devices.Length != 1) { throw new Exception("There are multiple devices with same name: " + ldn.Value); } else { dev = devs.Devices[0]; if (dev.Security != Security.None) { Console.WriteLine("Reading frame counter."); GXDLMSData fc = new GXDLMSData(listener.InvocationCounter); reader.Read(fc, 2); dev.InvocationCounter = 1 + Convert.ToUInt32(fc.Value); Console.WriteLine("Device ID: " + dev.Id + " LDN: " + (string)ldn.Value); Console.WriteLine("Frame counter: " + dev.FrameCounter); } GetNextTaskResponse ret; using (System.Net.Http.HttpResponseMessage response = httpClient.PostAsJsonAsync(Startup.ServerAddress + "/api/task/GetNextTask", new GetNextTask() { Listener = true, DeviceId = dev.Id }).Result) { Helpers.CheckStatus(response); ret = response.Content.ReadAsAsync <GetNextTaskResponse>().Result; } if (ret.Tasks == null || ret.Tasks.Length == 0) { Console.WriteLine("No tasks to execute"); } else { Console.WriteLine("Task count: " + ret.Tasks.Length); if (client.ClientAddress != dev.ClientAddress || dev.Security != Security.None) { reader.Release(); reader.Disconnect(); client = new GXDLMSSecureClient(dev.UseLogicalNameReferencing, dev.ClientAddress, dev.PhysicalAddress, (Authentication)dev.Authentication, dev.Password, dev.InterfaceType); client.UseUtc2NormalTime = dev.UtcTimeZone; client.Standard = (Standard)dev.Standard; if (dev.Conformance != 0) { client.ProposedConformance = (Conformance)dev.Conformance; } client.Priority = dev.Priority; client.ServiceClass = dev.ServiceClass; client.Ciphering.SystemTitle = GXCommon.HexToBytes(dev.ClientSystemTitle); client.Ciphering.BlockCipherKey = GXCommon.HexToBytes(dev.BlockCipherKey); client.Ciphering.AuthenticationKey = GXCommon.HexToBytes(dev.AuthenticationKey); client.ServerSystemTitle = GXCommon.HexToBytes(dev.DeviceSystemTitle); client.Ciphering.InvocationCounter = dev.InvocationCounter; client.Ciphering.Security = (Security)dev.Security; reader = new GXDLMSReader(client, media, _logger); reader.InitializeConnection(); } List <GXValue> values = new List <GXValue>(); foreach (GXTask task in ret.Tasks) { GXDLMSObject obj = GXDLMSClient.CreateObject((ObjectType)task.Object.ObjectType); obj.LogicalName = task.Object.LogicalName; try { if (task.TaskType == TaskType.Write) { if (obj.LogicalName == "0.0.1.1.0.255" && task.Index == 2) { client.UpdateValue(obj, task.Index, GXDateTime.ToUnixTime(DateTime.UtcNow)); } else { client.UpdateValue(obj, task.Index, GXDLMSTranslator.XmlToValue(task.Data)); } reader.Write(obj, task.Index); } else if (task.TaskType == TaskType.Action) { reader.Method(obj, task.Index, GXDLMSTranslator.XmlToValue(task.Data), DataType.None); } else if (task.TaskType == TaskType.Read) { //Reading the meter. if (task.Object.Attributes[0].DataType != 0) { obj.SetDataType(task.Index, (DataType)task.Object.Attributes[0].DataType); } if (task.Object.Attributes[0].UIDataType != 0) { obj.SetUIDataType(task.Index, (DataType)task.Object.Attributes[0].UIDataType); } Reader.Reader.Read(null, httpClient, reader, task, media, obj); if (task.Object.Attributes[0].DataType == 0) { task.Object.Attributes[0].DataType = (int)obj.GetDataType(task.Index); if (task.Object.Attributes[0].UIDataType == 0) { task.Object.Attributes[0].UIDataType = (int)obj.GetUIDataType(task.Index); } UpdateDatatype u = new UpdateDatatype() { Items = new GXAttribute[] { task.Object.Attributes[0] } }; using (System.Net.Http.HttpResponseMessage response = httpClient.PostAsJsonAsync(Startup.ServerAddress + "/api/Object/UpdateDatatype", u).Result) { Helpers.CheckStatus(response); } } } } catch (Exception ex) { task.Result = ex.Message; AddError error = new AddError(); error.Error = new GXError() { DeviceId = dev.Id, Error = "Failed to " + task.TaskType + " " + task.Object.LogicalName + ":" + task.Index + ". " + ex.Message }; using (System.Net.Http.HttpResponseMessage response = httpClient.PostAsJsonAsync(Startup.ServerAddress + "/api/error/AddError", error).Result) { Helpers.CheckStatus(response); response.Content.ReadAsAsync <AddErrorResponse>(); } } using (System.Net.Http.HttpResponseMessage response = httpClient.PostAsJsonAsync(Startup.ServerAddress + "/api/task/TaskReady", new TaskReady() { Tasks = new GXTask[] { task } }).Result) { Helpers.CheckStatus(response); } } } } } } catch (Exception ex) { try { AddSystemError info = new AddSystemError(); info.Error = new GXSystemError() { Error = ex.Message }; using (System.Net.Http.HttpResponseMessage response = httpClient.PostAsJsonAsync(Startup.ServerAddress + "/api/SystemError/AddSystemError", info).Result) { Helpers.CheckStatus(response); } } catch (Exception ex2) { } } finally { if (reader != null) { reader.Close(); } } } }
///<summary> ///Get date and time from DLMS data. ///</summary> ///<param name="settings">DLMS settings.</param> ///<param name="buff">Received DLMS data.</param> ///<param name="info">Data info.</param> ///<returns> ///Parsed date and time. ///</returns> private static object GetDateTime(GXDLMSSettings settings, GXByteBuffer buff, GXDataInfo info) { // If there is not enough data available. if (buff.Size - buff.Position < 12) { //If time. if (buff.Size - buff.Position < 5) { return GetTime(buff, info); } //If date. else if (buff.Size - buff.Position < 6) { return GetDate(buff, info); } info.Complete = false; return null; } if (info.xml != null) { info.xml.AppendLine(info.xml.GetDataType(info.Type), "Value", GXCommon.ToHex(buff.Data, false, buff.Position, 12)); } GXDateTime dt = new GXDateTime(); //Get year. int year = buff.GetUInt16(); if (year == 0xFFFF || year == 0) { year = DateTime.Now.Year; dt.Skip |= DateTimeSkips.Year; } //Get month int month = buff.GetUInt8(); if (month == 0 || month == 0xFF || month == 0xFE || month == 0xFD) { month = 1; dt.Skip |= DateTimeSkips.Month; } int day = buff.GetUInt8(); if (day < 1 || day == 0xFF) { day = 1; dt.Skip |= DateTimeSkips.Day; } else if (day == 0xFD || day == 0xFE) { day = DateTime.DaysInMonth(year, month) + (sbyte)day + 2; } //Skip week day if (buff.GetUInt8() == 0xFF) { dt.Skip |= DateTimeSkips.DayOfWeek; } //Get time. int hours = buff.GetUInt8(); if (hours == 0xFF) { hours = 0; dt.Skip |= DateTimeSkips.Hour; } int minutes = buff.GetUInt8(); if (minutes == 0xFF) { minutes = 0; dt.Skip |= DateTimeSkips.Minute; } int seconds = buff.GetUInt8(); if (seconds == 0xFF) { seconds = 0; dt.Skip |= DateTimeSkips.Second; } int milliseconds = buff.GetUInt8(); if (milliseconds != 0xFF) { milliseconds *= 10; } else { milliseconds = 0; dt.Skip |= DateTimeSkips.Ms; } int deviation = buff.GetInt16(); dt.Status = (ClockStatus)buff.GetUInt8(); if (settings != null && settings.UtcTimeZone) { deviation = -deviation; } dt.Deviation = deviation; //0x8000 == -32768 //deviation = -1 if skipped. if (deviation != -1 && deviation != -32768 && year != 1 && (dt.Skip & DateTimeSkips.Year) == 0) { dt.Value = new DateTimeOffset(new DateTime(year, month, day, hours, minutes, seconds, milliseconds), new TimeSpan(0, -deviation, 0)); } else //Use current time if deviation is not defined. { dt.Skip |= DateTimeSkips.Devitation; DateTime tmp = new DateTime(year, month, day, hours, minutes, seconds, milliseconds, DateTimeKind.Local); dt.Value = new DateTimeOffset(tmp, TimeZoneInfo.Local.GetUtcOffset(tmp)); } return dt; }
///<summary> ///Convert date time to DLMS bytes. ///</summary> ///<param name="buff"> ///Byte buffer where data is write. ///</param> ///<param name="value"> ///Added value. ///</param> private static void SetDateTime(GXDLMSSettings settings, GXByteBuffer buff, object value) { GXDateTime dt; if (value is GXDateTime) { dt = (GXDateTime)value; } else if (value is DateTime) { dt = new GXDateTime((DateTime)value); dt.Skip = dt.Skip | DateTimeSkips.Ms; } else if (value is string) { dt = new GXDateTime(DateTime.Parse((string)value)); dt.Skip = dt.Skip | DateTimeSkips.Ms; } else { throw new Exception("Invalid date format."); } if (dt.Value.UtcDateTime == DateTime.MinValue) { dt.Value = DateTime.SpecifyKind(new DateTime(2000, 1, 1).Date, DateTimeKind.Utc); } else if (dt.Value.UtcDateTime == DateTime.MaxValue) { dt.Value = DateTime.SpecifyKind(DateTime.Now.AddYears(1).Date, DateTimeKind.Utc); } DateTimeOffset tm = dt.Value; if ((dt.Skip & DateTimeSkips.Year) == 0) { buff.SetUInt16((ushort)tm.Year); } else { buff.SetUInt16(0xFFFF); } if ((dt.Skip & DateTimeSkips.Month) == 0) { if (dt.DaylightSavingsBegin) { buff.SetUInt8(0xFE); } else if (dt.DaylightSavingsEnd) { buff.SetUInt8(0xFD); } else { buff.SetUInt8((byte)tm.Month); } } else { buff.SetUInt8(0xFF); } if ((dt.Skip & DateTimeSkips.Day) == 0) { buff.SetUInt8((byte)tm.Day); } else { buff.SetUInt8(0xFF); } // Add week day if ((dt.Skip & DateTimeSkips.DayOfWeek) != 0) { buff.SetUInt8(0xFF); } else { if (dt.Value.DayOfWeek == DayOfWeek.Sunday) { buff.SetUInt8(7); } else { buff.SetUInt8((byte)(dt.Value.DayOfWeek)); } } //Add time. if ((dt.Skip & DateTimeSkips.Hour) == 0) { buff.SetUInt8((byte)tm.Hour); } else { buff.SetUInt8(0xFF); } if ((dt.Skip & DateTimeSkips.Minute) == 0) { buff.SetUInt8((byte)tm.Minute); } else { buff.SetUInt8(0xFF); } if ((dt.Skip & DateTimeSkips.Second) == 0) { buff.SetUInt8((byte)tm.Second); } else { buff.SetUInt8(0xFF); } if ((dt.Skip & DateTimeSkips.Ms) == 0) { buff.SetUInt8((byte)(tm.Millisecond / 10)); } else { buff.SetUInt8((byte)0xFF); //Hundredths of second is not used. } //Add deviation. if ((dt.Skip & DateTimeSkips.Devitation) == 0) { if (settings != null && settings.UtcTimeZone) { buff.SetInt16((Int16)(dt.Value.Offset.TotalMinutes)); } else { buff.SetInt16((Int16)(-dt.Value.Offset.TotalMinutes)); } } else //deviation not used. { buff.SetUInt16(0x8000); } //Add clock_status if (dt.Value.LocalDateTime.IsDaylightSavingTime()) { buff.SetUInt8((byte)(dt.Status | ClockStatus.DaylightSavingActive)); } else { buff.SetUInt8((byte)dt.Status); } }
/// <summary> /// Constructor. /// </summary> /// <param name="ln">Logical Name of the object.</param> /// <param name="sn">Short Name of the object.</param> public GXDLMSClock(string ln, ushort sn) : base(ObjectType.Clock, ln, sn) { Time = new GXDateTime(DateTime.MinValue); }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { switch (e.Index) { case 1: LogicalName = GXCommon.ToLogicalName(e.Value); break; case 2: CurrentCreditAmount = (int)e.Value; break; case 3: Type = (CreditType)(byte)e.Value; break; case 4: Priority = (byte)e.Value; break; case 5: WarningThreshold = (int)e.Value; break; case 6: Limit = (int)e.Value; break; case 7: if ((string)e.Value == "") { CreditConfiguration = (CreditConfiguration)0; } else { GXByteBuffer bb = new GXByteBuffer(); GXCommon.SetBitString(bb, e.Value, true); CreditConfiguration = (CreditConfiguration)bb.GetUInt8(1); } break; case 8: Status = (CreditStatus)(byte)e.Value; break; case 9: PresetCreditAmount = (int)e.Value; break; case 10: CreditAvailableThreshold = (int)e.Value; break; case 11: if (e.Value == null) { Period = new GXDateTime(DateTime.MinValue); } else { if (e.Value is byte[]) { e.Value = GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime, settings.UseUtc2NormalTime); } else if (e.Value is string) { e.Value = new GXDateTime((string)e.Value); } if (e.Value is GXDateTime) { Period = (GXDateTime)e.Value; } } break; default: e.Error = ErrorCode.ReadWriteDenied; break; } }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, int index, object value) { if (index == 1) { if (value is string) { LogicalName = value.ToString(); } else { LogicalName = GXDLMSClient.ChangeType((byte[])value, DataType.OctetString).ToString(); } } else if (index == 2) { if (Scaler != 1) { try { CurrentAverageValue = Convert.ToDouble(value) * Scaler; } catch (Exception) { //Sometimes scaler is set for wrong Object type. CurrentAverageValue = value; } } else { CurrentAverageValue = value; } } else if (index == 3) { if (Scaler != 1) { try { LastAverageValue = Convert.ToDouble(value) * Scaler; } catch (Exception) { //Sometimes scaler is set for wrong Object type. LastAverageValue = value; } } else { LastAverageValue = value; } } else if (index == 4) { if (value == null) { Scaler = 1; Unit = Unit.None; } else { object[] arr = (object[])value; if (arr.Length != 2) { throw new Exception("setValue failed. Invalid scaler unit value."); } _scaler = Convert.ToInt32(arr[0]); Unit = (Unit)Convert.ToInt32(arr[1]); } } else if (index == 5) { Status = Convert.ToInt32(value); } else if (index == 6) { if (value == null) { CaptureTime = new GXDateTime(DateTime.MinValue); } else { if (value is byte[]) { value = GXDLMSClient.ChangeType((byte[])value, DataType.DateTime); } CaptureTime = (GXDateTime)value; } } else if (index == 7) { if (value == null) { StartTimeCurrent = new GXDateTime(DateTime.MinValue); } else { if (value is byte[]) { value = GXDLMSClient.ChangeType((byte[])value, DataType.DateTime); } StartTimeCurrent = (GXDateTime)value; } } else if (index == 8) { Period = Convert.ToUInt32(value); } else if (index == 9) { NumberOfPeriods = Convert.ToUInt16(value); } else { throw new ArgumentException("SetValue failed. Invalid attribute index."); } }
/// <summary> /// Constructor. /// </summary> public GXDLMSSeasonProfile(string name, GXDateTime start, string weekName) { Name = name; Start = start; WeekName = weekName; }
///<summary> ///Convert date to DLMS bytes. ///</summary> ///<param name="buff"> ///Byte buffer where data is write. ///</param> ///<param name="value"> ///Added value. ///</param> private static void SetDate(GXByteBuffer buff, object value) { GXDateTime dt; if (value is GXDateTime) { dt = (GXDateTime)value; } else if (value is DateTime) { dt = new GXDateTime((DateTime)value); } else if (value is DateTimeOffset) { dt = new GXDateTime((DateTimeOffset)value); } else if (value is string) { dt = DateTime.Parse((string)value); } else { throw new Exception("Invalid date format."); } // Add year. if ((dt.Skip & DateTimeSkips.Year) != 0) { buff.SetUInt16(0xFFFF); } else { buff.SetUInt16((UInt16)dt.Value.Year); } // Add month if (dt.DaylightSavingsBegin) { buff.SetUInt8(0xFE); } else if (dt.DaylightSavingsEnd) { buff.SetUInt8(0xFD); } else if ((dt.Skip & DateTimeSkips.Month) != 0) { buff.SetUInt8(0xFF); } else { buff.SetUInt8((byte)dt.Value.Month); } // Add day if ((dt.Skip & DateTimeSkips.Day) != 0) { buff.SetUInt8(0xFF); } else { buff.SetUInt8((byte)dt.Value.Day); } // Add week day if ((dt.Skip & DateTimeSkips.DayOfWeek) != 0) { buff.SetUInt8(0xFF); } else { if (dt.Value.DayOfWeek == DayOfWeek.Sunday) { buff.SetUInt8(7); } else { buff.SetUInt8((byte)(dt.Value.DayOfWeek)); } } }
void IGXDLMSBase.SetValue(int index, object value) { if (index == 1) { if (value is string) { LogicalName = value.ToString(); } else { LogicalName = GXDLMSClient.ChangeType((byte[])value, DataType.OctetString).ToString(); } } else if (index == 2) { if (CaptureObjects == null || CaptureObjects.Count == 0) { throw new Exception("Read capture objects first."); } if (value != null && (value as object[]).Length != 0) { DateTime lastDate = DateTime.MinValue; foreach (object[] row in (value as object[])) { if ((row as object[]).Length != CaptureObjects.Count) { throw new Exception("Number of columns do not match."); } for (int pos = 0; pos != row.Length; ++pos) { DataType type = CaptureObjects[pos].Key.GetUIDataType(CaptureObjects[pos].Value.AttributeIndex); if (row[pos] is byte[]) { if (type != DataType.None && row[pos] is byte[]) { row[pos] = GXDLMSClient.ChangeType(row[pos] as byte[], type); if (row[pos] is GXDateTime) { GXDateTime dt = (GXDateTime)row[pos]; lastDate = dt.Value; } } } else if (type == DataType.DateTime && row[pos] == null && CapturePeriod != 0) { if (lastDate == DateTime.MinValue && Buffer.Count != 0) { lastDate = ((GXDateTime)Buffer[Buffer.Count - 1].GetValue(pos)).Value; } if (lastDate != DateTime.MinValue) { lastDate = lastDate.AddSeconds(CapturePeriod); row[pos] = new GXDateTime(lastDate); } } if (CaptureObjects[pos].Key is GXDLMSRegister && CaptureObjects[pos].Value.AttributeIndex == 2) { double scaler = (CaptureObjects[pos].Key as GXDLMSRegister).Scaler; if (scaler != 1) { try { row[pos] = Convert.ToDouble(row[pos]) * scaler; } catch { //Skip error } } } } Buffer.Add(row); } EntriesInUse = Buffer.Count; } } else if (index == 3) { Buffer.Clear(); EntriesInUse = 0; CaptureObjects.Clear(); GXDLMSObjectCollection objects = new GXDLMSObjectCollection(); foreach (object it in value as object[]) { object[] tmp = it as object[]; if (tmp.Length != 4) { throw new GXDLMSException("Invalid structure format."); } ObjectType type = (ObjectType)Convert.ToInt16(tmp[0]); string ln = GXDLMSObject.toLogicalName((byte[])tmp[1]); int attributeIndex = Convert.ToInt16(tmp[2]); int dataIndex = Convert.ToInt16(tmp[3]); GXDLMSObject obj = null; if (Parent != null) { obj = Parent.FindByLN(type, ln); } if (obj == null) { obj = GXDLMSClient.CreateDLMSObject((int)type, null, 0, ln, 0); } CaptureObjects.Add(new GXKeyValuePair <GXDLMSObject, GXDLMSCaptureObject>(obj, new GXDLMSCaptureObject(attributeIndex, dataIndex))); objects.Add(obj); } GXDLMSClient.UpdateOBISCodes(objects); } else if (index == 4) { CapturePeriod = Convert.ToInt32(value); } else if (index == 5) { SortMethod = (SortMethod)Convert.ToInt32(value); } else if (index == 6) { if (value != null) { object[] tmp = value as object[]; if (tmp.Length != 4) { throw new GXDLMSException("Invalid structure format."); } ObjectType type = (ObjectType)Convert.ToInt16(tmp[0]); string ln = GXDLMSObject.toLogicalName((byte[])tmp[1]); SortAttributeIndex = Convert.ToInt16(tmp[2]); SortDataIndex = Convert.ToInt16(tmp[3]); SortObject = null; foreach (var it in CaptureObjects) { if (it.Key.ObjectType == type && it.Key.LogicalName == ln) { SortObject = it.Key; break; } } } else { SortObject = null; } } else if (index == 7) { EntriesInUse = Convert.ToInt32(value); } else if (index == 8) { ProfileEntries = Convert.ToInt32(value); } else { throw new ArgumentException("SetValue failed. Invalid attribute index."); } }
/// <summary> /// Constructor. /// </summary> public GXDLMSSeasonProfile(byte[] name, GXDateTime start, GXDLMSWeekProfile weekProfile) { Name = name; Start = start; WeekName = weekProfile.Name; }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { switch (e.Index) { case 1: LogicalName = GXCommon.ToLogicalName(e.Value); break; case 2: { ChangedParameter = new GXDLMSTarget(); List <object> tmp = null; if (e.Value is List <object> ) { tmp = (List <object>)e.Value; } else if (e.Value is object[]) { tmp = new List <object>((object[])e.Value); } if (tmp != null) { if (tmp.Count != 4) { throw new GXDLMSException("Invalid structure format."); } ObjectType type = (ObjectType)Convert.ToInt16(tmp[0]); ChangedParameter.Target = settings.Objects.FindByLN(type, (byte[])tmp[1]); if (ChangedParameter.Target == null) { ChangedParameter.Target = GXDLMSClient.CreateObject(type); ChangedParameter.Target.LogicalName = GXCommon.ToLogicalName((byte[])tmp[1]); } ChangedParameter.AttributeIndex = Convert.ToByte(tmp[2]); ChangedParameter.Value = tmp[3]; } break; } case 3: { if (e.Value == null) { CaptureTime = new GXDateTime(DateTime.MinValue); } else { if (e.Value is byte[]) { e.Value = GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime, settings.UseUtc2NormalTime); } else if (e.Value is string) { e.Value = new GXDateTime((string)e.Value); } if (e.Value is GXDateTime) { CaptureTime = (GXDateTime)e.Value; } else if (e.Value is String) { DateTime tm; if (!DateTime.TryParse((String)e.Value, out tm)) { CaptureTime = DateTime.ParseExact((String)e.Value, CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern + " " + CultureInfo.CurrentCulture.DateTimeFormat.LongTimePattern, CultureInfo.CurrentUICulture); } else { CaptureTime = tm; } } else { CaptureTime = Convert.ToDateTime(e.Value); } } break; } case 4: { Parameters.Clear(); if (e.Value != null) { foreach (object it in e.Value as IEnumerable <object> ) { List <object> tmp; if (it is List <object> ) { tmp = (List <object>)it; } else { tmp = new List <object>((object[])it); } if (tmp.Count != 3) { throw new GXDLMSException("Invalid structure format."); } GXDLMSTarget obj = new GXDLMSTarget(); ObjectType type = (ObjectType)Convert.ToInt16(tmp[0]); obj.Target = settings.Objects.FindByLN(type, (byte[])tmp[1]); if (obj.Target == null) { obj.Target = GXDLMSClient.CreateObject(type); obj.Target.LogicalName = GXCommon.ToLogicalName((byte[])tmp[1]); } obj.AttributeIndex = Convert.ToByte(tmp[2]); Parameters.Add(obj); } } break; } default: e.Error = ErrorCode.ReadWriteDenied; break; } }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { if (e.Value is string) { LogicalName = e.Value.ToString(); } else { LogicalName = GXDLMSClient.ChangeType((byte[])e.Value, DataType.OctetString).ToString(); } } else if (e.Index == 2) { ListeningWindow.Clear(); if (e.Value is Object[]) { foreach (object it in e.Value as Object[]) { Object[] tmp = it as Object[]; GXDateTime start = GXDLMSClient.ChangeType((byte[])tmp[0], DataType.DateTime) as GXDateTime; GXDateTime end = GXDLMSClient.ChangeType((byte[])tmp[1], DataType.DateTime) as GXDateTime; ListeningWindow.Add(new KeyValuePair <GXDateTime, GXDateTime>(start, end)); } } } else if (e.Index == 3) { if (e.Value is Object[]) { List <string> tmp = new List <string>(); foreach (object it in e.Value as Object[]) { tmp.Add(ASCIIEncoding.ASCII.GetString((byte[])it)); } AllowedSenders = tmp.ToArray(); } else { AllowedSenders = new string[0]; } } else if (e.Index == 4) { SendersAndActions.Clear(); if (e.Value is Object[]) { foreach (object it in e.Value as Object[]) { Object[] tmp = it as Object[]; string id = ASCIIEncoding.ASCII.GetString((byte[])tmp[0]); Object[] tmp2 = tmp[1] as Object[]; /*TODO: * KeyValuePair<int, GXDLMSScriptAction> executed_script = new KeyValuePair<int, GXDLMSScriptAction>(Convert.ToInt32(tmp2[1], tmp2[2])); * SendersAndActions.Add(new KeyValuePair<string, KeyValuePair<int, GXDLMSScriptAction>>(id, tmp[1] as GXDateTime)); * */ } } } else { e.Error = ErrorCode.ReadWriteDenied; } }
static byte[] GetDateTime(GXDateTime dt) { if (dt.Value == DateTime.MinValue) { dt.Value = DateTime.SpecifyKind(new DateTime(2000, 1, 1).Date, DateTimeKind.Utc); } else if (dt.Value == DateTime.MaxValue) { dt.Value = DateTime.SpecifyKind(DateTime.Now.AddYears(1).Date, DateTimeKind.Utc); } DateTime tm; //If used normal time. if ((dt.Skip & DateTimeSkips.Devitation) == 0) { tm = dt.Value; } else //If devitation is skipped. { //If value is given as UTC time. if (TimeZone.CurrentTimeZone.GetUtcOffset(dt.Value).TotalMinutes == 0) { tm = dt.Value; } else { tm = dt.Value.ToUniversalTime(); } } List<byte> tmp = new List<byte>(); //Add size tmp.Add(12); if ((dt.Skip & DateTimeSkips.Year) == 0) { GXCommon.SetUInt16((ushort)tm.Year, tmp); } else { GXCommon.SetUInt16((ushort)0xFFFF, tmp); } if ((dt.Skip & DateTimeSkips.Month) == 0) { if (dt.DaylightSavingsBegin) { tmp.Add(0xFE); } else if (dt.DaylightSavingsEnd) { tmp.Add(0xFD); } else { tmp.Add((byte)tm.Month); } } else { tmp.Add(0xFF); } if ((dt.Skip & DateTimeSkips.Day) == 0) { tmp.Add((byte)tm.Day); } else { tmp.Add(0xFF); } //Week day is not spesified. //Standard defines. tmp.Add(0xFF); tmp.Add(0xFF); //Add time. if ((dt.Skip & DateTimeSkips.Hour) == 0) { tmp.Add((byte)tm.Hour); } else { tmp.Add(0xFF); } if ((dt.Skip & DateTimeSkips.Minute) == 0) { tmp.Add((byte)tm.Minute); } else { tmp.Add(0xFF); } if ((dt.Skip & DateTimeSkips.Second) == 0) { tmp.Add((byte)tm.Second); } else { tmp.Add(0xFF); } if ((dt.Skip & DateTimeSkips.Ms) == 0) { tmp.Add((byte)(tm.Millisecond / 10)); } else { tmp.Add((byte)0xFF); //Hundredths of second is not used. } //Add deviation. if ((dt.Skip & DateTimeSkips.Devitation) == 0) { short devitation = (short)TimeZone.CurrentTimeZone.GetUtcOffset(dt.Value).TotalMinutes; GXCommon.SetInt16(devitation, tmp); } else //deviation not used. { tmp.Add((byte)0x00); tmp.Add((byte)0x00); } //Add clock_status tmp.Add((byte)dt.Status); return tmp.ToArray(); }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { switch (e.Index) { case 1: LogicalName = GXCommon.ToLogicalName(e.Value); break; case 2: if (e.Value is byte[]) { Operator = ASCIIEncoding.ASCII.GetString((byte[])e.Value); } else { Operator = (string)e.Value; } break; case 3: Status = (GsmStatus)(byte)e.Value; break; case 4: CircuitSwitchStatus = (GsmCircuitSwitchStatus)(byte)e.Value; break; case 5: PacketSwitchStatus = (GsmPacketSwitchStatus)(byte)e.Value; break; case 6: if (e.Value != null) { object[] tmp = (object[])e.Value; CellInfo.CellId = Convert.ToUInt32(tmp[0]); CellInfo.LocationId = (UInt16)tmp[1]; CellInfo.SignalQuality = (byte)tmp[2]; CellInfo.Ber = (byte)tmp[3]; if (Version > 0) { CellInfo.MobileCountryCode = (UInt16)tmp[4]; CellInfo.MobileNetworkCode = (UInt16)tmp[5]; CellInfo.ChannelNumber = (UInt32)tmp[6]; } } break; case 7: AdjacentCells.Clear(); if (e.Value != null) { foreach (object it in (object[])e.Value) { object[] tmp = (object[])it; AdjacentCell ac = new Objects.AdjacentCell(); ac.CellId = Convert.ToUInt32(tmp[0]); ac.SignalQuality = (byte)tmp[1]; AdjacentCells.Add(ac); } } break; case 8: if (e.Value is byte[]) { e.Value = GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime, settings.UseUtc2NormalTime); } else if (e.Value is string) { e.Value = new GXDateTime((string)e.Value); } CaptureTime = (GXDateTime)e.Value; break; default: e.Error = ErrorCode.ReadWriteDenied; break; } }
/// <summary> /// Reserved for internal use. /// </summary> internal static object GetData(byte[] buff, ref int pos, ActionType action, out int count, out int index, ref DataType type, ref int cachePosition) { count = 0; index = 0; object value = null; if (pos == buff.Length) { pos = -1; return null; } bool knownType = type != DataType.None; if (!knownType) { type = (DataType)buff[pos++]; } if (type == DataType.None) { return value; } if (pos == buff.Length) { pos = -1; return null; } int size = buff.Length - pos; if (type == DataType.Array || type == DataType.Structure) { count = GXCommon.GetObjectCount(buff, ref pos); if (action == ActionType.Count) { return value; //Don't go further. Only object's count is resolved. } if (cachePosition > pos) { pos = cachePosition; } size = buff.Length - pos; if (count != 0 && size < 1) { pos = -1; return null; } List<object> arr = new List<object>(count); for (index = 0; index != count; ++index) { DataType itemType = DataType.None; int colCount, colIndex; int tmpPos = 0; object tmp = GetData(buff, ref pos, ActionType.None, out colCount, out colIndex, ref itemType, ref tmpPos); if (colCount == colIndex && pos != -1) { arr.Add(tmp); } if (pos == -1) { break; } else { cachePosition = pos; } } if (index == count && pos != -1) { cachePosition = buff.Length; } value = arr.ToArray(); } else if (type == DataType.Boolean) { value = buff[pos++] != 0; } else if (type == DataType.BitString) { int oldPos = pos; int cnt = GetObjectCount(buff, ref pos); size -= pos - oldPos; double t = cnt; t /= 8; if (cnt % 8 != 0) { ++t; } int byteCnt = (int)Math.Floor(t); if (size < byteCnt) //If there is not enough data available. { pos = -1; return null; } string str = ""; while (cnt > 0) { str += ToBitString(buff[pos++], cnt); cnt -= 8; } value = str; } else if (type == DataType.Int32) { if (size < 4) //If there is not enough data available. { pos = -1; return null; } value = GXCommon.GetInt32(buff, ref pos); } else if (type == DataType.UInt32) { if (size < 4) //If there is not enough data available. { pos = -1; return null; } value = GXCommon.GetUInt32(buff, ref pos); } else if (type == DataType.StringUTF8) { int len = 0; if (knownType) { len = buff.Length; } else { len = GXCommon.GetObjectCount(buff, ref pos); if (buff.Length - pos < len) //If there is not enough data available. { pos = -1; return null; } } if (len > 0) { value = ASCIIEncoding.UTF8.GetString(GXCommon.RawData(buff, ref pos, len)); } else { value = ""; } } else if (type == DataType.String) { int len = 0; if (knownType) { len = buff.Length; } else { len = GXCommon.GetObjectCount(buff, ref pos); if (buff.Length - pos < len) //If there is not enough data available. { pos = -1; return null; } } if (len > 0) { bool octetString = false; if (knownType) { //Check that this is not octet string. foreach (byte it in buff) { if (it != 0 && it < 0x20) { octetString = true; break; } } } if (octetString) { StringBuilder sb = new StringBuilder(3 * buff.Length); foreach (byte it in buff) { sb.Append(it); sb.Append('.'); } sb.Remove(sb.Length - 1, 1); value = sb.ToString(); } else { //Remove '\0' from string if used. while (len > 0 && buff[len - 1] == 0) { --len; } value = ASCIIEncoding.ASCII.GetString(GXCommon.RawData(buff, ref pos, len)); } } } //Example Logical name is octet string, so do not change to string... else if (type == DataType.OctetString) { int len = 0; if (knownType) { len = buff.Length; } else { len = GXCommon.GetObjectCount(buff, ref pos); if (buff.Length - pos < len) //If there is not enough data available. { pos = -1; return null; } } value = GXCommon.RawData(buff, ref pos, len); } else if (type == DataType.BinaryCodedDesimal) { int len; if (knownType) { len = buff.Length; } else { len = GXCommon.GetObjectCount(buff, ref pos); } StringBuilder bcd = new StringBuilder(len * 2); for (int a = 0; a != len; ++a) { int idHigh = buff[pos] >> 4; int idLow = buff[pos] & 0x0F; ++pos; bcd.Append(string.Format("{0}{1}", idHigh, idLow)); } return bcd.ToString(); } else if (type == DataType.Int8) { value = (sbyte)buff[pos++]; } else if (type == DataType.Int16) { if (size < 2) //If there is not enough data available. { pos = -1; return null; } value = GXCommon.GetInt16(buff, ref pos); } else if (type == DataType.UInt8) { value = buff[pos++]; } else if (type == DataType.UInt16) { if (size < 2) //If there is not enough data available. { pos = -1; return null; } value = GXCommon.GetUInt16(buff, ref pos); } else if (type == DataType.CompactArray) { throw new Exception("Invalid data type."); } else if (type == DataType.Int64) { if (size < 8) //If there is not enough data available. { pos = -1; return null; } value = GXCommon.GetInt64(buff, ref pos); } else if (type == DataType.UInt64) { if (size < 8) //If there is not enough data available. { pos = -1; return null; } value = GXCommon.GetUInt64(buff, ref pos); } else if (type == DataType.Enum) { if (size < 1) //If there is not enough data available. { pos = -1; return null; } value = buff[pos++]; } else if (type == DataType.Float32) { if (size < 4) //If there is not enough data available. { pos = -1; return null; } value = GXCommon.ToFloat(buff, ref pos); } else if (type == DataType.Float64) { if (size < 8) //If there is not enough data available. { pos = -1; return null; } value = GXCommon.ToDouble(buff, ref pos); } else if (type == DataType.DateTime) { if (size < 12) //If there is not enough data available. { pos = -1; return null; } GXDateTime dt = new GXDateTime(); //Get year. int year = GXCommon.GetUInt16(buff, ref pos); if (year == 0xFFFF || year == 0) { year = DateTime.MinValue.Year; dt.Skip |= DateTimeSkips.Year; } //Get month int month = buff[pos++]; if (month == 0 || month == 0xFF || month == 0xFE || month == 0xFD) { month = 1; dt.Skip |= DateTimeSkips.Month; } int day = buff[pos++]; if (day < 1 || day == 0xFF) { day = 1; dt.Skip |= DateTimeSkips.Day; } else if (day == 0xFD || day == 0xFE) { day = DateTime.DaysInMonth(year, month) + (sbyte)day + 2; } //Skip week day ++pos; //Get time. int hours = buff[pos++]; if (hours == 0xFF) { hours = 0; dt.Skip |= DateTimeSkips.Hour; } int minutes = buff[pos++]; if (minutes == 0xFF) { minutes = 0; dt.Skip |= DateTimeSkips.Minute; } int seconds = buff[pos++]; if (seconds == 0xFF) { seconds = 0; dt.Skip |= DateTimeSkips.Second; } int milliseconds = buff[pos++]; if (milliseconds != 0xFF && milliseconds != 0) { milliseconds *= 10; } else { milliseconds = 0; dt.Skip |= DateTimeSkips.Ms; } int deviation = GXCommon.GetInt16(buff, ref pos); dt.Status = (ClockStatus)buff[pos++]; if ((deviation & 0xFFFF) != 0x8000 && year != 1) { dt.Value = DateTime.SpecifyKind(new DateTime(year, month, day, hours, minutes, seconds, milliseconds), DateTimeKind.Utc); dt.Value = dt.Value.AddMinutes(deviation); dt.Value = dt.Value.ToLocalTime(); } else //Use current time if deviation is not defined. { dt.Value = new DateTime(year, month, day, hours, minutes, seconds, milliseconds); } value = dt; } else if (type == DataType.Date) { if (size < 5) //If there is not enough data available. { pos = 0xFF; return null; } //Get year. int year = GXCommon.GetUInt16(buff, ref pos); //IskraEmeco meter returns bytes in wrong order. if (year != 0xFFFF && year > 2100) { pos -= 2; year = buff[pos++] | buff[pos++] << 8; //If Actaris SL 7000 and ACE 6000 returns invalid date. if (year == 0x5C13) { year = -1; } } //Get month int month = buff[pos++]; int day = buff[pos++]; //Skip week day int DayOfWeek = buff[pos++]; //If day of week are not used. GXDateTime dt = new GXDateTime(year, month, day, -1, -1, 1, -1); return dt; } else if (type == DataType.Time) { if (size < 4) //If there is not enough data available. { pos = -1; return null; } //Get time. int hours = buff[pos++]; int minutes = buff[pos++]; int seconds = buff[pos++]; int milliseconds = buff[pos++]; GXDateTime dt = new GXDateTime(-1, -1, -1, hours, minutes, seconds, milliseconds); value = dt; } else { throw new Exception("Invalid data type."); } return value; }
void IGXDLMSBase.SetValue(int index, object value) { if (index == 1) { if (value is string) { LogicalName = value.ToString(); } else { LogicalName = GXDLMSClient.ChangeType((byte[])value, DataType.OctetString).ToString(); } } else if (index == 2) { if (value == null) { Time = new GXDateTime(DateTime.MinValue); } else { if (value is byte[]) { value = GXDLMSClient.ChangeType((byte[])value, DataType.DateTime); } Time = (GXDateTime)value; } } else if (index == 3) { TimeZone = Convert.ToInt32(value); } else if (index == 4) { Status = (ClockStatus)Convert.ToInt32(value); } else if (index == 5) { if (value == null) { Begin = new GXDateTime(DateTime.MinValue); } else { if (value is byte[]) { value = GXDLMSClient.ChangeType((byte[])value, DataType.DateTime); } Begin = (GXDateTime)value; } } else if (index == 6) { if (value == null) { End = new GXDateTime(DateTime.MinValue); } else { if (value is byte[]) { value = GXDLMSClient.ChangeType((byte[])value, DataType.DateTime); } End = (GXDateTime)value; } } else if (index == 7) { Deviation = Convert.ToInt32(value); } else if (index == 8) { Enabled = Convert.ToBoolean(value); } else if (index == 9) { ClockBase = (ClockBase)Convert.ToInt32(value); } else { throw new ArgumentException("SetValue failed. Invalid attribute index."); } }
/// <summary> /// Reserved for internal use. /// </summary> /// <param name="buff"></param> /// <param name="type"></param> /// <param name="value"></param> public static void SetData(List<byte> buff, DataType type, object value) { bool reverse = true; List<byte> tmp = new List<byte>(); //If byte array is added do not add type. if ((type == DataType.Array || type == DataType.Structure) && value is byte[]) { buff.AddRange((byte[]) value); return; } if (type == DataType.None) { value = null; } else if (type == DataType.Boolean) { value = (byte) (Convert.ToBoolean(value) ? 1 : 0); } else if (type == DataType.BitString) { byte val = 0; int index = 0; if (value is string) { string str = value as string; SetObjectCount(str.Length, tmp); foreach (char it in str) { if (it == '1') { val |= (byte)(1 << index++); } else if (it == '0') { index++; } else { throw new ArgumentException("Not a bit string."); } if (index == 8) { index = 0; tmp.Add(val); val = 0; } } if (index != 0) { tmp.Add(val); } value = tmp.ToArray(); reverse = false; } else if (value is byte[]) { byte[] arr = value as byte[]; SetObjectCount(arr.Length, tmp); tmp.AddRange(arr); value = tmp.ToArray(); reverse = false; } else if (value is bool[]) { bool[] arr = value as bool[]; SetObjectCount(arr.Length, tmp); foreach (bool it in arr) { if (it) { val |= (byte)(1 << index++); } else { ++index; } if (index == 8) { index = 0; tmp.Add(val); val = 0; } } if (index != 0) { tmp.Add(val); } value = tmp.ToArray(); reverse = false; } else if (value == null) { tmp.Add(0); value = tmp.ToArray(); reverse = false; } else { throw new Exception("BitString must give as string."); } } else if (type == DataType.Int32) { value = Convert.ToInt32(value); } else if (type == DataType.UInt32) { value = Convert.ToUInt32(value); } else if (type == DataType.String) { if (value != null) { string str = value.ToString(); SetObjectCount(str.Length, tmp); tmp.AddRange(ASCIIEncoding.ASCII.GetBytes(str)); } else { SetObjectCount(0, tmp); } value = tmp.ToArray(); reverse = false; } else if (type == DataType.StringUTF8) { if (value != null) { string str = value.ToString(); byte[] tmp1 = ASCIIEncoding.UTF8.GetBytes(str); SetObjectCount(tmp1.Length, tmp); tmp.AddRange(tmp1); } else { SetObjectCount(0, tmp); } value = tmp.ToArray(); reverse = false; } else if (type == DataType.Array || type == DataType.Structure) { if (value != null) { Array arr = (Array)value; SetObjectCount(arr.Length, tmp); foreach (object it in arr) { SetData(tmp, GetValueType(it), it); } } else { SetObjectCount(0, tmp); } value = tmp.ToArray(); reverse = false; } else if (type == DataType.OctetString) { reverse = false; if (value is string) { if ((value as string) == "") { SetObjectCount(0, tmp); value = tmp.ToArray(); } else { string[] items = (value as string).Split('.'); tmp.Clear(); SetObjectCount(items.Length, tmp); foreach (string it in items) { tmp.Add(byte.Parse(it)); } value = tmp.ToArray(); } } else if (value == null) { SetObjectCount(0, tmp); value = tmp.ToArray(); } else if (value is byte[]) { SetObjectCount((value as byte[]).Length, tmp); tmp.AddRange(value as byte[]); value = tmp.ToArray(); } else if (value is GXDateTime) { value = GetDateTime(value as GXDateTime); } else if (value is DateTime) { value = GetDateTime(new GXDateTime(Convert.ToDateTime(value))); } else { value = Convert.ToString(value); } } else if (type == DataType.BinaryCodedDesimal) { if (!(value is string)) { throw new Exception("BCD value must give as string."); } string str = value.ToString().Trim(); int len = str.Length; if (len % 2 != 0) { str = "0" + str; ++len; } len /= 2; List<byte> val = new List<byte>(len); val.Add((byte)(len)); for (int pos = 0; pos != len; ++pos) { byte ch1 = byte.Parse(str.Substring(2 * pos, 1)); byte ch2 = byte.Parse(str.Substring(2 * pos + 1, 1)); val.Add((byte)(ch1 << 4 | ch2)); } reverse = false; value = val.ToArray(); } else if (type == DataType.Int8) { value = Convert.ToSByte(value); } else if (type == DataType.Int16) { value = (short) Convert.ToInt32(value); } else if (type == DataType.UInt8) { value = Convert.ToByte(value); } else if (type == DataType.UInt16) { value = Convert.ToUInt16(value); } else if (type == DataType.CompactArray) { throw new Exception("Invalid data type."); } else if (type == DataType.Int64) { value = Convert.ToInt64(value); } else if (type == DataType.UInt64) { value = Convert.ToUInt64(value); } else if (type == DataType.Enum) { value = Convert.ToByte(value); } else if (type == DataType.Float32) { value = Convert.ToSingle(value); } else if (type == DataType.Float64) { value = Convert.ToDouble(value); } else if (type == DataType.DateTime) { type = DataType.OctetString; if (value is GXDateTime) { value = GetDateTime(value as GXDateTime); } else { value = GetDateTime(new GXDateTime(Convert.ToDateTime(value))); } reverse = false; } else if (type == DataType.Date) { GXDateTime dt; if (value is GXDateTime) { dt = value as GXDateTime; } else if (value is DateTime) { dt = new GXDateTime((DateTime)value); } else { throw new Exception("Invalid date format."); } type = DataType.OctetString; //Add size tmp.Add(5); //Add year. if ((dt.Skip & DateTimeSkips.Year) != 0) { GXCommon.SetUInt16(0xFFFF, tmp); } else { GXCommon.SetUInt16((ushort)dt.Value.Year, tmp); } //Add month. if (dt.DaylightSavingsBegin) { tmp.Add(0xFE); } else if (dt.DaylightSavingsEnd) { tmp.Add(0xFD); } else if ((dt.Skip & DateTimeSkips.Month) != 0) { tmp.Add(0xFF); } else { tmp.Add((byte)dt.Value.Month); } if ((dt.Skip & DateTimeSkips.Day) != 0) { tmp.Add(0xFF); } else { tmp.Add((byte)dt.Value.Day); } //Week day is not spesified. tmp.Add(0xFF); value = tmp.ToArray(); reverse = false; } else if (type == DataType.Time) { GXDateTime dt; if (value is GXDateTime) { dt = value as GXDateTime; } else if (value is DateTime) { dt = new GXDateTime((DateTime)value); } else { throw new Exception("Invalid date format."); } type = DataType.OctetString; //Add size tmp.Add(4); //Add time. if ((dt.Skip & DateTimeSkips.Hour) != 0) { tmp.Add(0xFF); } else { tmp.Add((byte)dt.Value.Hour); } if ((dt.Skip & DateTimeSkips.Minute) != 0) { tmp.Add(0xFF); } else { tmp.Add((byte)dt.Value.Minute); } if ((dt.Skip & DateTimeSkips.Second) != 0) { tmp.Add(0xFF); } else { tmp.Add((byte)dt.Value.Second); } tmp.Add((byte)0xFF); //Hundredths of second is not used. value = tmp.ToArray(); reverse = false; } else { throw new Exception("Invalid data type."); } buff.Add((byte)type); if (value != null) { byte[] data = Gurux.Shared.GXCommon.GetAsByteArray(value); if (reverse) { Array.Reverse(data); } buff.AddRange(data); } }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { switch (e.Index) { case 1: LogicalName = GXCommon.ToLogicalName(e.Value); break; case 2: Token = (byte[])e.Value; break; case 3: if (e.Value is byte[]) { Time = (GXDateTime)GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime, settings != null && settings.UseUtc2NormalTime); } else if (e.Value is string) { Time = new GXDateTime((string)e.Value); } else { Time = (GXDateTime)e.Value; } break; case 4: Descriptions.Clear(); if (e.Value != null) { foreach (object it in (IEnumerable <object>)e.Value) { Descriptions.Add(ASCIIEncoding.ASCII.GetString((byte[])it)); } } break; case 5: DeliveryMethod = (TokenDelivery)Convert.ToByte(e.Value); break; case 6: if (e.Value != null) { List <object> arr; if (e.Value is List <object> ) { arr = (List <object>)e.Value; } else { arr = new List <object>((object[])e.Value); } StatusCode = (TokenStatusCode)Convert.ToInt32(arr[0]); DataValue = Convert.ToString(arr[1]); } else { StatusCode = TokenStatusCode.FormatOk; DataValue = ""; } break; default: e.Error = ErrorCode.ReadWriteDenied; break; } }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { switch (e.Index) { case 1: LogicalName = GXCommon.ToLogicalName(e.Value); break; case 2: if (e.Value != null) { List <object> arr; if (e.Value is List <object> ) { arr = (List <object>)e.Value; } else { arr = new List <object>((object[])e.Value); } AccountStatus = (AccountStatus)Convert.ToByte(arr[0]); PaymentMode = (PaymentMode)Convert.ToByte(arr[1]); } else { AccountStatus = AccountStatus.NewInactiveAccount; PaymentMode = PaymentMode.Credit; } break; case 3: CurrentCreditInUse = (byte)e.Value; break; case 4: CurrentCreditStatus = (AccountCreditStatus)Convert.ToByte(e.Value); break; case 5: AvailableCredit = (int)e.Value; break; case 6: AmountToClear = (int)e.Value; break; case 7: ClearanceThreshold = (int)e.Value; break; case 8: AggregatedDebt = (int)e.Value; break; case 9: CreditReferences.Clear(); if (e.Value != null) { foreach (object it in (IEnumerable <object>)e.Value) { CreditReferences.Add(GXCommon.ToLogicalName(it)); } } break; case 10: ChargeReferences.Clear(); if (e.Value != null) { foreach (object it in (IEnumerable <object>)e.Value) { ChargeReferences.Add(GXCommon.ToLogicalName(it)); } } break; case 11: CreditChargeConfigurations.Clear(); if (e.Value != null) { foreach (object tmp in (IEnumerable <object>)e.Value) { List <object> it; if (tmp is List <object> ) { it = (List <object>)tmp; } else { it = new List <object>((object[])tmp); } GXCreditChargeConfiguration item = new GXCreditChargeConfiguration(); item.CreditReference = GXCommon.ToLogicalName(it[0]); item.ChargeReference = GXCommon.ToLogicalName(it[1]); item.CollectionConfiguration = (CreditCollectionConfiguration)Convert.ToByte(it[2]); CreditChargeConfigurations.Add(item); } } break; case 12: TokenGatewayConfigurations.Clear(); if (e.Value != null) { foreach (object tmp in (IEnumerable <object>)e.Value) { List <object> it; if (tmp is List <object> ) { it = (List <object>)tmp; } else { it = new List <object>((object[])tmp); } GXTokenGatewayConfiguration item = new GXTokenGatewayConfiguration(); item.CreditReference = GXCommon.ToLogicalName(it[0]); item.TokenProportion = (byte)it[1]; TokenGatewayConfigurations.Add(item); } } break; case 13: if (e.Value == null) { AccountActivationTime = new GXDateTime(DateTime.MinValue); } else { if (e.Value is byte[]) { e.Value = GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime, settings.UseUtc2NormalTime); } else if (e.Value is string) { e.Value = new GXDateTime((string)e.Value); } if (e.Value is GXDateTime) { AccountActivationTime = (GXDateTime)e.Value; } } break; case 14: if (e.Value == null) { AccountClosureTime = new GXDateTime(DateTime.MinValue); } else { if (e.Value is byte[]) { e.Value = GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime, settings.UseUtc2NormalTime); } else if (e.Value is string) { e.Value = new GXDateTime((string)e.Value); } if (e.Value is GXDateTime) { AccountClosureTime = (GXDateTime)e.Value; } } break; case 15: if (e.Value != null) { List <object> tmp; if (e.Value is List <object> ) { tmp = (List <object>)e.Value; } else { tmp = new List <object>((object[])e.Value); } Currency.Name = (string)tmp[0]; Currency.Scale = (sbyte)tmp[1]; Currency.Unit = (Currency)Convert.ToByte(tmp[2]); } else { Currency.Name = null; Currency.Scale = 0; Currency.Unit = 0; } break; case 16: LowCreditThreshold = (int)e.Value; break; case 17: NextCreditAvailableThreshold = (int)e.Value; break; case 18: MaxProvision = (UInt16)e.Value; break; case 19: MaxProvisionPeriod = (int)e.Value; break; default: e.Error = ErrorCode.ReadWriteDenied; break; } }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { LogicalName = GXCommon.ToLogicalName(e.Value); } else if (e.Index == 2) { if (e.Value == null) { Time = new GXDateTime(DateTime.MinValue); } else { if (e.Value is byte[]) { e.Value = GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime, settings != null && settings.UseUtc2NormalTime); } else if (e.Value is string) { e.Value = new GXDateTime((string)e.Value); } if (e.Value is GXDateTime) { Time = (GXDateTime)e.Value; } else if (e.Value is String) { DateTime tm; if (!DateTime.TryParse((String)e.Value, out tm)) { Time = DateTime.ParseExact((String)e.Value, CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern + " " + CultureInfo.CurrentCulture.DateTimeFormat.LongTimePattern, CultureInfo.CurrentUICulture); } else { Time = tm; } } else { Time = Convert.ToDateTime(e.Value); } } } else if (e.Index == 3) { TimeZone = Convert.ToInt32(e.Value); } else if (e.Index == 4) { Status = (ClockStatus)Convert.ToInt32(e.Value); } else if (e.Index == 5) { if (e.Value == null) { Begin = new GXDateTime(DateTime.MinValue); } else { if (e.Value is byte[]) { e.Value = GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime, settings.UseUtc2NormalTime); } else if (e.Value is string) { e.Value = new GXDateTime((string)e.Value); } Begin = (GXDateTime)e.Value; } } else if (e.Index == 6) { if (e.Value == null) { End = new GXDateTime(DateTime.MinValue); } else { if (e.Value is byte[]) { e.Value = GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime, settings.UseUtc2NormalTime); } else if (e.Value is string) { e.Value = new GXDateTime((string)e.Value); } End = (GXDateTime)e.Value; } } else if (e.Index == 7) { Deviation = Convert.ToInt32(e.Value); } else if (e.Index == 8) { Enabled = Convert.ToBoolean(e.Value); if (settings != null && settings.IsServer) { if (Enabled) { Status |= ClockStatus.DaylightSavingActive; } else { Status &= ~ClockStatus.DaylightSavingActive; } } } else if (e.Index == 9) { ClockBase = (ClockBase)Convert.ToInt32(e.Value); } else { e.Error = ErrorCode.ReadWriteDenied; } }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { switch (e.Index) { case 1: LogicalName = GXCommon.ToLogicalName(e.Value); break; case 2: AccountStatus = (AccountStatus)((object[])e.Value)[0]; PaymentMode = (PaymentMode)((object[])e.Value)[1]; break; case 3: CurrentCreditInUse = (byte)e.Value; break; case 4: if ((string)e.Value == "") { CurrentCreditStatus = (AccountCreditStatus)0; } else { GXByteBuffer bb = new GXByteBuffer(); GXCommon.SetBitString(bb, e.Value); CurrentCreditStatus = (AccountCreditStatus)bb.GetUInt8(1); } break; case 5: AvailableCredit = (int)e.Value; break; case 6: AmountToClear = (int)e.Value; break; case 7: ClearanceThreshold = (int)e.Value; break; case 8: AggregatedDebt = (int)e.Value; break; case 9: CreditReferences.Clear(); if (e.Value != null) { foreach (object it in (object[])e.Value) { CreditReferences.Add(GXCommon.ToLogicalName(it)); } } break; case 10: ChargeReferences.Clear(); if (e.Value != null) { foreach (object it in (object[])e.Value) { ChargeReferences.Add(GXCommon.ToLogicalName(it)); } } break; case 11: CreditChargeConfigurations.Clear(); if (e.Value != null) { foreach (object[] it in (object[])e.Value) { GXCreditChargeConfiguration item = new GXCreditChargeConfiguration(); item.CreditReference = GXCommon.ToLogicalName(it[0]); item.ChargeReference = GXCommon.ToLogicalName(it[1]); if ((string)it[2] == "") { item.CollectionConfiguration = 0; } else { GXByteBuffer tmp2 = new GXByteBuffer(); GXCommon.SetBitString(tmp2, it[2]); item.CollectionConfiguration = (CreditCollectionConfiguration)tmp2.GetUInt8(1); } CreditChargeConfigurations.Add(item); } } break; case 12: TokenGatewayConfigurations.Clear(); if (e.Value != null) { foreach (object[] it in (object[])e.Value) { GXTokenGatewayConfiguration item = new GXTokenGatewayConfiguration(); item.CreditReference = GXCommon.ToLogicalName(it[0]); item.TokenProportion = (byte)it[1]; TokenGatewayConfigurations.Add(item); } } break; case 13: if (e.Value == null) { AccountActivationTime = new GXDateTime(DateTime.MinValue); } else { if (e.Value is byte[]) { e.Value = GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime, settings.UseUtc2NormalTime); } else if (e.Value is string) { e.Value = new GXDateTime((string)e.Value); } if (e.Value is GXDateTime) { AccountActivationTime = (GXDateTime)e.Value; } } break; case 14: if (e.Value == null) { AccountClosureTime = new GXDateTime(DateTime.MinValue); } else { if (e.Value is byte[]) { e.Value = GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime, settings.UseUtc2NormalTime); } else if (e.Value is string) { e.Value = new GXDateTime((string)e.Value); } if (e.Value is GXDateTime) { AccountClosureTime = (GXDateTime)e.Value; } } break; case 15: object[] tmp = (object[])e.Value; Currency.Name = (string)tmp[0]; Currency.Scale = (sbyte)tmp[1]; Currency.Unit = (Currency)tmp[2]; break; case 16: LowCreditThreshold = (int)e.Value; break; case 17: NextCreditAvailableThreshold = (int)e.Value; break; case 18: MaxProvision = (UInt16)e.Value; break; case 19: MaxProvisionPeriod = (int)e.Value; break; default: e.Error = ErrorCode.ReadWriteDenied; break; } }
private async void DoWork() { _logger.LogInformation("Reader Service is working."); GetNextTaskResponse ret = null; GXDLMSObjectCollection objects = new GXDLMSObjectCollection(); HttpResponseMessage response; while (!closing.WaitOne(1)) { try { using (response = await client.PostAsJsonAsync(Startup.ServerAddress + "/api/task/GetNextTask", new GetNextTask())) { Helpers.CheckStatus(response); ret = await response.Content.ReadAsAsync <GetNextTaskResponse>(); } if (ret.Tasks != null) { int pos = 0; GXDevice dev; GXDLMSSecureClient cl; using (response = await client.PostAsJsonAsync(Startup.ServerAddress + "/api/device/ListDevices", new ListDevices() { Ids = new[] { ret.Tasks[0].Object.DeviceId } })) { Helpers.CheckStatus(response); ListDevicesResponse r = await response.Content.ReadAsAsync <ListDevicesResponse>(); if (r.Devices == null || r.Devices.Length == 0) { continue; } dev = r.Devices[0]; } IGXMedia media; if (string.Compare(dev.MediaType, typeof(GXNet).FullName, true) == 0) { media = new GXNet(); } else if (string.Compare(dev.MediaType, typeof(GXSerial).FullName, true) == 0) { media = new GXSerial(); } else if (string.Compare(dev.MediaType, typeof(GXTerminal).FullName, true) == 0) { media = new GXTerminal(); } else { Type type = Type.GetType(dev.MediaType); if (type == null) { string ns = ""; pos = dev.MediaType.LastIndexOf('.'); if (pos != -1) { ns = dev.MediaType.Substring(0, pos); } foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { if (assembly.GetName().Name == ns) { if (assembly.GetType(dev.MediaType, false, true) != null) { type = assembly.GetType(dev.MediaType); } } } } if (type == null) { throw new Exception("Invalid media type: " + dev.MediaType); } media = (IGXMedia)Activator.CreateInstance(type); } if (media == null) { throw new Exception("Unknown media type '" + dev.MediaType + "'."); } media.Settings = dev.MediaSettings; GXDLMSReader reader; //Read frame counter from the meter. if (dev.Security != 0) { cl = new GXDLMSSecureClient(dev.UseLogicalNameReferencing, 16, dev.PhysicalAddress, Authentication.None, null, (InterfaceType)dev.InterfaceType); reader = new GXDLMSReader(cl, media, TraceLevel.Verbose, _logger); media.Open(); reader.InitializeConnection(); //Read Innovation counter. GXDLMSData d = new GXDLMSData(dev.FrameCounter); reader.Read(d, 2); dev.InvocationCounter = 1 + Convert.ToUInt32(d.Value); reader.Disconnect(); media.Close(); } cl = new GXDLMSSecureClient(dev.UseLogicalNameReferencing, dev.ClientAddress, dev.PhysicalAddress, (Authentication)dev.Authentication, dev.Password, (InterfaceType)dev.InterfaceType); if (dev.HexPassword != null && dev.HexPassword.Length != 0) { cl.Password = dev.HexPassword; } cl.UtcTimeZone = dev.UtcTimeZone; cl.Standard = (Standard)dev.Standard; cl.Ciphering.SystemTitle = GXCommon.HexToBytes(dev.ClientSystemTitle); if (cl.Ciphering.SystemTitle != null && cl.Ciphering.SystemTitle.Length == 0) { cl.Ciphering.SystemTitle = null; } cl.Ciphering.BlockCipherKey = GXCommon.HexToBytes(dev.BlockCipherKey); if (cl.Ciphering.BlockCipherKey != null && cl.Ciphering.BlockCipherKey.Length == 0) { cl.Ciphering.BlockCipherKey = null; } cl.Ciphering.AuthenticationKey = GXCommon.HexToBytes(dev.AuthenticationKey); if (cl.Ciphering.AuthenticationKey != null && cl.Ciphering.AuthenticationKey.Length == 0) { cl.Ciphering.AuthenticationKey = null; } cl.ServerSystemTitle = GXCommon.HexToBytes(dev.DeviceSystemTitle); if (cl.ServerSystemTitle != null && cl.ServerSystemTitle.Length == 0) { cl.ServerSystemTitle = null; } cl.Ciphering.InvocationCounter = dev.InvocationCounter; cl.Ciphering.Security = (Security)dev.Security; reader = new GXDLMSReader(cl, media, TraceLevel.Verbose, _logger); media.Open(); reader.InitializeConnection(); pos = 0; int count = ret.Tasks.Length; foreach (GXTask task in ret.Tasks) { ++pos; try { GXDLMSObject obj = GXDLMSClient.CreateObject((ObjectType)task.Object.ObjectType); obj.LogicalName = task.Object.LogicalName; obj.ShortName = task.Object.ShortName; if (task.TaskType == TaskType.Write) { if (obj.LogicalName == "0.0.1.1.0.255" && task.Index == 2) { cl.UpdateValue(obj, task.Index, GXDateTime.ToUnixTime(DateTime.UtcNow)); } else { cl.UpdateValue(obj, task.Index, GXDLMSTranslator.XmlToValue(task.Data)); } reader.Write(obj, task.Index); } else if (task.TaskType == TaskType.Action) { reader.Method(obj, task.Index, GXDLMSTranslator.XmlToValue(task.Data), DataType.None); } else if (task.TaskType == TaskType.Read) { //Reading the meter. Reader.Read(_logger, client, reader, task, media, obj); } } catch (Exception ex) { task.Result = ex.Message; AddError error = new AddError(); error.Error = new GXError() { DeviceId = dev.Id, Error = "Failed to " + task.TaskType + " " + task.Object.LogicalName + ":" + task.Index + ". " + ex.Message }; using (response = await client.PostAsJsonAsync(Startup.ServerAddress + "/api/error/AddError", error)) { Helpers.CheckStatus(response); await response.Content.ReadAsAsync <AddErrorResponse>(); } } task.End = DateTime.Now; //Close connection after last task is executed. //This must done because there might be new task to execute. if (count == pos) { try { reader.Close(); } catch (Exception ex) { task.Result = ex.Message; AddError error = new AddError(); error.Error = new GXError() { DeviceId = dev.Id, Error = "Failed to close the connection. " + ex.Message }; using (response = await client.PostAsJsonAsync(Startup.ServerAddress + "/api/error/AddError", error)) { Helpers.CheckStatus(response); await response.Content.ReadAsAsync <AddErrorResponse>(); } } } //Update execution time. response = client.PostAsJsonAsync(Startup.ServerAddress + "/api/task/TaskReady", new TaskReady() { Tasks = new GXTask[] { task } }).Result; Helpers.CheckStatus(response); } } else { try { using (response = await client.PostAsJsonAsync(Startup.ServerAddress + "/api/task/WaitChange", new WaitChange() { Change = TargetType.Tasks, Time = lastUpdated, WaitTime = _waitTime })) { Helpers.CheckStatus(response); { WaitChangeResponse r = await response.Content.ReadAsAsync <WaitChangeResponse>(); if (r.Time > lastUpdated) { lastUpdated = r.Time; } } } } catch (Exception) { Thread.Sleep(10000); } } } catch (Exception ex) { if (ret == null) { _logger.LogInformation("Failed to connect to the DB server."); } else { AddError error = new AddError(); error.Error = new GXError() { DeviceId = ret.Tasks[0].Object.DeviceId, Error = "Failed to " + ret.Tasks[0].TaskType + " " + ret.Tasks[0].Object.LogicalName + ":" + ret.Tasks[0].Index + ". " + ex.Message }; using (response = await client.PostAsJsonAsync(Startup.ServerAddress + "/api/error/AddError", error)) { if (ret.Tasks != null) { DateTime now = DateTime.Now; foreach (GXTask it in ret.Tasks) { it.Result = ex.Message; it.End = now; } response = await client.PostAsJsonAsync(Startup.ServerAddress + "/api/task/TaskReady", new TaskReady() { Tasks = ret.Tasks }); } } } _logger.LogInformation(ex.Message); Console.WriteLine(ex.Message); if (!(ex is GXDLMSException)) { Console.WriteLine("+++++++++++++++++++++++++"); Console.WriteLine(ex); } } } }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { if (e.Value is string) { LogicalName = e.Value.ToString(); } else { LogicalName = GXDLMSClient.ChangeType((byte[])e.Value, DataType.OctetString).ToString(); } } else if (e.Index == 2) { if (e.Value != null) { String ln = GXDLMSClient.ChangeType((byte[])((object[])e.Value)[0], DataType.OctetString).ToString(); Target = (GXDLMSScriptTable)settings.Objects.FindByLN(ObjectType.ScriptTable, ln); if (Target == null) { #pragma warning disable CS0618 ExecutedScriptLogicalName = ln; #pragma warning restore CS0618 } ExecutedScriptSelector = Convert.ToUInt16(((object[])e.Value)[1]); } else { Target = null; ExecutedScriptSelector = 0; } } else if (e.Index == 3) { Type = (SingleActionScheduleType)Convert.ToInt32(e.Value); } else if (e.Index == 4) { ExecutionTime = null; if (e.Value != null) { List <GXDateTime> items = new List <GXDateTime>(); foreach (object[] it in (object[])e.Value) { GXDateTime time = (GXDateTime)GXDLMSClient.ChangeType((byte[])it[0], DataType.Time); time.Skip &= ~(DateTimeSkips.Year | DateTimeSkips.Month | DateTimeSkips.Day | DateTimeSkips.DayOfWeek); GXDateTime date = (GXDateTime)GXDLMSClient.ChangeType((byte[])it[1], DataType.Date); date.Skip &= ~(DateTimeSkips.Hour | DateTimeSkips.Minute | DateTimeSkips.Second | DateTimeSkips.Ms); GXDateTime tmp = new DLMS.GXDateTime(date); tmp.Value = tmp.Value.AddHours(time.Value.Hour); tmp.Value = tmp.Value.AddMinutes(time.Value.Minute); tmp.Value = tmp.Value.AddSeconds(time.Value.Second); tmp.Skip = date.Skip | time.Skip; items.Add(tmp); } ExecutionTime = items.ToArray(); } } else { e.Error = ErrorCode.ReadWriteDenied; } }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { LogicalName = GXCommon.ToLogicalName(e.Value); } else if (e.Index == 2) { if (Scaler != 1 && e.Value != null && !e.User) { try { if (settings.IsServer) { CurrentAverageValue = e.Value; } else { CurrentAverageValue = Convert.ToDouble(e.Value) * Scaler; } } catch (Exception) { //Sometimes scaler is set for wrong Object type. CurrentAverageValue = e.Value; } } else { CurrentAverageValue = e.Value; } } else if (e.Index == 3) { if (Scaler != 1 && e.Value != null && !e.User) { try { SetDataType(e.Index, GXCommon.GetDLMSDataType(e.Value.GetType())); if (settings.IsServer) { LastAverageValue = e.Value; } else { LastAverageValue = Convert.ToDouble(e.Value) * Scaler; } } catch (Exception) { //Sometimes scaler is set for wrong Object type. LastAverageValue = e.Value; } } else { LastAverageValue = e.Value; } } else if (e.Index == 4) { if (e.Value == null) { Scaler = 1; Unit = Unit.None; } else { List <object> arr; if (e.Value is List <object> ) { arr = (List <object>)e.Value; } else { arr = new List <object>((object[])e.Value); } if (arr.Count != 2) { throw new Exception("setValue failed. Invalid scaler unit value."); } scaler = Convert.ToInt32(arr[0]); Unit = (Unit)Convert.ToInt32(arr[1]); } } else if (e.Index == 5) { Status = Convert.ToInt32(e.Value); } else if (e.Index == 6) { if (e.Value == null) { CaptureTime = new GXDateTime(DateTime.MinValue); } else { if (e.Value is byte[]) { e.Value = GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime, settings.UseUtc2NormalTime); } else if (e.Value is string) { e.Value = new GXDateTime((string)e.Value); } CaptureTime = (GXDateTime)e.Value; } } else if (e.Index == 7) { if (e.Value == null) { StartTimeCurrent = new GXDateTime(DateTime.MinValue); } else { if (e.Value is byte[]) { e.Value = GXDLMSClient.ChangeType((byte[])e.Value, DataType.DateTime, settings.UseUtc2NormalTime); } else if (e.Value is string) { e.Value = new GXDateTime((string)e.Value); } StartTimeCurrent = (GXDateTime)e.Value; } } else if (e.Index == 8) { Period = Convert.ToUInt32(e.Value); } else if (e.Index == 9) { NumberOfPeriods = Convert.ToUInt16(e.Value); } else { e.Error = ErrorCode.ReadWriteDenied; } }
void IGXDLMSBase.SetValue(GXDLMSSettings settings, ValueEventArgs e) { if (e.Index == 1) { if (e.Value is string) { LogicalName = e.Value.ToString(); } else { LogicalName = GXDLMSClient.ChangeType((byte[])e.Value, DataType.OctetString).ToString(); } } else if (e.Index == 2) { PushObjectList.Clear(); if (e.Value is Object[]) { foreach (object it in e.Value as Object[]) { Object[] tmp = it as Object[]; ObjectType type = (ObjectType)Convert.ToUInt16(tmp[0]); String ln = GXDLMSClient.ChangeType((byte[])tmp[1], DataType.OctetString).ToString(); GXDLMSObject obj = settings.Objects.FindByLN(type, ln); if (obj == null) { obj = GXDLMSClient.CreateObject(type); obj.LogicalName = ln; } GXDLMSCaptureObject co = new GXDLMSCaptureObject(Convert.ToInt32(tmp[2]), Convert.ToInt32(tmp[3])); PushObjectList.Add(new KeyValuePair <GXDLMSObject, GXDLMSCaptureObject>(obj, co)); } } } else if (e.Index == 3) { object[] tmp = e.Value as object[]; if (tmp != null) { Service = (ServiceType)Convert.ToInt32(tmp[0]); Destination = (string)GXDLMSClient.ChangeType((byte[])tmp[1], DataType.String); Message = (MessageType)Convert.ToInt32(tmp[2]); } } else if (e.Index == 4) { CommunicationWindow.Clear(); if (e.Value is Object[]) { foreach (object it in e.Value as Object[]) { Object[] tmp = it as Object[]; GXDateTime start = GXDLMSClient.ChangeType((byte[])tmp[0], DataType.DateTime) as GXDateTime; GXDateTime end = GXDLMSClient.ChangeType((byte[])tmp[1], DataType.DateTime) as GXDateTime; CommunicationWindow.Add(new KeyValuePair <GXDateTime, GXDateTime>(start, end)); } } } else if (e.Index == 5) { RandomisationStartInterval = (UInt16)e.Value; } else if (e.Index == 6) { NumberOfRetries = (byte)e.Value; } else if (e.Index == 7) { RepetitionDelay = (UInt16)e.Value; } else { e.Error = ErrorCode.ReadWriteDenied; } }
///<summary> ///Convert time to DLMS bytes. ///</summary> ///<param name="buff"> ///Byte buffer where data is write. ///</param> ///<param name="value"> ///Added value. ///</param> private static void SetTime(GXByteBuffer buff, object value) { GXDateTime dt; if (value is GXDateTime) { dt = (GXDateTime)value; } else if (value is DateTime) { dt = new GXDateTime((DateTime)value); } else if (value is DateTimeOffset) { dt = new GXDateTime((DateTimeOffset)value); } else if (value is string) { dt = DateTime.Parse((string)value); } else { throw new Exception("Invalid date format."); } //Add time. if ((dt.Skip & DateTimeSkips.Hour) != 0) { buff.SetUInt8(0xFF); } else { buff.SetUInt8((byte)dt.Value.Hour); } if ((dt.Skip & DateTimeSkips.Minute) != 0) { buff.SetUInt8(0xFF); } else { buff.SetUInt8((byte)dt.Value.Minute); } if ((dt.Skip & DateTimeSkips.Second) != 0) { buff.SetUInt8(0xFF); } else { buff.SetUInt8((byte)dt.Value.Second); } //Hundredths of second is not used. if ((dt.Skip & DateTimeSkips.Ms) != 0) { buff.SetUInt8(0xFF); } else { buff.SetUInt8((byte)(dt.Value.Millisecond / 10)); } }