private void LoadDevices(List <ModbusDeviceDefinition> modbusDevicesDefintions) { if (PackageHost.ContainsSetting("Devices")) { // Read the JSON setting var devices = PackageHost.GetSettingAsJsonObject <List <ModbusDevice> >("Devices"); // For each device foreach (ModbusDevice device in devices) { // Get the definition from the ModbusDeviceDefinitions's setting var definition = modbusDevicesDefintions.FirstOrDefault(d => d.Name == device.DeviceType); // If the definition exists if (definition != null) { // Registering the device PackageHost.WriteInfo($"Registering {device} ({definition.Name} with {definition.Properties.Count} properties). Interval: {device.RequestInterval} second(s)"); this.deviceStates.Add(new DeviceState { Device = device, Definition = definition }); } else { // Otherwise ignore this device ! PackageHost.WriteWarn($"The device {device} will be ignore : unknown device type ({device.DeviceType})"); } } } }
/// <summary> /// Called when the package is started. /// </summary> public override void OnStart() { Task.Factory.StartNew(async() => { while (PackageHost.IsRunning) { try { if (PackageHost.ContainsSetting("Monitoring")) { dynamic config = PackageHost.GetSettingAsJsonObject("Monitoring", true); foreach (dynamic ressource in config) { string name = ressource.Name.Value; if (monitoringChecks.ContainsKey(name) == false || DateTime.Now.Subtract(monitoringChecks[name]).TotalSeconds >= (ressource["Interval"] != null ? ressource.Interval.Value : DEFAULT_CHECK_INTERVAL)) { this.CheckResource(name, ressource.Type.Value, ressource); monitoringChecks[name] = DateTime.Now; } } } } catch (Exception ex) { PackageHost.WriteError("Monitor task error : " + ex.Message); } await Task.Delay(1000); } }, TaskCreationOptions.LongRunning); }
/// <summary> /// Package start /// </summary> public override void OnStart() { PackageHost.WriteInfo("Package starting - IsRunning: {0} - IsConnected: {1}", PackageHost.IsRunning, PackageHost.IsConnected); //parallel connection to the devices PackageHost.GetSettingAsJsonObject <IEnumerable <DeviceConfig> >("Devices").AsParallel().ForAll(dc => { //create new device and connect Device device = new Device(dc.Hostname, dc.Port) { Name = dc.Name }; try { if (device.Connect().Result) { PackageHost.WriteInfo($"Device {dc.Name} ({dc.Hostname}:{dc.Port}) connected"); device.OnNotificationReceived += (object sender, NotificationReceivedEventArgs e) => { //updated device properties PackageHost.PushStateObject(dc.Name, device.Properties); PackageHost.WriteDebug(e.Result); }; device.OnError += (object sender, UnhandledExceptionEventArgs e) => { PackageHost.WriteError(e.ExceptionObject); }; //initial device properties PackageHost.PushStateObject(dc.Name, device.Properties); } _all.Add(dc.Name, device); } catch (Exception ex) { PackageHost.WriteError($"Unable to connect to device {dc.Name} ({dc.Hostname}:{dc.Port}) : {ex.Message}");; } }); //creation of groups foreach (DeviceGroupConfig gc in PackageHost.GetSettingAsJsonObject <IEnumerable <DeviceGroupConfig> >("Groups")) { DeviceGroup group = new DeviceGroup(); foreach (Device device in gc.Devices.Select(x => _all.SingleOrDefault(d => d.Key == x).Value)) { group.Add(device); } _all.Add(gc.Name, group); } }
/// <summary> /// Main function /// </summary> public override void OnStart() { PackageHost.WriteInfo("Package starting - IsRunning: {0} - IsConnected: {1}", PackageHost.IsRunning, PackageHost.IsConnected); // Get the custom names soCustomNames = PackageHost.GetSettingAsJsonObject <Dictionary <string, string> >("soCustomNames"); PackageHost.SettingsUpdated += (s, e) => { soCustomNames = PackageHost.GetSettingAsJsonObject <Dictionary <string, string> >("soCustomNames"); }; Thread connexion = new Thread(new ThreadStart(this.StartListener)); connexion.Start(); }
/// <summary> /// Package start /// </summary> public override void OnStart() { PackageHost.WriteInfo("Package starting - IsRunning: {0} - IsConnected: {1}", PackageHost.IsRunning, PackageHost.IsConnected); //parallel connection to the devices PackageHost.GetSettingAsJsonObject <IEnumerable <DeviceConfig> >("Devices").AsParallel().ForAll(dc => { //create new device and connect Device device = new Device(dc.Hostname, dc.Port) { Name = dc.Name }; try { device.Connect().Wait(); if (device.IsConnected) { device.OnError -= ErrorEvent; device.OnError += ErrorEvent; device.SetName(dc.Name).Wait(); PackageHost.WriteInfo($"device '{dc.Name}' ({device.Hostname}:{device.Port}) connected"); } } catch (Exception ex) { PackageHost.WriteWarn($"Cannot connect device '{device.Name}' ({device.Hostname}:{device.Port}), message : {ex.Message}"); } _all.Add(dc.Name, device); }); //creation of groups foreach (DeviceGroupConfig gc in PackageHost.GetSettingAsJsonObject <IEnumerable <DeviceGroupConfig> >("Groups")) { DeviceGroup group = new DeviceGroup(); foreach (Device device in gc.Devices.Select(x => _all.SingleOrDefault(d => d.Key == x).Value)) { group.Add(device); } _all.Add(gc.Name, group); } UpdateDevicesStateObjects(); }
/// <summary> /// Package start /// </summary> public override void OnStart() { PackageHost.WriteInfo("Package starting - IsRunning: {0} - IsConnected: {1}", PackageHost.IsRunning, PackageHost.IsConnected); // Get the custom names this.soCustomNames = PackageHost.GetSettingAsJsonObject <Dictionary <string, Tuple <string, int> > >("soCustomNames"); PackageHost.SettingsUpdated += (s, e) => { this.soCustomNames = PackageHost.GetSettingAsJsonObject <Dictionary <string, Tuple <string, int> > >("soCustomNames"); }; // Connect to rflink PackageHost.WriteInfo($"Connecting to RfLink device ... {PackageHost.GetSettingValue("PortName")}"); this.RFLinkConnect(PackageHost.GetSettingValue("PortName"), new List <string>()); // Assert RfLink is alive KeepAlive(); }
private static List <ModbusDeviceDefinition> LoadModbusDevicesDefinitions() { if (PackageHost.ContainsSetting("ModbusDeviceDefinitions")) { // Read the JSON setting var modbusDevicesDefintions = PackageHost.GetSettingAsJsonObject <List <ModbusDeviceDefinition> >("ModbusDeviceDefinitions"); // For each definition foreach (ModbusDeviceDefinition definition in modbusDevicesDefintions) { // Create the StateObject type descriptor var soType = new PackageDescriptor.TypeDescriptor { TypeName = definition.Name, TypeFullname = $"Modbus.{definition.Name}", Description = definition.Description, Properties = definition.Properties.Select(p => new PackageDescriptor.MemberDescriptor { Name = p.Name, Description = p.Description, Type = PackageDescriptor.MemberDescriptor.MemberType.Property, TypeName = p.GetCLRType().FullName }).ToList() }; // And add it to the Package's descriptor PackageHost.WriteInfo($"Registering type {soType.TypeFullname} ..."); PackageHost.PackageDescriptor.StateObjectTypes.Add(soType); } // Declare the Package's descriptor on Constellation PackageHost.DeclarePackageDescriptor(); // Return the loaded definitions return(modbusDevicesDefintions); } else { return(null); } }
/// <summary> /// Called when the package is started. /// </summary> public override void OnStart() { // Check PortName settings if (!PackageHost.ContainsSetting("PortName")) { PackageHost.WriteError("The setting 'PortName' is requiered to start the package !"); return; } // Get the custom names this.stateObjectCustomNames = PackageHost.GetSettingAsJsonObject <Dictionary <string, string> >("StateObjectCustomNames"); PackageHost.SettingsUpdated += (s, e) => { // Refresh the dictionary on settings's update! this.stateObjectCustomNames = PackageHost.GetSettingAsJsonObject <Dictionary <string, string> >("StateObjectCustomNames"); }; // Init the RFX manager this.rfx = new RfxManager(PackageHost.GetSettingValue("PortName")); // Message handler for verbose mode this.rfx.OnMessage += (s, e) => { if (PackageHost.GetSettingValue <bool>("Verbose")) { PackageHost.WriteInfo(e.Message); } }; // Forward message to group ? this.rfx.OnPacketReceived += (s, e) => { if (PackageHost.ContainsSetting("ForwardRawMessageToGroup") && !string.IsNullOrEmpty(PackageHost.GetSettingValue("ForwardRawMessageToGroup"))) { PackageHost.CreateMessageProxy(MessageScope.ScopeType.Group, PackageHost.GetSettingValue("ForwardRawMessageToGroup")).MessageReceived(e.Packet); } }; // Attach handler on receive packet this.rfx.Subscribe <InterfaceMessage>(p => { PackageHost.WriteInfo($"RFXCOM device ({p.TransceiverName}) connected on port '{this.rfx.RfxInterface.SerialPort.PortName}' with {p.Protocols.Count(i => i.Enabled)} protocol(s) enabled ({string.Join(", ", p.Protocols.Where(i => i.Enabled).Select(i => i.Name))})"); PackageHost.PushStateObject("RFXCOM", new { p.TransceiverName, p.TypeName, p.Protocols, p.FirmwareVersion }, "RfxCom.Device"); }); this.rfx.Subscribe <TemperatureSensor>(p => { // Push StateObject PackageHost.PushStateObject(this.GetStateObjectName("TemperatureSensor_" + p.SensorID), new { p.SensorID, p.Channel, p.SequenceNumber, p.BatteryLevel, p.SignalLevel, p.Temperature, p.SubTypeName }, "RfxCom.TemperatureSensor", new Dictionary <string, object>() { ["Type"] = p.TypeName, ["RawData"] = BitConverter.ToString(p.RawData) }, PackageHost.GetSettingValue <int>("SensorStateObjectLifetime")); }); this.rfx.Subscribe <TemperatureHumiditySensor>(p => { // Push StateObject PackageHost.PushStateObject(this.GetStateObjectName("TemperatureHumiditySensor_" + p.SensorID), new { p.SensorID, p.Channel, p.SequenceNumber, p.BatteryLevel, p.SignalLevel, p.Temperature, p.Humidity, p.Status, p.SubTypeName, }, "RfxCom.TemperatureHumiditySensor", new Dictionary <string, object>() { ["Type"] = p.TypeName, ["RawData"] = BitConverter.ToString(p.RawData) }, PackageHost.GetSettingValue <int>("SensorStateObjectLifetime")); }); // Starting ! var protocolsEnabled = PackageHost.ContainsSetting("ProtocolsEnabled") ? PackageHost.GetSettingValue("ProtocolsEnabled").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(p => p.Trim()).ToArray() : null; this.rfx.Connect(protocolsEnabled); PackageHost.WriteInfo("The RFXcom package is started!"); }
/// <summary> /// Called when the package is started. /// </summary> public override void OnStart() { // Getting last StateObjects from the previous instance PackageHost.LastStateObjectsReceived += (s, e) => { PackageHost.WriteInfo($"Receiving {e.StateObjects.Count} StateObject(s) from the previous package's instance"); // For each StateObjects e.StateObjects.ForEach(so => { var elementId = so.DynamicValue.Id.Value; // For all BinaryState if (this.ipx.Elements.ContainsKey(elementId) && so.Type == typeof(BinaryState).FullName) { if (so.DynamicValue.State == this.ipx.Elements[elementId].State && so.DynamicValue.LastKnownActivity.Value != null) { // Restore the LastKnownActivity if the state unchanged PackageHost.WriteInfo($"Restoring the LastKnownActivity to {so.DynamicValue.LastKnownActivity.Value} for {so.DynamicValue.Label}"); this.ipx.Elements[elementId].LastKnownActivity = Convert.ToDateTime(so.DynamicValue.LastKnownActivity.Value); this.PushIPXElement(this.ipx.Elements[elementId]); } else if (so.DynamicValue.State != this.ipx.Elements[elementId].State) { // Update the LastKnownActivity if the state changed PackageHost.WriteInfo($"Updating the LastKnownActivity for {so.DynamicValue.Label} (the state has changed)"); this.ipx.Elements[elementId].LastKnownActivity = DateTime.Now; this.PushIPXElement(this.ipx.Elements[elementId]); } } }); }; // Load the element's types to poll this.LoadElementTypesToPoll(); // Create the IPX800 v4 manager this.ipx = new IPX800v4( PackageHost.GetSettingValue("Host"), PackageHost.GetSettingValue <int>("HttpPort"), PackageHost.GetSettingValue("ApiKey"), PackageHost.GetSettingAsJsonObject <List <IPXElementConfiguration> >("ElementsConfigurations"), PackageHost.GetSettingValue <bool>("IgnoreUnknownElement")); // When a new element is added, push it to Constellation and watch property changes this.ipx.ElementAdded += (s, e) => { PackageHost.WriteInfo($"Adding {e.Element}"); e.Element.PropertyChanged += (s2, e2) => { PackageHost.WriteInfo($"Updating '{e2.PropertyName}' of '{(s2 as IIPXElement).Id}' => {s2}"); this.PushIPXElement(e.Element); if (s2 is BinaryState bs && bs.RefreshElementsOnUpdate?.Count > 0) { bs.RefreshElementsOnUpdate.ForEach(t => this.Refresh(t)); } }; this.PushIPXElement(e.Element); }; // Refresh all ! PackageHost.WriteInfo("Requesting IPX elements ..."); this.ipx.Refresh(); // Start the polling loop if needed if (this.elementTypesToPoll?.Count > 0) { PackageHost.WriteInfo($"Polling {string.Join(", ", this.elementTypesToPoll.Select(a => a.Key.ToString()))} every {PackageHost.GetSettingValue<int>("PollInterval")} second(s)"); // Poll now elementTypesToPoll.Keys.ToList().ForEach(type => this.ipx.Refresh(type)); // And start the timer this.timer = new Timer(PackageHost.GetSettingValue <int>("PollInterval") * 1000) { Enabled = true, AutoReset = true }; this.timer.Elapsed += (s, e) => elementTypesToPoll.Keys.ToList().ForEach(type => this.ipx.Refresh(type)); this.timer.Start(); } // Update settings PackageHost.SettingsUpdated += (s, e) => { if (this.timer != null) { this.timer.Interval = PackageHost.GetSettingValue <int>("PollInterval") * 1000; PackageHost.WriteInfo($"Updating the polling interval to {this.timer.Interval} ms"); } }; #if DEBUG // Used for debug only ! PackageHost.SubscribeMessages("IPX"); #endif PackageHost.WriteInfo("IPX800 connector is started!"); }