Created
April 18, 2013 14:39
-
-
Save cwschroeder/5413244 to your computer and use it in GitHub Desktop.
MSK Relay ComJob example for communication and load profile readout of EMH LZQJ meter via GSM modem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace RelayMeterComDemo | |
{ | |
using System; | |
using System.Collections.Concurrent; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Net; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using Client.Http; | |
using Core.Models.Client.Jobs; | |
using Core.Models.Client.Jobs.Meter; | |
using Core.Models.Client.Jobs.Meter.Action; | |
using Core.Models.Client.Jobs.Meter.Driver; | |
using Core.Models.Client.Jobs.Meter.Driver.Sml.Muc; | |
using Core.Models.Client.Jobs.Meter.Result; | |
using Core.Models.JsonExtensions.Job.MeterComJob; | |
using Core.Models.Server.Node; | |
using NDesk.Options; | |
using NLog; | |
/// <summary> | |
/// Demo program to show some of the MSK relay's metering functionalities. | |
/// </summary> | |
class Program | |
{ | |
private enum RegisterMode | |
{ | |
Pull, | |
Push | |
} | |
/// <summary> | |
/// Logger instance. | |
/// </summary> | |
private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); | |
/// <summary> | |
/// The TCP/IP endpoint of the relay server. | |
/// </summary> | |
private static IPEndPoint relayEndpoint; | |
/// <summary> | |
/// The domain of this client. | |
/// </summary> | |
private static string domain; | |
/// <summary> | |
/// The relay identification of this client. | |
/// </summary> | |
private static string ident; | |
/// <summary> | |
/// The password to register this client at the relay server. | |
/// </summary> | |
private static string password; | |
/// <summary> | |
/// The relay identification of the job receiver. | |
/// </summary> | |
private static string targetIdent; | |
/// <summary> | |
/// The http relay client. | |
/// </summary> | |
private static PersistentClient client; | |
/// <summary> | |
/// The relay client registration mode defines whether push messages | |
/// should be sent from relay server to client or not. | |
/// </summary> | |
private static RegisterMode registerMode = RegisterMode.Push; | |
/// <summary> | |
/// Wait handle for incoming push jobs | |
/// </summary> | |
private static readonly ManualResetEvent PushJobReceivedWaitHandle = new ManualResetEvent(false); | |
/// <summary> | |
/// Number and timestamp of push messages retrieved within wait time. | |
/// </summary> | |
private static readonly ConcurrentDictionary<int, DateTime> PushOkDict = new ConcurrentDictionary<int, DateTime>(); | |
/// <summary> | |
/// Job-Id and Job for request response jobs. | |
/// </summary> | |
private static readonly ConcurrentDictionary<string, Job> JobDict = new ConcurrentDictionary<string, Job>(); | |
/// <summary> | |
/// List of timestamps indicating unsuccesful waits for push messages. | |
/// </summary> | |
private static readonly ConcurrentBag<DateTime> PushFailedList = new ConcurrentBag<DateTime>(); | |
/// <summary> | |
/// Number of pending jobs obtained from client relay registration. | |
/// </summary> | |
private static int jobsAvailable; | |
/// <summary> | |
/// Test program to demonstrate meter data communication. | |
/// </summary> | |
/// <param name="args">The args.</param> | |
static void Main(string[] args) | |
{ | |
Logger.Info("*** METERING JOB DEMO STARTED ***"); | |
// get command line parameters | |
ParseArguments(args); | |
//start client | |
Run(); | |
// increase receive timeout from 60 sec to 5 min. | |
client.DefaultReceiveTimeout = TimeSpan.FromMinutes(1); | |
client.ReceiveBufferSize = 8192 * 4; | |
// start monitoring | |
Monitor(); | |
// Register by pull and get all pending jobs (jobs stored on server) | |
//RegisterForPull(true); | |
// Reconnect and register for push messages | |
//RegisterForPush(); | |
//var kmServerId = "0502445A470001"; | |
//var kmIptIdent = "0502445A470001"; | |
while (true) | |
{ | |
// Read the most relevant data from a MUC device | |
//var meterServerId = ReadDzgMucMainParameters(TimeSpan.FromSeconds(20), kmIptIdent, kmServerId); | |
//if (string.IsNullOrEmpty(meterServerId)) | |
//{ | |
// Thread.Sleep(3000); | |
// continue; | |
//} | |
// Read collected load profile from MUC device | |
// ReadDzgMucLoadProfile(TimeSpan.FromSeconds(15), meterServerId, kmServerId, kmIptIdent); | |
ReadLzqjLoadProfile(TimeSpan.FromSeconds(120), "015256382650", "03180474"); | |
break; | |
// Set the push parameters of a MUC device | |
//WriteDzgMucPushParameters(TimeSpan.FromSeconds(10), meterServerId, kmServerId, kmIptIdent, TimeSpan.FromSeconds(60)); | |
// Read the push parameters of a MUC device | |
//ReadDzgMucPushParameters(TimeSpan.FromSeconds(10), meterServerId, kmServerId, kmIptIdent); | |
} | |
// shutdown http client | |
client.Terminate(); | |
Console.ReadLine(); | |
} | |
/// <summary> | |
/// Runs this instance. | |
/// </summary> | |
private static void Run() | |
{ | |
try | |
{ | |
if (client != null) | |
{ | |
client.Terminate(); | |
} | |
switch (registerMode) | |
{ | |
case RegisterMode.Pull: | |
RegisterForPull(); | |
break; | |
case RegisterMode.Push: | |
RegisterForPush(); | |
break; | |
} | |
} | |
catch (Exception ex) | |
{ | |
Logger.ErrorException("Run failed", ex); | |
} | |
} | |
/// <summary> | |
/// Registers for pull. | |
/// <remarks>Use pull for relay client registration in order to avoid that job | |
/// status changes are sent to the client.</remarks> | |
/// </summary> | |
/// <param name="getJobs">if set to <c>true</c> [get jobs].</param> | |
private static void RegisterForPull(bool getJobs = false) | |
{ | |
try | |
{ | |
if (registerMode == RegisterMode.Pull && client != null && client.State == RelayState.Registered) | |
{ | |
return; | |
} | |
if (client != null) | |
{ | |
client.Terminate(); | |
} | |
client = new PersistentClient(relayEndpoint, domain, ident, password, pushJobs: false); | |
jobsAvailable = client.Register(TimeSpan.FromSeconds(15), true); | |
if (getJobs) | |
{ | |
// get remaining jobs first... | |
GetJobs(); | |
} | |
} | |
catch (Exception ex) | |
{ | |
Logger.ErrorException("Relay registration failed (pull).", ex); | |
} | |
} | |
/// <summary> | |
/// Registers for push. | |
/// <remarks>Use push for relay client registration in order to let this client be notified about new incoming jobs | |
/// or job status changes.</remarks> | |
/// </summary> | |
private static void RegisterForPush() | |
{ | |
try | |
{ | |
if (registerMode == RegisterMode.Push && client != null && client.State == RelayState.Registered) | |
{ | |
return; | |
} | |
if (client != null) | |
{ | |
client.Terminate(); | |
} | |
client = new PersistentClient(relayEndpoint, domain, ident, password, pushJobs: true); | |
jobsAvailable = client.Register(TimeSpan.FromSeconds(15), true); | |
// bind event handler | |
client.NewJobReceived += (@base, job) => ProcessNewMeterComJobResult(job); | |
client.UpdatedJobReceived += (source, job) => ProcessUpdatedMeterComJobResult(job); | |
} | |
catch (Exception ex) | |
{ | |
Logger.ErrorException("Relay registration failed (push).", ex); | |
} | |
} | |
/// <summary> | |
/// Gets the jobs. | |
/// </summary> | |
private static void GetJobs() | |
{ | |
while (jobsAvailable-- > 0) | |
{ | |
Job job; | |
if (!client.TryGetJob(TimeSpan.FromSeconds(10), out job)) | |
{ | |
Logger.Error("Getjob failed."); | |
client.Disconnect(); | |
return; | |
} | |
if (job == null) | |
{ | |
Logger.Error("Job is null."); | |
client.Disconnect(); | |
return; | |
} | |
} | |
} | |
/// <summary> | |
/// Monitors this instance. | |
/// </summary> | |
private static void Monitor() | |
{ | |
Task.Factory.StartNew( | |
() => | |
{ | |
while (true) | |
{ | |
if (DateTime.Now - client.LastDataReceived < TimeSpan.FromSeconds(10)) | |
{ | |
Thread.Sleep(1000); | |
continue; | |
} | |
Logger.Info("Timed out push operations: {0}.", PushFailedList.Count); | |
if (PushFailedList.Count > 0) | |
{ | |
PushFailedList.Reverse().Take(10).ToList().ForEach(e => Logger.Info("Failed push receive, timed out at: {0}.", e)); | |
} | |
Logger.Info("Successful push operations: {0}.", PushOkDict.Count); | |
if (PushOkDict.Count > 0) | |
{ | |
Logger.Info("Last successful push receive: {0}.", PushOkDict[PushOkDict.Count - 1]); | |
} | |
if (!client.TryPing(TimeSpan.FromSeconds(3))) | |
{ | |
Logger.Warn("Ping failed, restarting..."); | |
Thread.Sleep(1000); | |
Run(); | |
} | |
} | |
}); | |
} | |
/// <summary> | |
/// Reads the DZG muc main parameters. | |
/// </summary> | |
/// <param name="waitTime">The wait time.</param> | |
/// <param name="iptAddress">The ipt address.</param> | |
/// <param name="kmServerId">The km server id.</param> | |
/// <param name="kmUsername">The km username.</param> | |
/// <param name="kmPassword">The km password.</param> | |
public static string ReadDzgMucMainParameters(TimeSpan waitTime, string iptAddress, string kmServerId, string kmUsername = "admin", string kmPassword = "geheim!") | |
{ | |
if (client.State != RelayState.Registered) | |
{ | |
return null; | |
} | |
var asf = new MeterComJobData( | |
kmServerId, //< Sensor Server Id | |
AddressInfo. Gsm("0151 1234567", "AT&F"), //< Use IPT for communication between Relay and MUC | |
DeviceDriver.DzgMuc) { ComModuleUsername = kmUsername, ComModulePassword = kmPassword, ComModuleId = kmServerId }; //< Driver | |
// create request | |
var mcjd = new MeterComJobData( | |
kmServerId, //< Sensor Server Id | |
AddressInfo.Ipt(iptAddress), //< Use IPT for communication between Relay and MUC | |
DeviceDriver.DzgMuc) { ComModuleUsername = kmUsername, ComModulePassword = kmPassword, ComModuleId = kmServerId }; //< Driver | |
// add actions | |
mcjd.Add(DeviceDriver.DzgMuc.ReadMainParameters()); | |
// create job | |
var job = new MeterComJob( | |
mcjd, | |
new RelayUri(domain, targetIdent).GetCanonicalString(), // Job target address is Relay's internal metering node | |
"Metering com job " + DateTime.Now, MeterComJobBinaryConverter.Json); // Job name | |
// transmit job to relay | |
client.AddJob(job, TimeSpan.FromSeconds(5), true); | |
if (job.Id == null) | |
{ | |
Logger.Warn("No job id received."); | |
return null; | |
} | |
JobDict[job.Id.ToString()] = job; | |
// wait for any job result | |
if (!client.JobResultWaitHandle.WaitOne(waitTime)) | |
{ | |
Logger.Warn("Job timed out!"); | |
return null; | |
} | |
// job result available, process result data | |
var resultJob = JobDict[job.Id.ToString()]; | |
var results = ProcessComJobResult(resultJob, false); | |
var r = results.OfType<DeviceInfoResponse>().FirstOrDefault(mp => mp.Sensors.FirstOrDefault() != null); | |
if (r != null) | |
{ | |
var s = r.Sensors.FirstOrDefault(); | |
if (s != null && s.ServerId != null) | |
{ | |
return BitConverter.ToString(s.ServerId).Replace("-", string.Empty); | |
} | |
} | |
return null; | |
} | |
/// <summary> | |
/// Reads the DZG muc load profile. | |
/// </summary> | |
/// <param name="waitTime">The wait time.</param> | |
/// <param name="meterServerId">The meter server id.</param> | |
/// <param name="kmServerId">The km server id.</param> | |
/// <param name="iptAddress">The ipt address.</param> | |
/// <param name="kmUsername">The km username.</param> | |
/// <param name="kmPassword">The km password.</param> | |
public static void ReadDzgMucLoadProfile(TimeSpan waitTime, string meterServerId, string kmServerId, string iptAddress, string kmUsername = "admin", string kmPassword = "geheim!") | |
{ | |
if (client.State != RelayState.Registered) | |
{ | |
return; | |
} | |
// create request | |
var mcjd = new MeterComJobData( | |
meterServerId, //< Sensor Server Id | |
AddressInfo.Ipt(iptAddress), //< Use IPT for communication between Relay and MUC | |
DeviceDriver.DzgMuc) { ComModuleUsername = kmUsername, ComModulePassword = kmPassword, ComModuleId = kmServerId }; //< Driver | |
// add actions | |
mcjd.Add(DeviceDriver.DzgMuc.ReadDataCollector(DeviceDriverSmlMuc.CollectorType.MeasurementsPerQuarterHour, DateTime.UtcNow.AddMinutes(-150), DateTime.UtcNow)); | |
// create job | |
var job = new MeterComJob( | |
mcjd, | |
new RelayUri(domain, targetIdent).GetCanonicalString(), // Job target address is Relay's internal metering node | |
"Metering com job " + DateTime.Now, MeterComJobBinaryConverter.Json); // Job name | |
// transmit job to relay | |
if (!client.TryAddJob(job, TimeSpan.FromSeconds(3))) | |
{ | |
Logger.Warn("Adding job failed."); | |
return; | |
} | |
// wait for any job result | |
if (!client.JobResultWaitHandle.WaitOne(waitTime)) | |
{ | |
Logger.Warn("Job timed out!"); | |
} | |
} | |
/// <summary> | |
/// Reads the LZQJ load profile. | |
/// </summary> | |
/// <param name="waitTime">The wait time.</param> | |
/// <param name="kmPhoneNumber">The km phone number.</param> | |
/// <param name="meterServerId">The meter server id.</param> | |
/// <returns></returns> | |
public static void ReadLzqjLoadProfile(TimeSpan waitTime, string kmPhoneNumber, string meterServerId) | |
{ | |
if (client.State != RelayState.Registered) | |
{ | |
return; | |
} | |
// create request | |
var mcjd = new MeterComJobData( | |
meterServerId, //< Meter Id | |
AddressInfo.Gsm(kmPhoneNumber), //< Use AT-modem for communication between Relay and meter | |
DeviceDriver.Lzqj); //< Driver | |
// add actions | |
mcjd.Add(DeviceDriver.Lzqj.ReadLoadProfileAction(DateTime.Now.AddDays(-1), DateTime.Now)); | |
// create job | |
var job = new MeterComJob( | |
mcjd, | |
new RelayUri(domain, targetIdent).GetCanonicalString(), // Job target address is Relay's internal metering node | |
"Metering com job " + DateTime.Now, MeterComJobBinaryConverter.Json); // Job name | |
// transmit job to relay | |
if (!client.TryAddJob(job, TimeSpan.FromSeconds(3))) | |
{ | |
Logger.Warn("Adding job failed."); | |
return; | |
} | |
// wait for any job result | |
if (!client.JobResultWaitHandle.WaitOne(waitTime)) | |
{ | |
Logger.Warn("Job timed out!"); | |
} | |
} | |
/// <summary> | |
/// Reads the DZG muc push parameters. | |
/// </summary> | |
/// <param name="waitTime">The wait time.</param> | |
/// <param name="kmServerId">The km server id.</param> | |
/// <param name="sensorServerId">The sensor server id.</param> | |
/// <param name="kmIptIdent">The km ipt ident.</param> | |
/// <param name="kmUsername">The km username.</param> | |
/// <param name="kmPassword">The km password.</param> | |
public static void ReadDzgMucPushParameters(TimeSpan waitTime, string sensorServerId, string kmServerId, string kmIptIdent, string kmUsername = "admin", string kmPassword = "geheim!") | |
{ | |
if (client.State != RelayState.Registered) | |
{ | |
return; | |
} | |
// create request | |
var mcjd = new MeterComJobData( | |
sensorServerId, //< Sensor Server Id | |
AddressInfo.Ipt(kmIptIdent), //< Use IPT for communication between Relay and MUC | |
DeviceDriver.DzgMuc) { ComModuleUsername = kmUsername, ComModulePassword = kmPassword, ComModuleId = kmServerId }; //< Driver | |
// add actions | |
mcjd.Add(DeviceDriver.DzgMuc.ReadPushInterval(DeviceDriverSmlMuc.CollectorType.MeasurementsPerMinute)); | |
//mcjd.Add(DeviceDriver.DzgMuc.ReadPushInterval(DeviceDriverSmlMuc.CollectorType.MeasurementsPerQuarterHour)); | |
// create job | |
var job = new MeterComJob( | |
mcjd, | |
new RelayUri(domain, targetIdent).GetCanonicalString(), // Job target address is Relay's internal metering node | |
"Metering com job " + DateTime.Now, MeterComJobBinaryConverter.Json); // Job name | |
// transmit job to relay | |
client.AddJob(job, TimeSpan.FromSeconds(5), true); | |
// wait for any job result | |
if (!client.JobResultWaitHandle.WaitOne(waitTime)) | |
{ | |
Logger.Warn("Job timed out!"); | |
} | |
} | |
/// <summary> | |
/// Writes the DZG muc push parameters. | |
/// </summary> | |
/// <param name="waitTime">The wait time.</param> | |
/// <param name="kmServerId">The km server id.</param> | |
/// <param name="sensorServerId">The sensor server id.</param> | |
/// <param name="kmIptIdent">The km ipt ident.</param> | |
/// <param name="kmUsername">The km username.</param> | |
/// <param name="kmPassword">The km password.</param> | |
public static void WriteDzgMucPushParameters(TimeSpan waitTime, string sensorServerId, string kmServerId, string kmIptIdent, TimeSpan pushInterval, string kmUsername = "admin", string kmPassword = "geheim!") | |
{ | |
if (client.State != RelayState.Registered) | |
{ | |
return; | |
} | |
// create request | |
var mcjd = new MeterComJobData( | |
sensorServerId, //< Sensor Server Id | |
AddressInfo.Ipt(kmIptIdent), //< Use IPT for communication between Relay and MUC | |
DeviceDriver.DzgMuc) { ComModuleUsername = kmUsername, ComModulePassword = kmPassword, ComModuleId = kmServerId }; //< Driver | |
// add actions | |
mcjd.Add(DeviceDriver.DzgMuc.SetPushInterval(pushInterval, DeviceDriverSmlMuc.CollectorType.MeasurementsPerMinute)); | |
// create job | |
var job = new MeterComJob( | |
mcjd, | |
new RelayUri(domain, targetIdent).GetCanonicalString(), // Job target address is Relay's internal metering node | |
"Metering com job " + DateTime.Now, MeterComJobBinaryConverter.Json); // Job name | |
// transmit job to relay | |
client.AddJob(job, TimeSpan.FromSeconds(5), true); | |
// wait for any job result | |
if (!client.JobResultWaitHandle.WaitOne(waitTime)) | |
{ | |
Logger.Warn("Job timed out!"); | |
} | |
} | |
/// <summary> | |
/// Gets the node status. | |
/// </summary> | |
private static void GetNodeStatus() | |
{ | |
if (client.State != RelayState.Registered) | |
{ | |
return; | |
} | |
var nodeStates = client.GetNodeStates(HostType.Device, TimeSpan.FromSeconds(3)); | |
nodeStates.ToList().ForEach(ns => | |
Logger.Debug("Host type: {0}, ident {1}, last updated {2}, registrations {3}/{4}, sessions {5}.", | |
ns.HostType, | |
ns.Ident, | |
ns.LastUpdate, | |
ns.ActiveRegistrationsTotal, | |
ns.MaxRegistrationsTotal, | |
ns.ActiveSessionsTotal)); | |
} | |
/// <summary> | |
/// Processes a new incoming meter COM job. | |
/// </summary> | |
/// <param name="job">The new job with result data.</param> | |
private static void ProcessNewMeterComJobResult(Job job) | |
{ | |
Logger.Info("Processing --- NEW --- meter com job result..."); | |
// signal wait handle and store job in push dictionary | |
PushJobReceivedWaitHandle.Set(); | |
PushOkDict[PushOkDict.Count] = DateTime.Now; | |
ProcessComJobResult(job); | |
} | |
/// <summary> | |
/// Processes an updated meter COM job. | |
/// </summary> | |
/// <param name="job">The updated job with result data.</param> | |
private static void ProcessUpdatedMeterComJobResult(Job job) | |
{ | |
Logger.Info("#### Processing --- UPDATED --- meter com job result..."); | |
// store job in job dictionary | |
JobDict[job.Id.ToString()] = job; | |
ProcessComJobResult(job); | |
} | |
/// <summary> | |
/// Processes the meter COM job result. | |
/// <remarks>Set a breakpoint to debug the result data structures.</remarks> | |
/// </summary> | |
/// <param name="job">The job with metering result data.</param> | |
/// <param name="printResults">if set to <c>true</c> [print results].</param> | |
/// <returns></returns> | |
/// <exception cref="System.NullReferenceException">MeterComJob</exception> | |
/// <exception cref="System.ArgumentOutOfRangeException"></exception> | |
private static List<ActionResult> ProcessComJobResult(Job job, bool printResults = true) | |
{ | |
var resultList = new List<ActionResult>(); | |
if (job.Status == JobStatus.Failed || job.Status == JobStatus.Unprocessed) | |
{ | |
return resultList; | |
} | |
MeterComJob mcj; | |
if (MeterComJob.TryConvert(job, out mcj, MeterComJobBinaryConverter.Json) == false) | |
{ | |
throw new NullReferenceException("MeterComJob"); | |
} | |
if (mcj.MeterComJobResult == null) | |
{ | |
throw new NullReferenceException("MeterComJobResult"); | |
} | |
foreach (var result in mcj.MeterComJobResult.Results) | |
{ | |
Logger.Info("**** Result received ****"); | |
resultList.Add(result); | |
if (!printResults) | |
{ continue; } | |
switch (result.RequestActionType) | |
{ | |
case ActionType.ReadList: | |
var listResult = result as ListResponse; | |
if (listResult == null) | |
{ | |
throw new NullReferenceException("listResult"); | |
} | |
Logger.Info(listResult.ToString()); | |
break; | |
case ActionType.ReadDateTime: | |
var dateTimeResult = result as DateTimeResponse; | |
if (dateTimeResult == null) | |
{ | |
throw new NullReferenceException("dateTimeResult"); | |
} | |
Logger.Info(dateTimeResult); | |
break; | |
case ActionType.ReadEventLog: | |
var eventLogResult = result as EventLogResponse; | |
if (eventLogResult == null) | |
{ | |
throw new NullReferenceException("eventLogResult"); | |
} | |
Logger.Info(eventLogResult); | |
break; | |
case ActionType.ReadLoadProfile: | |
var readLoadProfileResult = result as LoadProfileResponse; | |
if (readLoadProfileResult == null) | |
{ | |
throw new NullReferenceException("readLoadProfileResult"); | |
} | |
Logger.Info(readLoadProfileResult); | |
break; | |
case ActionType.ReadRegister: | |
var registerResponse = result as RegisterResponse; | |
if (registerResponse == null) | |
{ | |
throw new NullReferenceException("registerResponse"); | |
} | |
Logger.Info(registerResponse); | |
break; | |
case ActionType.ReadParameter: | |
var parameterResponse = result as ParameterResponse; | |
if (parameterResponse == null) | |
{ | |
throw new NullReferenceException("parameterResponse"); | |
} | |
Logger.Info(parameterResponse); | |
if (parameterResponse.Tree != null && parameterResponse.Tree.ValueId != null && parameterResponse.Tree.Value != null) | |
{ | |
if (parameterResponse.Tree.ValueId.ToLowerInvariant().Equals("interval")) | |
{ | |
Logger.Info("MUC PUSH Interval: {0} SEC.", parameterResponse.Tree.Value.UnsignedValue); | |
} | |
} | |
break; | |
case ActionType.WriteDateTime: | |
var writeDateResult = result as WriteDateTimeResponse; | |
if (writeDateResult == null) | |
{ | |
throw new NullReferenceException("writeDateResult"); | |
} | |
Logger.Info(writeDateResult); | |
break; | |
case ActionType.WriteParameter: | |
var writeParamResult = result as WriteParameterResponse; | |
if (writeParamResult == null) | |
{ | |
throw new NullReferenceException("writeParamResult"); | |
} | |
Logger.Info(writeParamResult); | |
break; | |
case ActionType.ReadDeviceInfo: | |
var deviceInfoResult = result as DeviceInfoResponse; | |
if (deviceInfoResult == null) | |
{ | |
throw new NullReferenceException("deviceInfoResult"); | |
} | |
Logger.Info(deviceInfoResult); | |
break; | |
default: | |
throw new ArgumentOutOfRangeException(); | |
} | |
} | |
return resultList; | |
} | |
/// <summary> | |
/// Waits for push data. | |
/// </summary> | |
/// <param name="waitTime">The wait time.</param> | |
private static void WaitForPushData(TimeSpan waitTime) | |
{ | |
PushJobReceivedWaitHandle.Reset(); | |
if (!PushJobReceivedWaitHandle.WaitOne(waitTime)) | |
{ | |
Logger.Error("Waiting for push job timed out after: {0}.", waitTime); | |
PushFailedList.Add(DateTime.Now); | |
} | |
} | |
/// <summary> | |
/// Creates a com job for reading a MUC meter gateway with the relay using a TCP connection to connect to the device. | |
/// </summary> | |
/// <remarks>The client uses job notifications to receive job responses.</remarks> | |
/// <param name="client">The client.</param> | |
/// <param name="waitTime">The wait time for job responses.</param> | |
public static void PutMeterComJobMucIpt(PersistentClient client, TimeSpan waitTime) | |
{ | |
// create request | |
var mcjd = new MeterComJobData( | |
"0901445A4700014FB180", //< Sensor Server Id | |
AddressInfo.Ipt("device4"), //< Use IPT for communication between Relay and MUC | |
DeviceDriver.DzgMuc) { ComModuleUsername = "admin", ComModulePassword = "geheim!", ComModuleId = "0500153B016AD6" }; //< Driver | |
// add actions | |
//mcjd.Add(DeviceDriver.DzgMuc.SetNtpParameters( | |
// new DeviceDriverSmlMuc.NtpParameter() { HostnameOrIp = "ptbtime1.ptb.de", PortNumber = 123, IsActive = true }, | |
// new DeviceDriverSmlMuc.NtpParameter() { HostnameOrIp = "ptbtime2.ptb.de", PortNumber = 123, IsActive = false })); | |
//mcjd.Add(DeviceDriver.DzgMuc.ReadCurrentMeasurementData()); | |
//mcjd.Add(DeviceDriver.DzgMuc.ReadDataCollector(DeviceDriverSmlMuc.CollectorType.MeasurementsPerMinute, DateTime.UtcNow.AddMinutes(-3), DateTime.UtcNow)); | |
//mcjd.Add(DeviceDriver.DzgMuc.ReadMainParameters()); | |
mcjd.Add(DeviceDriver.DzgMuc.ReadNtpParameters()); | |
// create job | |
var job = new MeterComJob( | |
mcjd, | |
new RelayUri(domain, targetIdent).GetCanonicalString(), // Job target address is Relay's internal metering node | |
"Metering com job " + DateTime.Now, MeterComJobBinaryConverter.Json); // Job name | |
// transmit job to relay | |
client.AddJob(job, TimeSpan.FromSeconds(3), true); | |
// wait for any job result | |
if (!client.JobResultWaitHandle.WaitOne(waitTime)) | |
{ | |
Logger.Warn("Job timed out!"); | |
} | |
} | |
//public static void PutMeterComJobMucTcp(PersistentClient client, TimeSpan waitTime) | |
//{ | |
// // create request | |
// var mcjd = new MeterComJobData( | |
// "0901445A4700014FB180", //< Sensor Server Id | |
// AddressInfo.Tcp("192.168.178.36", 7259, false), //< Use TCP/IP between Relay and MUC | |
// DeviceDriver.DzgMuc) { ComModuleUsername = "admin", ComModulePassword = "geheim!", ComModuleId = "0500153B016AD6" }; //< Driver | |
// // add actions | |
// mcjd.Add(DeviceDriver.DzgMuc.SetNtpParameters( | |
// new DeviceDriverSmlMuc.NtpParameter() { HostnameOrIp = "ptbtime1.ptb.de", PortNumber = 123, IsActive = true }, | |
// new DeviceDriverSmlMuc.NtpParameter() { HostnameOrIp = "ptbtime2.ptb.de", PortNumber = 123, IsActive = false })); | |
// mcjd.Add(DeviceDriver.DzgMuc.ReadCurrentMeasurementData()); | |
// mcjd.Add(DeviceDriver.DzgMuc.ReadMainParameters()); | |
// // create job | |
// var job = new MeterComJob( | |
// mcjd, | |
// new RelayUri(domain, targetIdent).GetCanonicalString(), // Job target address is Relay's internal metering node | |
// "Metering com job " + DateTime.Now, MeterComJobBinaryConverter.Json); // Job name | |
// // transmit job to relay | |
// client.AddJob(job, TimeSpan.FromSeconds(3), true); | |
// // wait for any job result | |
// if (!client.JobResultWaitHandle.WaitOne(waitTime)) | |
// { | |
// Logger.Warn("Job timed out!"); | |
// } | |
//} | |
private static void ParseArguments(string[] args) | |
{ | |
if (!args.Any()) | |
{ | |
Console.WriteLine("No parameters given, using default."); | |
relayEndpoint = new IPEndPoint(Dns.GetHostAddresses("msk-software.de").First(), 18080); | |
//relayEndpoint = new IPEndPoint(Dns.GetHostAddresses("213.209.107.181").First(), 8080); | |
//domain = "ivu"; | |
//ident = "msk2"; | |
domain = "DomainA"; | |
ident = "btcamm"; | |
//ident = "pushtarget"; | |
password = "geheim"; | |
targetIdent = "metering1"; | |
return; | |
} | |
bool showHelp = false; | |
var os = new OptionSet() | |
{ | |
{"s|server=", "The hostname or ip address of the relay server", v => relayEndpoint = new IPEndPoint(Dns.GetHostAddresses(v).First(), 18080) }, | |
{"p|port=", "The tcp port of the relay server", v => relayEndpoint.Port = int.Parse(v)}, | |
{"d|domain=", "The relay domain of this client", v => domain = v}, | |
{"i|ident=", "The relay ident of this client", v => ident = v}, | |
{"t|target=", "The relay ident of the job target", v => targetIdent = v}, | |
{"pw|password=", "The password of this client", v => password = v}, | |
{"h|help", "show this message and exit", s => { showHelp = true; }}, | |
}; | |
try | |
{ | |
os.Parse(args); | |
if (showHelp) | |
{ | |
os.WriteOptionDescriptions(Console.Out); | |
Environment.Exit(1); | |
} | |
} | |
catch (OptionException e) | |
{ | |
Console.Write(e.Message); | |
Console.WriteLine("Try '--help' for more information."); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment