private static bool DeviceIsDimmer(PlugExtraData.clsPlugExtraData extraData) { int? manufacturerId = (int?)extraData.GetNamed("manufacturer_id"); ushort?prodId = (ushort?)extraData.GetNamed("manufacturer_prod_id"); ushort?prodType = (ushort?)extraData.GetNamed("manufacturer_prod_type"); int? relationship = (int?)extraData.GetNamed("relationship"); byte? commandClass = (byte?)extraData.GetNamed("commandclass"); return(manufacturerId == 12 && prodId == 12342 && prodType == 17479 && relationship == 4 && commandClass == 38); }
static internal void SetDeviceKeys(DeviceClass dev, string id, string name) { PlugExtraData.clsPlugExtraData pData = dev.get_PlugExtraData_Get(hs); if (pData == null) { pData = new PlugExtraData.clsPlugExtraData(); } pData.AddNamed("id", id); pData.AddNamed("name", name); dev.set_PlugExtraData_Set(hs, pData); }
public void SaveConfiguration() { var extraData = hsDevice.get_PlugExtraData_Get(HS); if (extraData == null) { extraData = new PlugExtraData.clsPlugExtraData(); } extraData.AddNamed("EnOcean Cfg", deviceConfig.ToString()); hsDevice.set_PlugExtraData_Set(HS, extraData); Controller.SaveConfiguration(); }
static internal string GetDeviceKeys(DeviceClass dev, out string name) { string id = ""; name = ""; PlugExtraData.clsPlugExtraData pData = dev.get_PlugExtraData_Get(hs); if (pData != null) { id = (string)pData.GetNamed("id"); name = (string)pData.GetNamed("name"); } return(id); }
public string MakeNewRule() { var dv = Instance.host.NewDeviceRef("R"); Scheduler.Classes.DeviceClass newDevice = (Scheduler.Classes.DeviceClass)Instance.host.GetDeviceByRef(dv); newDevice.set_InterfaceInstance(Instance.host, Instance.name); newDevice.set_Name(Instance.host, "Type Meter Calc " + dv); //newDevice.set_Location2(Instance.host, "ScratchpadRule"); newDevice.set_Location(Instance.host, "Utilities"); newDevice.set_Location2(Instance.host, "Calcs"); //newDevice.set_Interface(Instance.host, "Modbus Configuration");//Put here the registered name of the page for what we want in the Modbus tab!!! So easy! newDevice.set_Interface(Instance.host, Util.IFACE_NAME); //Needed to link device to plugin, so the tab calls back to the correct hardcoded homeseer function //newDevice.set_InterfaceInstance()'' SET INTERFACE INSTANCE newDevice.set_Relationship(Instance.host, Enums.eRelationship.Not_Set); newDevice.MISC_Set(Instance.host, Enums.dvMISC.NO_LOG); newDevice.MISC_Set(Instance.host, Enums.dvMISC.SHOW_VALUES); // newDevice.MISC_Set(Instance.host, Enums.dvMISC.HIDDEN); HomeSeerAPI.PlugExtraData.clsPlugExtraData EDO = new PlugExtraData.clsPlugExtraData(); // EDO = newDevice.get_PlugExtraData_Get(Instance.host); string ruleString = makeNewRules(); string userNote = newDevice.get_UserNote(Instance.host); userNote = userNote.Split("PLUGIN EXTRA DATA:".ToCharArray())[0]; userNote += "PLUGIN EXTRA DATA:" + ruleString.ToString(); newDevice.set_UserNote(Instance.host, userNote); EDO.AddNamed("SSIDKey", ruleString); newDevice.set_PlugExtraData_Set(Instance.host, EDO); // newDevice.set_Device_Type_String(Instance.host, makeNewModbusGateway()); var DevINFO = new DeviceTypeInfo_m.DeviceTypeInfo(); DevINFO.Device_API = DeviceTypeInfo_m.DeviceTypeInfo.eDeviceAPI.Plug_In; newDevice.set_DeviceType_Set(Instance.host, DevINFO); Instance.Devices.Add(new SiidDevice(Instance, newDevice)); MakeStewardVSP(dv); return("refresh"); }
public void Initialize() { Dictionary <int, Scheduler.Classes.DeviceClass> device_map = new Dictionary <int, Scheduler.Classes.DeviceClass>(); Dictionary <int, bool> processed = new Dictionary <int, bool>(); Scheduler.Classes.clsDeviceEnumeration devenum = HS.GetDeviceEnumerator() as Scheduler.Classes.clsDeviceEnumeration; while (!devenum.Finished) { Scheduler.Classes.DeviceClass dev = devenum.GetNext(); if (dev.get_Interface(null) != Constants.PLUGIN_STRING_NAME) { continue; // Not ours! } var extraData = dev.get_PlugExtraData_Get(HS); if (extraData == null) { extraData = new PlugExtraData.clsPlugExtraData(); } var typeStr = (string)extraData.GetNamed("EnOcean Type"); if (typeStr == null) { continue; // No type - continue } if (typeStr != "Controller") { continue; // Not a controller } var dataStr = (string)extraData.GetNamed("EnOcean Cfg"); if (dataStr == null) { Console.WriteLine("No json data on device - skipping"); // extraData.AddNamed("EnOcean Cfg", config.ToString()); // rootDev.set_PlugExtraData_Set(HS, extraData); continue; // Skip interface } else { var config = JObject.Parse(dataStr); Console.WriteLine("Loaded config: {0}", config.ToString()); var ctrlInstance = new EnOceanController(HS, HSCB, hspiInst, config); ctrlInstance.Initialize(); AddInterface(ctrlInstance); } } }
void LoadChildDevices() { Scheduler.Classes.clsDeviceEnumeration devenum = HS.GetDeviceEnumerator() as Scheduler.Classes.clsDeviceEnumeration; while (!devenum.Finished) { Scheduler.Classes.DeviceClass hsDev = devenum.GetNext(); if (hsDev.get_Interface(null) != Constants.PLUGIN_STRING_NAME) { continue; // Not ours! } var extraData = hsDev.get_PlugExtraData_Get(HS); if (extraData == null) { extraData = new PlugExtraData.clsPlugExtraData(); } var typeStr = (string)extraData.GetNamed("EnOcean Type"); // if (typeStr == null) // Console.WriteLine("Warning: No device type set on child device"); var dataStr = (string)extraData.GetNamed("EnOcean Cfg"); var childConfig = new JObject(); if (dataStr != null) { childConfig = JObject.Parse(dataStr); } if (hsDev.get_Address(null).StartsWith(ControllerId)) { // Console.WriteLine("DT : {0} vs {1}", hsDev.get_Device_Type_String(null), EnOceanDeviceType.SimpleDevice.ToString()); if (hsDev.get_Device_Type_String(null) != "EnOcean " + EnOceanDeviceType.SimpleDevice.ToString()) { continue; } DeviceTypes.CreateDeviceInstance(HS, this, hsDev.get_Address(null), (string)childConfig["device_type"], childConfig); Console.WriteLine("Found child device: {0}", hsDev.get_Address(null)); } } }
public Boolean Initialize() { Dictionary <int, Scheduler.Classes.DeviceClass> device_map = new Dictionary <int, Scheduler.Classes.DeviceClass>(); // Dictionary<int, JObject> json_map = new Dictionary<int, JObject>(); Dictionary <int, bool> processed = new Dictionary <int, bool>(); //config = new JObject(); rootDev = getHSRootDevice(); var extraData = rootDev.get_PlugExtraData_Get(HS); if (extraData == null) { extraData = new PlugExtraData.clsPlugExtraData(); } var typeStr = (string)extraData.GetNamed("EnOcean Type"); if (typeStr == null) { Console.WriteLine("No type on device - adding"); extraData.AddNamed("EnOcean Type", "Controller"); rootDev.set_PlugExtraData_Set(HS, extraData); } if (config["nodes"] == null) { config.Add("nodes", new JObject()); } setControllerStatus("Initializing ctrl instance on port " + getPortName()); controller = new EnOceanFrameLayer(); if (controller.Open(getPortName())) { controller.PacketEventHandler += controller_PacketEvent; setControllerStatus("Active"); } else { setControllerStatus("Port open error!"); // GetHSDeviceByAddress(0x1234abcd); return(false); } var p = EnOceanPacket.MakePacket_CO_RD_VERSION(); controller.Send(p, (EnOceanPacket recvPacket) => { if (recvPacket.getType() != PacketType.RESPONSE) { return(false); } var br = new BinaryReader(new MemoryStream(recvPacket.GetData())); Console.WriteLine("Ret Code = {0}", br.ReadByte()); Console.WriteLine("App Version {0}", br.ReadUInt32()); Console.WriteLine("API Version {0}", br.ReadUInt32()); var uniqueControllerId = br.ReadUInt32().ToString("x8"); this.UniqueControllerId = uniqueControllerId; Console.WriteLine("Chip ID {0}", uniqueControllerId); Console.WriteLine("Chip Version {0}", br.ReadUInt32()); var d = Encoding.UTF8.GetString(br.ReadBytes(16), 0, 16); Console.WriteLine("APP NAME: {0}", d); //TODO: Parse app description return(true); }); int timeout = 30; while (timeout-- > 0 && this.UniqueControllerId == "Unknown") { Console.WriteLine("Waiting for controller id!"); Thread.Sleep(100); } // GetHSDeviceByAddress(0x1234abcd); if (UniqueControllerId == "Unknown") { Console.WriteLine("USB Device did not respond!"); setControllerStatus("Initialization error!"); return(false); } LoadChildDevices(); return(true); }
public void Initialize() { Dictionary<int, Scheduler.Classes.DeviceClass> device_map = new Dictionary<int, Scheduler.Classes.DeviceClass>(); Dictionary<int, bool> processed = new Dictionary<int, bool>(); Scheduler.Classes.clsDeviceEnumeration devenum = HS.GetDeviceEnumerator() as Scheduler.Classes.clsDeviceEnumeration; while (!devenum.Finished) { Scheduler.Classes.DeviceClass dev = devenum.GetNext(); if (dev.get_Interface(null) != Constants.PLUGIN_STRING_NAME) continue; // Not ours! var extraData = dev.get_PlugExtraData_Get(HS); if (extraData == null) extraData = new PlugExtraData.clsPlugExtraData(); var typeStr = (string)extraData.GetNamed("EnOcean Type"); if (typeStr == null) continue; // No type - continue if (typeStr != "Controller") continue; // Not a controller var dataStr = (string)extraData.GetNamed("EnOcean Cfg"); if (dataStr == null) { Console.WriteLine("No json data on device - skipping"); // extraData.AddNamed("EnOcean Cfg", config.ToString()); // rootDev.set_PlugExtraData_Set(HS, extraData); continue; // Skip interface } else { var config = JObject.Parse(dataStr); Console.WriteLine("Loaded config: {0}", config.ToString()); var ctrlInstance = new EnOceanController(HS, HSCB, hspiInst, config); ctrlInstance.Initialize(); AddInterface(ctrlInstance); } } }
void LoadChildDevices() { Scheduler.Classes.clsDeviceEnumeration devenum = HS.GetDeviceEnumerator() as Scheduler.Classes.clsDeviceEnumeration; while (!devenum.Finished) { Scheduler.Classes.DeviceClass hsDev = devenum.GetNext(); if (hsDev.get_Interface(null) != Constants.PLUGIN_STRING_NAME) continue; // Not ours! var extraData = hsDev.get_PlugExtraData_Get(HS); if (extraData == null) extraData = new PlugExtraData.clsPlugExtraData(); var typeStr = (string)extraData.GetNamed("EnOcean Type"); // if (typeStr == null) // Console.WriteLine("Warning: No device type set on child device"); var dataStr = (string)extraData.GetNamed("EnOcean Cfg"); var childConfig = new JObject(); if (dataStr != null) childConfig = JObject.Parse(dataStr); if (hsDev.get_Address(null).StartsWith(ControllerId)) { // Console.WriteLine("DT : {0} vs {1}", hsDev.get_Device_Type_String(null), EnOceanDeviceType.SimpleDevice.ToString()); if (hsDev.get_Device_Type_String(null) != "EnOcean " + EnOceanDeviceType.SimpleDevice.ToString()) continue; DeviceTypes.CreateDeviceInstance(HS, this, hsDev.get_Address(null), (string)childConfig["device_type"], childConfig); Console.WriteLine("Found child device: {0}", hsDev.get_Address(null)); } } }
public Boolean Initialize() { Dictionary<int, Scheduler.Classes.DeviceClass> device_map = new Dictionary<int, Scheduler.Classes.DeviceClass>(); // Dictionary<int, JObject> json_map = new Dictionary<int, JObject>(); Dictionary<int, bool> processed = new Dictionary<int, bool>(); //config = new JObject(); rootDev = getHSRootDevice(); var extraData = rootDev.get_PlugExtraData_Get(HS); if (extraData == null) extraData = new PlugExtraData.clsPlugExtraData(); var typeStr = (string)extraData.GetNamed("EnOcean Type"); if (typeStr == null) { Console.WriteLine("No type on device - adding"); extraData.AddNamed("EnOcean Type", "Controller"); rootDev.set_PlugExtraData_Set(HS, extraData); } if (config["nodes"] == null) { config.Add("nodes", new JObject()); } setControllerStatus("Initializing ctrl instance on port " + getPortName()); controller = new EnOceanFrameLayer(); if (controller.Open(getPortName())) { controller.PacketEventHandler += controller_PacketEvent; setControllerStatus("Active"); } else { setControllerStatus("Port open error!"); // GetHSDeviceByAddress(0x1234abcd); return false; } var p = EnOceanPacket.MakePacket_CO_RD_VERSION(); controller.Send(p, (EnOceanPacket recvPacket) => { if (recvPacket.getType() != PacketType.RESPONSE) return false; var br = new BinaryReader(new MemoryStream(recvPacket.GetData())); Console.WriteLine("Ret Code = {0}", br.ReadByte()); Console.WriteLine("App Version {0}", br.ReadUInt32()); Console.WriteLine("API Version {0}", br.ReadUInt32()); var uniqueControllerId = br.ReadUInt32().ToString("x8"); this.UniqueControllerId = uniqueControllerId; Console.WriteLine("Chip ID {0}", uniqueControllerId); Console.WriteLine("Chip Version {0}", br.ReadUInt32()); var d = Encoding.UTF8.GetString(br.ReadBytes(16), 0, 16); Console.WriteLine("APP NAME: {0}", d); //TODO: Parse app description return true; }); int timeout = 30; while (timeout-- > 0 && this.UniqueControllerId == "Unknown") { Console.WriteLine("Waiting for controller id!"); Thread.Sleep(100); } // GetHSDeviceByAddress(0x1234abcd); if (UniqueControllerId == "Unknown") { Console.WriteLine("USB Device did not respond!"); setControllerStatus("Initialization error!"); return false; } LoadChildDevices(); return true; }
public override void HSEvent(Enums.HSEvent eventType, object[] parameters) { if (!IsAnyWebHookConfigured()) { Program.WriteLog(LogType.Debug, "Ignoring event " + eventType + " because no webhook endpoint is configured."); return; } Dictionary <string, object> dict = new Dictionary <string, object> { { "eventType", eventType.ToString() } }; try { int devRef; switch (eventType) { case Enums.HSEvent.VALUE_SET: case Enums.HSEvent.VALUE_CHANGE: devRef = (int)parameters[4]; if (ignoreUnchangedEvents && (double)parameters[2] == (double)parameters[3]) { Program.WriteLog(LogType.Verbose, $"Suppressing {eventType} for device {devRef} because its value did not change ({(double)parameters[2]} == {(double)parameters[3]})"); return; } dict.Add("address", (string)parameters[1]); dict.Add("newValue", ((double)parameters[2]).ToString(CultureInfo.InvariantCulture)); dict.Add("oldValue", ((double)parameters[3]).ToString(CultureInfo.InvariantCulture)); dict.Add("ref", devRef); break; case Enums.HSEvent.STRING_CHANGE: devRef = (int)parameters[3]; dict.Add("address", (string)parameters[1]); dict.Add("newValue", (string)parameters[2]); dict.Add("ref", devRef); break; default: Program.WriteLog(LogType.Warn, "Unknown event type " + eventType); return; } if (ignoredDeviceRefs.Contains(devRef)) { Program.WriteLog(LogType.Verbose, $"Suppressing {eventType} for device {devRef} because it is ignored."); return; } if (ignoreTimerEvents) { if (!deviceRefTimerState.ContainsKey(devRef)) { // We need to check if this is a timer DeviceClass device = (DeviceClass)hs.GetDeviceByRef(devRef); PlugExtraData.clsPlugExtraData deviceData = device.get_PlugExtraData_Get(hs); deviceRefTimerState[devRef] = deviceData.GetNamed("timername") != null && device.get_Interface(hs) == ""; } if (deviceRefTimerState[devRef]) { // This is a timer. Program.WriteLog(LogType.Verbose, $"Suppressing {eventType} for device {devRef} because it's a timer."); return; } } string json = jsonSerializer.Serialize(dict); Program.WriteLog(LogType.Verbose, json); for (byte i = 0; i < TOTAL_WEBHOOK_SLOTS; i++) { if (webHooks[i] == null) { continue; } WebHook webHook = webHooks[i]; webHook.Execute(new StringContent(json, Encoding.UTF8, "application/json")).ContinueWith((task) => { Program.WriteLog(LogType.Verbose, "Sent WebHook " + webHook + " with status code " + task.Result.StatusCode); if (!task.Result.IsSuccessStatusCode) { Program.WriteLog(LogType.Warn, "Got non-successful response code from WebHook " + webHook + ": " + task.Result.StatusCode); } task.Result.Dispose(); }).ContinueWith((task) => { if (task.Exception?.InnerException != null) { Program.WriteLog(LogType.Error, $"Unable to send WebHook {webHook}: {getInnerExceptionMessage(task.Exception)}"); } }, TaskContinuationOptions.OnlyOnFaulted); } } catch (Exception ex) { Program.WriteLog(LogType.Error, ex.ToString()); } }
public void SaveConfiguration() { var extraData = hsDevice.get_PlugExtraData_Get(HS); if (extraData == null) extraData = new PlugExtraData.clsPlugExtraData(); extraData.AddNamed("EnOcean Cfg", deviceConfig.ToString()); hsDevice.set_PlugExtraData_Set(HS, extraData); Controller.SaveConfiguration(); }
private int CreateBasicDevice() { try { //Creating a brand new device, and get the actual device from the device reference var fullName = Location + GetName() + Location2 + GetName() + Name + Unique; var dv = (DeviceClass)_hs.GetDeviceByRef(_hs.NewDeviceRef(fullName)); var dvRef = dv.get_Ref(_hs); //Setting the type to plugin device var typeInfo = new DeviceTypeInfo_m.DeviceTypeInfo { Device_Type = (int)DeviceTypeInfo_m.DeviceTypeInfo.eDeviceAPI.Plug_In, Device_API = DeviceTypeInfo_m.DeviceTypeInfo.eDeviceAPI.Plug_In, Device_SubType_Description = Name }; dv.set_DeviceType_Set(_hs, typeInfo); var pluginExtraData = new PlugExtraData.clsPlugExtraData(); //var pluginExtraData = new PlugExtraData.clsPlugExtraData(); if (PEDStorage.Count > 0) { //PED storage got something foreach (KeyValuePair <string, string> pair in PEDStorage) { Console.WriteLine("Found PED"); pluginExtraData.AddNamed(pair.Key.ToString(), pair.Value.ToString()); } } dv.set_PlugExtraData_Set(_hs, pluginExtraData); dv.set_Interface(_hs, GetName()); //Don't change this, or the device won't be associated with your plugin dv.set_InterfaceInstance(_hs, InstanceFriendlyName()); //Don't change this, or the device won't be associated with that particular instance dv.set_Device_Type_String(_hs, Name); dv.set_Can_Dim(_hs, false); //Setting the name and locations dv.set_Name(_hs, Name); dv.set_Location(_hs, Location); dv.set_Location2(_hs, Location2); //Misc options dv.set_Status_Support(_hs, true); //Set to True if the devices can be polled, False if not. (See PollDevice in hspi.vb) dv.MISC_Set(_hs, Enums.dvMISC.SHOW_VALUES); //If not set, device control options will not be displayed. //dv.MISC_Set(_hs, Enums.dvMISC.NO_LOG); //As default, we don't want to Log every device value change to the Log //Committing to the database, clear value-status-pairs and graphic-status pairs _hs.SaveEventsDevices(); _hs.DeviceVSP_ClearAll(dvRef, true); _hs.DeviceVGP_ClearAll(dvRef, true); Id = dvRef; return(dvRef); //Return the reference } catch (Exception ex) { throw new Exception("Error creating basic device: " + ex.Message, ex); } }
public string addSubrule(string data) { //Make a new rule, but make it in service to an existing rule: var dv = Instance.host.NewDeviceRef("R"); Scheduler.Classes.DeviceClass newDevice = (Scheduler.Classes.DeviceClass)Instance.host.GetDeviceByRef(dv); newDevice.set_InterfaceInstance(Instance.host, Instance.name); newDevice.set_Name(Instance.host, "Type Meter Rate" + dv); // newDevice.set_Location2(Instance.host, "ScratchpadSubRule"); newDevice.set_Location(Instance.host, "Utilities"); newDevice.set_Location2(Instance.host, "Rates"); //newDevice.set_Interface(Instance.host, "Modbus Configuration");//Put here the registered name of the page for what we want in the Modbus tab!!! So easy! newDevice.set_Interface(Instance.host, Util.IFACE_NAME); //Needed to link device to plugin, so the tab calls back to the correct hardcoded homeseer function //newDevice.set_InterfaceInstance()'' SET INTERFACE INSTANCE newDevice.set_Relationship(Instance.host, Enums.eRelationship.Not_Set); newDevice.MISC_Set(Instance.host, Enums.dvMISC.NO_LOG); newDevice.MISC_Set(Instance.host, Enums.dvMISC.SHOW_VALUES); // newDevice.MISC_Set(Instance.host, Enums.dvMISC.HIDDEN); HomeSeerAPI.PlugExtraData.clsPlugExtraData EDO = new PlugExtraData.clsPlugExtraData(); // EDO = newDevice.get_PlugExtraData_Get(Instance.host); string ruleString = makeNewRules(); string userNote = newDevice.get_UserNote(Instance.host); userNote = userNote.Split("PLUGIN EXTRA DATA:".ToCharArray())[0]; userNote += "PLUGIN EXTRA DATA:" + ruleString.ToString(); newDevice.set_UserNote(Instance.host, userNote); EDO.AddNamed("SSIDKey", ruleString); newDevice.set_PlugExtraData_Set(Instance.host, EDO); // newDevice.set_Device_Type_String(Instance.host, makeNewModbusGateway()); var DevINFO = new DeviceTypeInfo_m.DeviceTypeInfo(); DevINFO.Device_API = DeviceTypeInfo_m.DeviceTypeInfo.eDeviceAPI.Plug_In; newDevice.set_DeviceType_Set(Instance.host, DevINFO); Instance.Devices.Add(new SiidDevice(Instance, newDevice)); MakeStewardVSP(dv); StringBuilder stb = new StringBuilder(); var page = this; string GatewayID = data.Split("_".ToCharArray())[1]; SiidDevice GateWay = SiidDevice.GetFromListByID(Instance.Devices, Convert.ToInt32(GatewayID)); Scheduler.Classes.DeviceClass Gateway = GateWay.Device; //Should keep in gateway a list of devices Gateway.AssociatedDevice_Add(Instance.host, dv); //This is totally working actually return("refresh"); stb.Append("<meta http-equiv=\"refresh\" content = \"0; URL='/deviceutility?ref=" + dv + "&edit=1'\" />"); // stb.Append("<a id = 'LALA' href='/deviceutility?ref=" + dv + "&edit=1'/><script>LALA.click()</script> "); page.AddBody(stb.ToString()); return(page.BuildPage()); }
public override string InitIO(string port) { Program.WriteLog(LogType.Verbose, "InitIO"); dimmersByRef = new Dictionary <int, DimmerDevice>(); haveDoneInitialUpdate = false; Dictionary <byte, DimmerDevice> dict = new Dictionary <byte, DimmerDevice>(); clsDeviceEnumeration enumerator = (clsDeviceEnumeration)hs.GetDeviceEnumerator(); do { DeviceClass device = enumerator.GetNext(); if (device != null) { if (device.get_Interface(hs) != "Z-Wave") { continue; } // It's a Z-Wave device PlugExtraData.clsPlugExtraData extraData = device.get_PlugExtraData_Get(hs); string[] addressParts = device.get_Address(hs).Split('-'); byte nodeId = byte.Parse(addressParts[1]); if (dict.ContainsKey(nodeId)) { continue; } if (DeviceIsDimmer(extraData)) { DimmerDevice dimmerDevice = new DimmerDevice { HomeID = addressParts[0], NodeID = nodeId, SwitchMultiLevelDeviceRef = device.get_Ref(hs) }; dict[nodeId] = dimmerDevice; dimmersByRef[dimmerDevice.SwitchMultiLevelDeviceRef] = dimmerDevice; } } } while (!enumerator.Finished); callbacks.RegisterEventCB(HomeSeerAPI.Enums.HSEvent.VALUE_SET, Name, InstanceFriendlyName()); callbacks.RegisterEventCB(HomeSeerAPI.Enums.HSEvent.VALUE_CHANGE, Name, InstanceFriendlyName()); hs.RegisterPage("IdleLightColorsSettings", Name, InstanceFriendlyName()); WebPageDesc configLink = new WebPageDesc { plugInName = Name, link = "IdleLightColorsSettings", linktext = "Settings", order = 1, page_title = "HS-WD200+ Idle Light Colors Settings", plugInInstance = InstanceFriendlyName() }; callbacks.RegisterConfigLink(configLink); callbacks.RegisterLink(configLink); offColor = (WD200NormalModeColor)int.Parse(hs.GetINISetting("Colors", "idle_color", ((int)WD200NormalModeColor.Blue).ToString(), IniFilename)); onColor = (WD200NormalModeColor)int.Parse(hs.GetINISetting("Colors", "active_color", ((int)WD200NormalModeColor.White).ToString(), IniFilename)); Program.WriteLog(LogType.Info, string.Format( "Init complete. Active color: {0}. Idle color: {1}. Found {2} dimmers with node IDs: {3}", onColor, offColor, dimmersByRef.Keys.Count, string.Join(", ", dimmersByRef.Values.Select(dimmerDevice => dimmerDevice.NodeID)) )); return(""); }