/// <summary> /// Adds the set unsigned param request. /// </summary> /// <param name="reqFile">The req file.</param> /// <param name="param">The param.</param> private void AddSetUnsignedParamRequest(SmlFile reqFile, UnsignedParam param) { var msg = new Core.Sml.Messages.Message() { TransactionId = new[] { (byte)(reqFile.Count + 1) }, GroupNo = 0x00, SetProcParameterRequest = new Core.Sml.Messages.SetProcParameterRequest() { TreePath = new List<Core.Obis.ObisId>() { new Core.Obis.ObisId((ulong)param.ObisCode) }, Tree = new Tree(new Core.Obis.ObisId((ulong)param.ObisCode), param.Data.Value) } }; //var obisId = (ObisId)param.ObisCode; //var paramTreePath = new SmlTreePath(obisId); //var tree = new SmlTree { ParameterName = new SmlOctetstring(ObisUtil.GetBytes(obisId)) }; //if (param.Data.HasValue == false) //{ // throw new ArgumentNullException("param"); //} //// TODO: check if casting is obsolete //if (obisId == ObisId.EdlActiveTariffAplus || obisId == ObisId.EdlActiveTariffAminus) //{ // tree.ParameterValue = new SmlProcParValue(new SmlUnsigned8((byte)param.Data.Value)); //} //else //{ // tree.ParameterValue = new SmlProcParValue(new SmlUnsigned64(param.Data.Value)); //} //var msg = SmlMessageFactory.SetProcParamReq(paramTreePath, tree); //var transactionId = new byte[] { (byte)(reqFile.Count + 1) }; //msg.TransactionId = new SmlOctetstring(transactionId); //msg.GroupNo = 0x00; reqFile.Add(msg); }
/// <summary> /// Creates the set request file for tariff. /// </summary> /// <param name="portId">The port id.</param> /// <param name="bitMask">The bit mask.</param> /// <param name="tariffAplus">The tariff aplus.</param> /// <param name="tarrifAminus">The tarrif aminus.</param> /// <returns>The request file to set the tariffs and bitmask.</returns> public static SmlFile CreateSetRequestFileForTariff( string portId, UnsignedParam bitMask, UnsignedParam tariffAplus, UnsignedParam tarrifAminus) { var handler = new SmlHandler(portId); var smlFile = new SmlFile(); handler.AddOpenRequest(smlFile); handler.AddSetBooleanParamRequest( smlFile, new BooleanParam() { ObisCode = (long)ObisId.EdlOperationModeEdl40, Data = false }); handler.AddSetUnsignedParamRequest(smlFile, bitMask); if (tariffAplus != null) { handler.AddSetUnsignedParamRequest(smlFile, tariffAplus); } if (tarrifAminus != null) { handler.AddSetUnsignedParamRequest(smlFile, tarrifAminus); } handler.AddCloseRequest(smlFile); return smlFile; }
public async Task WriteParameter(UnsignedParam param, bool enableManufacturerMode = false) { if (param.ObisCode == RegisterIds.SetTariff.AsLong()) { var isTarrifTwo = param.Data.Value == 2; TariffConfiguration tariffConfiguration = TariffConfiguration.None; var mm = await this.productionParameters.GetMeasurementMode().ConfigureAwait(false); switch (mm) { case MeasurmentMode.MM1_ImportReverseLocking: tariffConfiguration = TariffConfiguration.Import; break; case MeasurmentMode.MM2_ImportExport: tariffConfiguration = TariffConfiguration.Import | TariffConfiguration.Export; break; case MeasurmentMode.MM3_ExportLocking: case MeasurmentMode.MM4_Export: tariffConfiguration = TariffConfiguration.Export; break; } // read configuration to get status of reverse tariff control var tc = await this.baseMeterDevice.TariffControl.GetTariffConfiguration().ConfigureAwait(false); if (tc.HasFlag(TariffConfiguration.OnActivationUseT1)) { tariffConfiguration |= TariffConfiguration.OnActivationUseT1; } await this.baseMeterDevice.TariffControl.SetTariffConfiguration(tariffConfiguration).ConfigureAwait(false); await this.baseMeterDevice.TariffControl.SetLmnTariffSignal(isTarrifTwo).ConfigureAwait(false); } else if (param.ObisCode == VendorSpecificRegisterIds.MeasurementMode.AsLong()) { MeasurmentMode mmToWrite = (MeasurmentMode) param.Data.Value; await this.productionParameters.SetMeasurementMode(mmToWrite); } else { var obis = new ObisId((ulong) param.ObisCode); await this.baseMeterDevice.WriteRegisterAsync(obis, param.Data.Value).ConfigureAwait(false); } }
/// <summary> /// Creates the set request file. /// </summary> /// <param name="portId">The port id.</param> /// <param name="param">The param.</param> /// <returns></returns> public static SmlFile CreateSetRequestFile(string portId, UnsignedParam param) { var handler = new SmlHandler(portId); var smlFile = new SmlFile(); handler.AddOpenRequest(smlFile); handler.AddSetUnsignedParamRequest(smlFile, param); handler.AddCloseRequest(smlFile); return smlFile; }
/// <summary> /// Writes the parameter. /// </summary> /// <param name="param">The param.</param> public async Task WriteParameter(UnsignedParam param, bool enableManufacturerMode = false) { logger.Info("Writing unsigned parameter {0} with value {1}.", (ObisId)param.ObisCode, BitConverter.ToString(BitConverter.GetBytes(param.Data.Value))); await Retry.DoTask( async () => { var requestFile = SmlHandler.CreateSetRequestFile(portName, param); await SendRequestFile(requestFile, enableManufacturerMode).ConfigureAwait(false); if (writeOnlyParams.Contains(param.ObisCode)) { return; } var result = await ReadParameter(new UnsignedParam { ObisCode = param.ObisCode }); if (param.Data != result.Data) { throw new DataException( string.Format( "Failed to write and verify {0:X12}: written: {1}, read: {2}", param.ObisCode, param.Data, result.Data)); } }); }
public async Task<UnsignedParam> ReadParameter(UnsignedParam param) { if (param.ObisCode == VendorSpecificRegisterIds.MeasurementMode.AsLong()) { var pp = new ProductionParameters(this.baseMeterDevice); MeasurmentMode mm = await pp.GetMeasurementMode().ConfigureAwait(false); ulong mmNumber = 0; switch (mm) { case MeasurmentMode.MM1_ImportReverseLocking: mmNumber = 1; break; case MeasurmentMode.MM2_ImportExport: mmNumber = 2; break; case MeasurmentMode.MM3_ExportLocking: mmNumber = 3; break; case MeasurmentMode.MM4_Export: mmNumber = 4; break; default: throw new ArgumentOutOfRangeException(); } return new UnsignedParam() { ObisCode = param.ObisCode, Data = mmNumber }; } var obis = new ObisId((ulong)param.ObisCode); var result = await this.baseMeterDevice.ReadRegisterAsync(obis).ConfigureAwait(false); if (result == null) { throw new NullReferenceException(); } return new UnsignedParam() { ObisCode = param.ObisCode, Data = result.GetAsULong() }; }
/// <summary> /// Reads the number of tariffs. /// </summary> /// <param name="clientId">The client id.</param> /// <param name="communicationPort">The communication port.</param> /// <returns>Total number of configured tariffs.</returns> public async Task<UnsignedParam> ReadNumberOfTariffs(Guid clientId, CommunicationPort communicationPort) { var port = CheckConfiguration(communicationPort, clientId); if (port.MeterType == MeterType.Basemeter) { var boolParam = new BooleanParam() { ObisCode = RegisterIds.TariffOptionEnabled.AsLong() }; boolParam = await port.ComThread.ReadParameter(boolParam); if (boolParam.Data.Value) { return new UnsignedParam() { ObisCode = (long) ObisId.EdlDzgNumberOfTariffs, Data = 2 }; } else { return new UnsignedParam() { ObisCode = (long)ObisId.EdlDzgNumberOfTariffs, Data = 0 }; } } var numParam = new UnsignedParam() { ObisCode = (long)ObisId.EdlDzgNumberOfTariffs, Data = null }; numParam = await ClientComListDict[communicationPort.ComPortName].ComThread.ReadParameter(numParam); return numParam; }
/// <summary> /// Reads the parameter. /// </summary> /// <param name="param">The param.</param> /// <returns></returns> public async Task<UnsignedParam> ReadParameter(UnsignedParam param) { logger.Info("Reading unsigned parameter."); var requestFile = SmlHandler.CreateGetRequestFile(portName, param.ObisCode); return await Retry.Do( async () => { var resVal = await SendFile(requestFile).ConfigureAwait(false); CheckAttentionResponse(param.ObisCode, resVal); if (resVal != null) { var valB = Convert.ToUInt64(resVal); param.Data = valB; logger.Info("Responding with unsigned result: {0}.", param.Data); return param; } logger.Info("No response for reading unsigned parameter."); throw new NullReferenceException(); }); }
/// <summary> /// Writes the current aminus tariff. /// </summary> /// <param name="clientId">The client id.</param> /// <param name="communicationPort">The communication port.</param> /// <param name="tariffNumber">The tariff number.</param> public async Task WriteCurrentAminusTariff(Guid clientId, CommunicationPort communicationPort, byte tariffNumber) { var port = CheckConfiguration(communicationPort, clientId); if (communicationPort.MeterType == MeterType.Edl) { var meterDevice = ClientComListDict[communicationPort.ComPortName].EdlMeterDevice; if (tariffNumber > meterDevice.TariffCount) { throw new ArgumentOutOfRangeException("Selected tariff is not supported by this meter."); } await Retry.DoTask(async () => { // deactivate EDL40 mode if (meterDevice.IsOperationModeEdl40.Data == true) { await this.WriteIsOperationModeEdl40(clientId, communicationPort, false); } // set tariff mask to this meter's maximum tariff count var rawBytes = BitConverter.GetBytes(meterDevice.TariffMaskForLcd.Data.Value); Array.Resize(ref rawBytes, 2); var tariffCount = meterDevice.TariffCount; rawBytes[1] = 0; while (tariffCount-- > 0) { rawBytes[1] |= (byte)(rawBytes[1] << 1); rawBytes[1] |= 1; } if (meterDevice.MeasurementMode == "MM2") { tariffCount = meterDevice.TariffCount; rawBytes[0] = 0; while (tariffCount-- > 0) { rawBytes[0] |= (byte)(rawBytes[0] << 1); rawBytes[0] |= 1; } } var bitMask = BitConverter.ToUInt16(rawBytes, 0); meterDevice.TariffMaskForLcd.Data = bitMask; // configure the parameter here and the thread intetrnally checks, sets and keeps the active tariff byte tariffByte = 1; tariffByte = (byte)(tariffByte << (tariffNumber - 1)); var tariffParam = new UnsignedParam() { ObisCode = (long)ObisId.EdlActiveTariffAminus, Data = tariffByte }; var thread = ClientComListDict[communicationPort.ComPortName].ComThread; var device = ClientComListDict[communicationPort.ComPortName].EdlMeterDevice; await thread.WriteParameter(device.TariffMaskForLcd); await thread.WriteParameter(device.ActiveTariffAminus = tariffParam); }); } else { var setTariffParam = new UnsignedParam() { ObisCode = RegisterIds.SetTariff.AsLong(), Data = tariffNumber }; await port.ComThread.WriteParameter(setTariffParam); } }
/// <summary> /// Reads the number of manipulation events. /// </summary> /// <param name="clientId">The client id.</param> /// <param name="communicationPort">The communication port.</param> /// <returns>Total number of manipulation events.</returns> public async Task<UnsignedParam> ReadNumberOfManipulationEvents(Guid clientId, CommunicationPort communicationPort) { CheckConfiguration(communicationPort, clientId); var numParam = new UnsignedParam() {ObisCode = (long) ObisId.EdlManipulationEvent, Data = null}; numParam = await ClientComListDict[communicationPort.ComPortName].ComThread.ReadParameter(numParam); return numParam; }
/// <summary> /// Writes the measurement mode. /// </summary> /// <param name="clientId">The client id.</param> /// <param name="communicationPort">The communication port.</param> /// <param name="measurementMode">The measurement mode.</param> public async Task WriteMeasurementMode(Guid clientId, CommunicationPort communicationPort, string measurementMode) { CheckConfiguration(communicationPort, clientId); if (communicationPort.MeterType == MeterType.Edl) { byte mode = 0x08; switch (measurementMode) { case "MM1": mode = 0x08; break; case "MM2": mode = 0x0A; break; case "MM3": mode = 0x02; break; case "MM4": mode = 0x01; break; default: throw new InvalidEnumArgumentException("Invalid measurement mode. Measurement mode must be within MM1 ... MM4."); } var numParam = new UnsignedParam() { ObisCode = (long) ObisId.EdlDzgMeasurementMode, Data = mode }; await ClientComListDict[communicationPort.ComPortName].ComThread.WriteParameter(numParam); } else { // basemeter MeasurmentMode mode; switch (measurementMode) { case "MM1": mode = MeasurmentMode.MM1_ImportReverseLocking; break; case "MM2": mode = MeasurmentMode.MM2_ImportExport; break; case "MM3": mode = MeasurmentMode.MM3_ExportLocking; break; case "MM4": mode = MeasurmentMode.MM4_Export; break; default: throw new InvalidEnumArgumentException("Invalid measurement mode. Measurement mode must be within MM1 ... MM4."); } var numParam = new UnsignedParam() { ObisCode = VendorSpecificRegisterIds.MeasurementMode.AsLong(), Data = (ulong) mode }; await ClientComListDict[communicationPort.ComPortName].ComThread.WriteParameter(numParam); } }
/// <summary> /// Reads the measurement mode. /// </summary> /// <param name="clientId">The client id.</param> /// <param name="communicationPort">The communication port.</param> /// <returns>The configured measurement mode.</returns> public async Task<UnsignedParam> ReadMeasurementMode(Guid clientId, CommunicationPort communicationPort) { CheckConfiguration(communicationPort, clientId); var numParam = new UnsignedParam() { Data = null }; if (communicationPort.MeterType == MeterType.Basemeter) { numParam.ObisCode = VendorSpecificRegisterIds.MeasurementMode.AsLong(); } else if (communicationPort.MeterType == MeterType.Edl) { numParam.ObisCode = (long) ObisId.EdlDzgMeasurementMode; } else { throw new InvalidOperationException(); } numParam = await ClientComListDict[communicationPort.ComPortName].ComThread.ReadParameter(numParam); return numParam; }
//-- BEGIN public async Task<UnsignedParam> ReadMeterType(Guid clientId, CommunicationPort communicationPort) { var port = CheckConfiguration(communicationPort, clientId); var param = new UnsignedParam { Data = null, ObisCode = VendorSpecificRegisterIds.MeterType.AsLong() }; param = await port.ComThread.ReadParameter(param); return param; }
/// <summary> /// Writes the number of tariffs. /// </summary> /// <param name="clientId">The client id.</param> /// <param name="communicationPort">The communication port.</param> /// <param name="numberOfTariffs">The number of tariffs.</param> public async Task WriteNumberOfTariffs(Guid clientId, CommunicationPort communicationPort, byte numberOfTariffs) { CheckConfiguration(communicationPort, clientId); var numParam = new UnsignedParam() { ObisCode = (long) ObisId.EdlDzgNumberOfTariffs, Data = numberOfTariffs }; await ClientComListDict[communicationPort.ComPortName].ComThread.WriteParameter(numParam); }
/// <summary> /// Writes the parameter. /// </summary> /// <param name="param">The param.</param> public async Task WriteParameter(UnsignedParam param, bool enableManufacturerMode = false) { this.logger.Info("Writing unsigned parameter {0} with value {1}.", (ObisId)param.ObisCode, BitConverter.ToString(BitConverter.GetBytes(param.Data.Value))); await Retry.DoTask( async () => { var requestFile = SmlHandler.CreateSetRequestFile(this.endpoint, param); await this.SendRequestFile(requestFile, enableManufacturerMode); if (writeOnlyParams.Contains(param.ObisCode)) { return; } var result = await this.ReadParameter(new UnsignedParam() { ObisCode = param.ObisCode }); if (param.Data != result.Data) { throw new DataException( $"Failed to write and verify {param.ObisCode:X12}: written: {param.Data}, read: {result.Data}"); } }); }