/// <summary> /// Delegate to be called whenever the Z-Wave controller's status changes - prepares the library. /// </summary> /// <param name="sender">The Z-Wave controller which sent the change.</param> /// <param name="args"></param> protected void OnControllerStatusChanged(object sender, ControllerStatusEventArgs args) { switch (args.Status) { case ControllerStatus.Connected: Controller.Initialize(); break; case ControllerStatus.Disconnected: if (_stoppingSemaphor != null) { _stoppingSemaphor.Release(); _stoppingSemaphor = null; } OnDisconnected?.Invoke(this); break; case ControllerStatus.Error: OnError?.Invoke(this); break; case ControllerStatus.Ready: Controller.Discovery(); break; case ControllerStatus.Initializing: default: break; } }
private static void Discovery(ZWaveController controller) { ToggleDebug(true); controller.Discovery(); ToggleDebug(false); }
public object InterfaceControl(MigInterfaceCommand request) { ResponseText returnValue = new ResponseText("OK"); bool raiseEvent = false; string eventParameter = ModuleEvents.Status_Level; string eventValue = ""; string nodeId = request.Address; Commands command; Enum.TryParse <Commands>(request.Command.Replace(".", "_"), out command); ZWaveNode node = null; byte nodeNumber = 0; if (byte.TryParse(nodeId, out nodeNumber)) { if (nodeNumber > 0) { node = controller.GetNode(nodeNumber); } switch (command) { case Commands.Controller_Discovery: controller.Discovery(); break; case Commands.Controller_SoftReset: controller.SoftReset(); break; case Commands.Controller_HardReset: controller.HardReset(); controller.Discovery(); break; case Commands.Controller_HealNetwork: controller.HealNetwork(); break; case Commands.Controller_NodeNeighborUpdate: controller.RequestNeighborsUpdateOptions(nodeNumber); controller.RequestNeighborsUpdate(nodeNumber); controller.GetNeighborsRoutingInfo(nodeNumber); returnValue = GetResponseValue(nodeNumber, EventPath_RoutingInfo); break; case Commands.Controller_NodeRoutingInfo: controller.GetNeighborsRoutingInfo(nodeNumber); returnValue = GetResponseValue(nodeNumber, EventPath_RoutingInfo); break; case Commands.Controller_NodeAdd: lastAddedNode = 0; controller.BeginNodeAdd(); for (int i = 0; i < 20; i++) { if (lastAddedNode > 0) { break; } Thread.Sleep(500); } controller.StopNodeAdd(); returnValue = new ResponseText(lastAddedNode.ToString()); break; case Commands.Controller_NodeRemove: lastRemovedNode = 0; controller.BeginNodeRemove(); for (int i = 0; i < 20; i++) { if (lastRemovedNode > 0) { break; } Thread.Sleep(500); } controller.StopNodeRemove(); returnValue = new ResponseText(lastRemovedNode.ToString()); break; case Commands.Basic_Set: { raiseEvent = true; var level = int.Parse(request.GetOption(0)); eventValue = level.ToString(CultureInfo.InvariantCulture); Basic.Set(node, (byte)level); } break; case Commands.Basic_Get: Basic.Get(node); returnValue = GetResponseValue(nodeNumber, EventPath_Basic); break; case Commands.SwitchBinary_Set: { raiseEvent = true; var level = int.Parse(request.GetOption(0)); eventValue = level.ToString(CultureInfo.InvariantCulture); SwitchBinary.Set(node, (byte)level); } break; case Commands.SwitchBinary_Get: SwitchBinary.Get(node); returnValue = GetResponseValue(nodeNumber, EventPath_SwitchBinary); break; case Commands.SwitchMultilevel_Set: { raiseEvent = true; var level = int.Parse(request.GetOption(0)); eventValue = level.ToString(CultureInfo.InvariantCulture); SwitchMultilevel.Set(node, (byte)level); } break; case Commands.SwitchMultilevel_Get: SwitchMultilevel.Get(node); returnValue = GetResponseValue(nodeNumber, EventPath_SwitchMultilevel); break; case Commands.MultiInstance_GetCount: { string commandType = request.GetOption(0).Replace(".", ""); switch (commandType) { case "SwitchBinary": MultiInstance.GetCount(node, (byte)ZWaveLib.CommandClass.SwitchBinary); break; case "SwitchMultiLevel": MultiInstance.GetCount(node, (byte)ZWaveLib.CommandClass.SwitchMultilevel); break; case "SensorBinary": MultiInstance.GetCount(node, (byte)ZWaveLib.CommandClass.SensorBinary); break; case "SensorMultiLevel": MultiInstance.GetCount(node, (byte)ZWaveLib.CommandClass.SensorMultilevel); break; } returnValue = GetResponseValue(nodeNumber, EventPath_MultiInstance + "." + commandType + ".Count"); } break; case Commands.MultiInstance_Get: { byte instance = (byte)int.Parse(request.GetOption(1)); string commandType = request.GetOption(0).Replace(".", ""); switch (commandType) { case "SwitchBinary": MultiInstance.SwitchBinaryGet(node, instance); break; case "SwitchMultiLevel": MultiInstance.SwitchMultiLevelGet(node, instance); break; case "SensorBinary": MultiInstance.SensorBinaryGet(node, instance); break; case "SensorMultiLevel": MultiInstance.SensorMultiLevelGet(node, instance); break; } returnValue = GetResponseValue(nodeNumber, EventPath_MultiInstance + "." + commandType + "." + instance); } break; case Commands.MultiInstance_Set: { byte instance = (byte)int.Parse(request.GetOption(1)); int value = int.Parse(request.GetOption(2)); // //raisepropchanged = true; //parampath += "." + instance; // Status.Level.<instance> // switch (request.GetOption(0)) { case "Switch.Binary": MultiInstance.SwitchBinarySet(node, instance, value); //raiseparam = (double.Parse(request.GetOption(2)) / 255).ToString(); break; case "Switch.MultiLevel": MultiInstance.SwitchMultiLevelSet(node, instance, value); //raiseparam = (double.Parse(request.GetOption(2)) / 100).ToString(); // TODO: should it be 99 ? break; } } break; case Commands.SensorBinary_Get: SensorBinary.Get(node); break; case Commands.SensorMultiLevel_Get: SensorMultilevel.Get(node); break; case Commands.Meter_Get: // see ZWaveLib Sensor.cs for EnergyMeterScale options int scaleType = 0; int.TryParse(request.GetOption(0), out scaleType); Meter.Get(node, (byte)(scaleType << 0x03)); break; case Commands.Meter_SupportedGet: Meter.GetSupported(node); break; case Commands.Meter_Reset: Meter.Reset(node); break; case Commands.NodeInfo_Get: controller.GetNodeInformationFrame(nodeNumber); returnValue = GetResponseValue(nodeNumber, EventPath_NodeInfo); break; case Commands.Battery_Get: Battery.Get(node); returnValue = GetResponseValue(nodeNumber, EventPath_Battery); break; case Commands.Association_Set: Association.Set(node, (byte)int.Parse(request.GetOption(0)), (byte)int.Parse(request.GetOption(1))); break; case Commands.Association_Get: byte group = (byte)int.Parse(request.GetOption(0)); Association.Get(node, group); returnValue = GetResponseValue(nodeNumber, EventPath_Associations + "." + group); break; case Commands.Association_Remove: Association.Remove(node, (byte)int.Parse(request.GetOption(0)), (byte)int.Parse(request.GetOption(1))); break; case Commands.ManufacturerSpecific_Get: ManufacturerSpecific.Get(node); returnValue = GetResponseValue(nodeNumber, EventPath_ManufacturerSpecific); break; case Commands.Config_ParameterSet: Configuration.Set(node, (byte)int.Parse(request.GetOption(0)), int.Parse(request.GetOption(1))); break; case Commands.Config_ParameterGet: byte position = (byte)int.Parse(request.GetOption(0)); Configuration.Get(node, position); returnValue = GetResponseValue(nodeNumber, EventPath_ConfigVariables + "." + position); break; case Commands.WakeUp_Get: WakeUp.Get(node); returnValue = GetResponseValue(nodeNumber, EventPath_WakeUpInterval); break; case Commands.WakeUp_Set: WakeUp.Set(node, uint.Parse(request.GetOption(0))); break; case Commands.WakeUp_SendToSleep: WakeUp.SendToSleep(node); break; case Commands.WakeUp_GetAlwaysAwake: returnValue = new ResponseText(WakeUp.GetAlwaysAwake(node) ? "1" : "0"); break; case Commands.WakeUp_SetAlwaysAwake: WakeUp.SetAlwaysAwake(node, uint.Parse(request.GetOption(0)) == 1 ? true : false); break; case Commands.Version_Get: returnValue = new ResponseText("ERROR"); CommandClass cclass; Enum.TryParse <CommandClass>(request.GetOption(0), out cclass); if (cclass != CommandClass.NotSet) { var nodeCclass = node.GetCommandClass(cclass); if (nodeCclass != null && nodeCclass.Version != 0) { returnValue = new ResponseText(nodeCclass.Version.ToString()); } else { ZWaveLib.CommandClasses.Version.Get(node, cclass); returnValue = GetResponseValue(nodeNumber, "ZWaveNode.Version." + cclass); } } break; case Commands.Version_GetAll: controller.GetNodeCcsVersion(node); break; case Commands.Control_On: raiseEvent = true; double lastLevel = GetNormalizedValue((double)GetNodeLastLevel(node)); eventValue = lastLevel > 0 ? lastLevel.ToString(CultureInfo.InvariantCulture) : "1"; if (node.SupportCommandClass(CommandClass.SwitchMultilevel)) { SwitchMultilevel.Set(node, 0xFF); } else if (node.SupportCommandClass(CommandClass.SwitchBinary)) { SwitchBinary.Set(node, 0xFF); } else { Basic.Set(node, 0xFF); } SetNodeLevel(node, 0xFF); break; case Commands.Control_Off: raiseEvent = true; eventValue = "0"; if (node.SupportCommandClass(CommandClass.SwitchMultilevel)) { SwitchMultilevel.Set(node, 0x00); } else if (node.SupportCommandClass(CommandClass.SwitchBinary)) { SwitchBinary.Set(node, 0x00); } else { Basic.Set(node, 0x00); } SetNodeLevel(node, 0x00); break; case Commands.Control_Level: { raiseEvent = true; var level = int.Parse(request.GetOption(0)); eventValue = Math.Round(level / 100D, 2).ToString(CultureInfo.InvariantCulture); // the max value should be obtained from node parameters specifications, // here we assume that the commonly used interval is [0-99] for most multilevel switches if (level >= 100) { level = 99; } if (node.SupportCommandClass(CommandClass.SwitchMultilevel)) { SwitchMultilevel.Set(node, (byte)level); } else { Basic.Set(node, (byte)level); } SetNodeLevel(node, (byte)level); } break; case Commands.Control_Toggle: raiseEvent = true; if (GetNodeLevel(node) == 0) { double lastOnLevel = GetNormalizedValue((double)GetNodeLastLevel(node)); eventValue = lastOnLevel > 0 ? lastOnLevel.ToString(CultureInfo.InvariantCulture) : "1"; if (node.SupportCommandClass(CommandClass.SwitchMultilevel)) { SwitchMultilevel.Set(node, 0xFF); } else if (node.SupportCommandClass(CommandClass.SwitchBinary)) { SwitchBinary.Set(node, 0xFF); } else { Basic.Set(node, 0xFF); } SetNodeLevel(node, 0xFF); } else { eventValue = "0"; if (node.SupportCommandClass(CommandClass.SwitchMultilevel)) { SwitchMultilevel.Set(node, 0x00); } else if (node.SupportCommandClass(CommandClass.SwitchBinary)) { SwitchBinary.Set(node, 0x00); } else { Basic.Set(node, 0x00); } SetNodeLevel(node, 0x00); } break; case Commands.Thermostat_ModeGet: ThermostatMode.Get(node); break; case Commands.Thermostat_ModeSet: { ThermostatMode.Value mode = (ThermostatMode.Value)Enum.Parse(typeof(ThermostatMode.Value), request.GetOption(0)); // raiseEvent = true; eventParameter = "Thermostat.Mode"; eventValue = request.GetOption(0); // ThermostatMode.Set(node, mode); } break; case Commands.Thermostat_SetPointGet: { ThermostatSetPoint.Value mode = (ThermostatSetPoint.Value)Enum.Parse(typeof(ThermostatSetPoint.Value), request.GetOption(0)); ThermostatSetPoint.Get(node, mode); } break; case Commands.Thermostat_SetPointSet: { ThermostatSetPoint.Value mode = (ThermostatSetPoint.Value)Enum.Parse(typeof(ThermostatSetPoint.Value), request.GetOption(0)); double temperature = double.Parse(request.GetOption(1).Replace(',', '.'), CultureInfo.InvariantCulture); // raiseEvent = true; eventParameter = "Thermostat.SetPoint." + request.GetOption(0); eventValue = temperature.ToString(CultureInfo.InvariantCulture); // ThermostatSetPoint.Set(node, mode, temperature); } break; case Commands.Thermostat_FanModeGet: ThermostatFanMode.Get(node); break; case Commands.Thermostat_FanModeSet: { ThermostatFanMode.Value mode = (ThermostatFanMode.Value)Enum.Parse(typeof(ThermostatFanMode.Value), request.GetOption(0)); // raiseEvent = true; eventParameter = "Thermostat.FanMode"; eventValue = request.GetOption(0); // ThermostatFanMode.Set(node, mode); } break; case Commands.Thermostat_FanStateGet: ThermostatFanState.Get(node); break; case Commands.Thermostat_OperatingStateGet: ThermostatOperatingState.GetOperatingState(node); break; case Commands.UserCode_Set: byte userId = byte.Parse(request.GetOption(0)); byte userIdStatus = byte.Parse(request.GetOption(1)); byte[] tagCode = ZWaveLib.Utility.HexStringToByteArray(request.GetOption(2)); UserCode.Set(node, new ZWaveLib.Values.UserCodeValue(userId, userIdStatus, tagCode)); break; case Commands.DoorLock_Get: DoorLock.Get(node); returnValue = GetResponseValue(nodeNumber, ModuleEvents.Status_DoorLock); break; case Commands.DoorLock_Set: { DoorLock.Value mode = (DoorLock.Value)Enum.Parse(typeof(DoorLock.Value), request.GetOption(0)); DoorLock.Set(node, mode); } break; } } if (raiseEvent) { //ZWaveNode node = _controller.GetDevice ((byte)int.Parse (nodeid)); OnInterfacePropertyChanged(this.GetDomain(), nodeId, "ZWave Node", eventParameter, eventValue); } // return(returnValue); }