public ControlResponse Control(ControlRequest alexaRequest) { //IPremiseObject PremiseServer.HomeObject, rootObject; var response = new ControlResponse(); #region CheckRequest if ((alexaRequest == null) || (alexaRequest.header == null) || (alexaRequest.header.payloadVersion != "2")) { response.header.@namespace = Faults.Namespace; response.header.name = Faults.UnexpectedInformationReceivedError; response.payload.exception = new ExceptionResponsePayload { faultingParameter = "alexaRequest" }; return(response); } #endregion CheckRequest #region BuildResponse try { response.header.messageId = alexaRequest.header.messageId; response.header.@namespace = alexaRequest.header.@namespace; response.header.name = alexaRequest.header.name.Replace("Request", "Confirmation"); } catch (Exception) { response.header.@namespace = Faults.Namespace; response.header.name = Faults.UnexpectedInformationReceivedError; response.payload.exception = new ExceptionResponsePayload { faultingParameter = "alexaRequest.header.name" }; return(response); } #endregion BuildResponse //SYSClient client = new SYSClient(); #region ConnectToPremise if (PremiseServer.HomeObject == null) { response.header.@namespace = Faults.Namespace; response.header.name = Faults.DependentServiceUnavailableError; response.payload.exception = new ExceptionResponsePayload { dependentServiceName = "Premise Server" }; return(response); } #endregion ConnectToPremise try { if (!CheckAccessToken(alexaRequest.payload.accessToken).GetAwaiter().GetResult()) { response.header.@namespace = Faults.Namespace; response.header.name = Faults.InvalidAccessTokenError; response.payload.exception = new ExceptionResponsePayload(); return(response); } InformLastContact("ControlRequest:" + alexaRequest.payload.appliance.additionalApplianceDetails.path).GetAwaiter().GetResult(); // check request types ControlRequestType requestType = ControlRequestType.Unknown; DeviceType deviceType = DeviceType.Unknown; string command = alexaRequest.header.name.Trim().ToUpper(); switch (command) { case "TURNOFFREQUEST": requestType = ControlRequestType.TurnOffRequest; deviceType = DeviceType.OnOff; break; case "TURNONREQUEST": requestType = ControlRequestType.TurnOnRequest; deviceType = DeviceType.OnOff; break; case "SETTARGETTEMPERATUREREQUEST": requestType = ControlRequestType.SetTargetTemperature; deviceType = DeviceType.Thermostat; break; case "INCREMENTTARGETTEMPERATUREREQUEST": requestType = ControlRequestType.IncrementTargetTemperature; deviceType = DeviceType.Thermostat; break; case "DECREMENTTARGETTEMPERATUREREQUEST": requestType = ControlRequestType.DecrementTargetTemperature; deviceType = DeviceType.Thermostat; break; case "SETPERCENTAGEREQUEST": requestType = ControlRequestType.SetPercentage; deviceType = DeviceType.Dimmer; break; case "INCREMENTPERCENTAGEREQUEST": requestType = ControlRequestType.IncrementPercentage; deviceType = DeviceType.Dimmer; break; case "DECREMENTPERCENTAGEREQUEST": requestType = ControlRequestType.DecrementPercentage; deviceType = DeviceType.Dimmer; break; case "SETCOLORREQUEST": requestType = ControlRequestType.SetColorRequest; deviceType = DeviceType.ColorLight; break; case "SETCOLORTEMPERATUREREQUEST": requestType = ControlRequestType.SetColorTemperatureRequest; deviceType = DeviceType.ColorLight; break; case "INCREMENTCOLORTEMPERATUREREQUEST": requestType = ControlRequestType.IncrementColorTemperature; deviceType = DeviceType.ColorLight; break; case "DECREMENTCOLORTEMPERATUREREQUEST": requestType = ControlRequestType.DecrementColorTemperature; deviceType = DeviceType.ColorLight; break; default: response.header.@namespace = Faults.Namespace; response.header.name = Faults.UnsupportedOperationError; response.payload.exception = new ExceptionResponsePayload(); return(response); } // get the object IPremiseObject applianceToControl = null; try { Guid premiseId = new Guid(alexaRequest.payload.appliance.applianceId); applianceToControl = PremiseServer.RootObject.GetObject(premiseId.ToString("B")).GetAwaiter().GetResult(); if (applianceToControl == null) { throw new Exception(); } } catch { response.header.@namespace = Faults.Namespace; response.header.name = Faults.NoSuchTargetError; response.payload.exception = new ExceptionResponsePayload(); return(response); } if (deviceType == DeviceType.OnOff) { switch (requestType) { case ControlRequestType.TurnOnRequest: applianceToControl.SetValue("PowerState", "True").GetAwaiter().GetResult(); break; case ControlRequestType.TurnOffRequest: applianceToControl.SetValue("PowerState", "False").GetAwaiter().GetResult(); break; default: break; } } else if (deviceType == DeviceType.Dimmer) { double currentValue = 0.0; double adjustValue = 0.0; double valueToSend = 0.0; switch (requestType) { case ControlRequestType.SetPercentage: // obtain the adjustValue adjustValue = Math.Round(double.Parse(alexaRequest.payload.percentageState.value), 2).LimitToRange(0.00, 100.00); // convert from percentage and maintain fractional accuracy valueToSend = Math.Round(adjustValue / 100.00, 4); applianceToControl.SetValue("Brightness", valueToSend.ToString()).GetAwaiter().GetResult(); break; case ControlRequestType.IncrementPercentage: // obtain the adjustValue adjustValue = Math.Round(double.Parse(alexaRequest.payload.deltaPercentage.value) / 100.00, 2).LimitToRange(0.00, 100.00); currentValue = Math.Round(applianceToControl.GetValue <Double>("Brightness").GetAwaiter().GetResult(), 2); // maintain fractional accuracy valueToSend = Math.Round(currentValue + adjustValue, 2).LimitToRange(0.00, 1.00); applianceToControl.SetValue("Brightness", valueToSend.ToString()).GetAwaiter().GetResult(); break; case ControlRequestType.DecrementPercentage: // obtain the adjustValue adjustValue = Math.Round(double.Parse(alexaRequest.payload.deltaPercentage.value) / 100.00, 2).LimitToRange(0.00, 100.00); currentValue = Math.Round(applianceToControl.GetValue <Double>("Brightness").GetAwaiter().GetResult(), 2); // maintain fractional accuracy valueToSend = Math.Round(currentValue - adjustValue, 2).LimitToRange(0.00, 1.00); applianceToControl.SetValue("Brightness", valueToSend.ToString()).GetAwaiter().GetResult(); break; default: break; } } else if (deviceType == DeviceType.ColorLight) { const double adjustValue = 100.0; double currentValue = 0.0; double valueToSend = 0.0; response.payload.achievedState = new AchievedState(); switch (requestType) { case ControlRequestType.SetColorRequest: // obtain the adjustValue double hue = Math.Round(alexaRequest.payload.color.hue.LimitToRange(0, 360), 1); double saturation = Math.Round(alexaRequest.payload.color.saturation, 4); double brightness = Math.Round(alexaRequest.payload.color.brightness, 4); // set the values applianceToControl.SetValue("Hue", hue.ToString()).GetAwaiter().GetResult(); applianceToControl.SetValue("Saturation", saturation.ToString()).GetAwaiter().GetResult(); applianceToControl.SetValue("Brightness", brightness.ToString()).GetAwaiter().GetResult(); // read them back for achieved state response.payload.achievedState.color = new ApplianceColorValue { hue = Math.Round(applianceToControl.GetValue <Double>("Hue").GetAwaiter().GetResult(), 1), saturation = Math.Round(applianceToControl.GetValue <Double>("Saturation").GetAwaiter().GetResult(), 4), brightness = Math.Round(applianceToControl.GetValue <Double>("Brightness").GetAwaiter().GetResult(), 4) }; break; case ControlRequestType.SetColorTemperatureRequest: valueToSend = alexaRequest.payload.colorTemperature.value.LimitToRange(1000, 10000); // set the value applianceToControl.SetValue("Temperature", Math.Round(valueToSend, 0).ToString()).GetAwaiter().GetResult(); // read it back response.payload.achievedState.colorTemperature = new ApplianceColorTemperatureValue { value = applianceToControl.GetValue <int>("Temperature").GetAwaiter().GetResult() }; break; case ControlRequestType.IncrementColorTemperature: currentValue = applianceToControl.GetValue <int>("Temperature").GetAwaiter().GetResult(); valueToSend = Math.Round(currentValue + adjustValue, 0).LimitToRange(1000, 10000); // set the value applianceToControl.SetValue("Temperature", valueToSend.ToString()).GetAwaiter().GetResult(); // read it back response.payload.achievedState.colorTemperature = new ApplianceColorTemperatureValue { value = applianceToControl.GetValue <int>("Temperature").GetAwaiter().GetResult() }; break; case ControlRequestType.DecrementColorTemperature: currentValue = Math.Round(applianceToControl.GetValue <Double>("Temperature").GetAwaiter().GetResult(), 2); valueToSend = Math.Round(currentValue - adjustValue, 0).LimitToRange(1000, 10000); // set the value applianceToControl.SetValue("Temperature", valueToSend.ToString()).GetAwaiter().GetResult(); // read it back response.payload.achievedState.colorTemperature = new ApplianceColorTemperatureValue { value = applianceToControl.GetValue <int>("Temperature").GetAwaiter().GetResult() }; break; default: break; } } else if (deviceType == DeviceType.Thermostat) { int previousTemperatureMode; int temperatureMode; Temperature previousTargetTemperature = null; Temperature targetTemperature = null; double deltaTemperatureC = 0.0; // in C // obtain previous state (sys stores temperatures as K) previousTemperatureMode = applianceToControl.GetValue <int>("TemperatureMode").GetAwaiter().GetResult(); previousTargetTemperature = new Temperature(applianceToControl.GetValue <double>("CurrentSetPoint").GetAwaiter().GetResult()); switch (requestType) { case ControlRequestType.SetTargetTemperature: // get target temperature in C targetTemperature = new Temperature { Celcius = double.Parse(alexaRequest.payload.targetTemperature.value) }; break; case ControlRequestType.IncrementTargetTemperature: // get delta temp in C deltaTemperatureC = double.Parse(alexaRequest.payload.deltaTemperature.value); // increment the targetTemp targetTemperature = new Temperature { Celcius = previousTargetTemperature.Celcius + deltaTemperatureC }; break; case ControlRequestType.DecrementTargetTemperature: // get delta temp in C deltaTemperatureC = double.Parse(alexaRequest.payload.deltaTemperature.value); // decrement the targetTemp targetTemperature = new Temperature { Celcius = previousTargetTemperature.Celcius - deltaTemperatureC }; break; default: targetTemperature = new Temperature(0.00); previousTemperatureMode = 10; // error break; } // set new target temperature applianceToControl.SetValue("CurrentSetPoint", targetTemperature.Kelvin.ToString()).GetAwaiter().GetResult(); response.payload.targetTemperature = new ApplianceValue { value = targetTemperature.Celcius.ToString() }; // get new mode temperatureMode = applianceToControl.GetValue <int>("TemperatureMode").GetAwaiter().GetResult(); // report new mode response.payload.temperatureMode = new ApplianceValue { value = TemperatureMode.ModeToString(temperatureMode) }; // alloc a previousState object response.payload.previousState = new AppliancePreviousState { // report previous mode mode = new ApplianceValue { value = TemperatureMode.ModeToString(previousTemperatureMode) }, // report previous targetTemperature in C targetTemperature = new ApplianceValue { value = previousTargetTemperature.Celcius.ToString() } }; } else { response.header.@namespace = Faults.Namespace; response.header.name = Faults.UnsupportedOperationError; response.payload.exception = new ExceptionResponsePayload(); } } catch { response.header.@namespace = Faults.Namespace; response.header.name = Faults.DriverpublicError; response.payload.exception = new ExceptionResponsePayload(); } return(response); }
private void ProcessDeviceStateQueryRequest(QueryRequestType requestType, QueryRequest alexaRequest, QueryResponse response) { IPremiseObject applianceToQuery; InformLastContact("QueryRequest:" + alexaRequest.payload.appliance.additionalApplianceDetails.path).GetAwaiter().GetResult(); try { // Find the object Guid premiseId = new Guid(alexaRequest.payload.appliance.applianceId); applianceToQuery = PremiseServer.RootObject.GetObject(premiseId.ToString("B")).GetAwaiter().GetResult(); if (applianceToQuery == null) { throw new Exception(); } switch (requestType) { /* * case QueryRequestType.PowerState: * string state = applianceToQuery.GetValue("PowerState").GetAwaiter().GetResult(); * break; * * case QueryRequestType.DimmerLevel: * string state = applianceToQuery.GetValue("Brightness").GetAwaiter().GetResult(); * break; * * case QueryRequestType.ColorTemperature: * string state = applianceToQuery.GetValue("ColorTemperature").GetAwaiter().GetResult(); * break; * * case QueryRequestType.Color: * string state = applianceToQuery.GetValue("Hue").GetAwaiter().GetResult(); * break; */ case QueryRequestType.RetrieveCameraStreamUri: { response.payload.uri = new ApplianceValue(); string host = applianceToQuery.GetValue <string>("Host").GetAwaiter().GetResult(); string port = applianceToQuery.GetValue <string>("Port").GetAwaiter().GetResult(); string path = applianceToQuery.GetValue <string>("Path").GetAwaiter().GetResult(); response.payload.uri.value = string.Format(@"rtsp://{0}:{1}{2}", host, port, path); } break; case QueryRequestType.GetTargetTemperature: Temperature coolingSetPoint = new Temperature(applianceToQuery.GetValue <double>("CoolingSetPoint").GetAwaiter().GetResult()); Temperature heatingSetPoint = new Temperature(applianceToQuery.GetValue <double>("HeatingSetPoint").GetAwaiter().GetResult()); int temperatureMode = applianceToQuery.GetValue <int>("TemperatureMode").GetAwaiter().GetResult(); response.payload.temperatureMode = new ApplianceTemperatureMode { value = TemperatureMode.ModeToString(temperatureMode) }; response.payload.heatingTargetTemperature = new ApplianceTemperatureReading { value = double.Parse(string.Format("{0:N2}", heatingSetPoint.Celcius)), scale = "CELSIUS" }; response.payload.coolingTargetTemperature = new ApplianceTemperatureReading { value = double.Parse(string.Format("{0:N2}", coolingSetPoint.Celcius)), scale = "CELSIUS" }; //response.payload.applianceResponseTimestamp = DateTime.UtcNow.ToUniversalTime().ToString("yyyy-MM-dd'T'HH:mm:ss.ffZ");// XmlConvert.ToString(DateTime.UtcNow.ToUniversalTime(), XmlDateTimeSerializationMode.Utc); break; case QueryRequestType.GetTemperatureReading: Temperature temperature = new Temperature(applianceToQuery.GetValue <double>("Temperature").GetAwaiter().GetResult()); response.payload.temperatureReading = new ApplianceTemperatureReading { value = double.Parse(string.Format("{0:N2}", temperature.Celcius)), scale = "CELSIUS" }; //response.payload.applianceResponseTimestamp = DateTime.UtcNow.ToUniversalTime().ToString("yyyy-MM-dd'T'HH:mm:ss.ffZ"); //XmlConvert.ToString(DateTime.UtcNow.ToUniversalTime(), XmlDateTimeSerializationMode.Utc); break; default: response.header.@namespace = Faults.QueryNamespace; response.header.name = Faults.UnsupportedOperationError; response.payload.exception = new ExceptionResponsePayload { errorInfo = new ErrorInfo { description = "Unsupported Query Request Type" } }; break; } } catch { response.header.@namespace = Faults.QueryNamespace; response.header.name = Faults.NoSuchTargetError; response.payload.exception = new ExceptionResponsePayload(); } }
private void ProcessGetSpaceModeRequest(CustomRequest alexaRequest, CustomResponse response) { string toMatch = alexaRequest.payload.space.name; if (string.IsNullOrEmpty(toMatch) == false) { toMatch = toMatch.Trim(); var returnClause = new[] { "Name", "DisplayName", "Description", "CurrentScene", "Occupancy", "LastOccupied", "OccupancyCount", "OID", "OPATH", "OTYPENAME", "Type" }; dynamic whereClause = new ExpandoObject(); whereClause.TypeOf = PremiseServer.AlexaLocationClassPath; var sysRooms = PremiseServer.HomeObject.Select(returnClause, whereClause).GetAwaiter().GetResult(); foreach (var room in sysRooms) { string room_name = room.Name; string room_description = room.DisplayName; if ((!string.IsNullOrEmpty(room_description)) && (room_description.IndexOf("(Occupied)") != -1)) { room_description = room_description.Replace("(Occupied)", "").Trim(); } if ((room_name.Trim().ToLower() == toMatch) || (room_description.Trim().ToLower() == toMatch)) { InformLastContact("Get Space Status (success): " + toMatch).GetAwaiter().GetResult(); IPremiseObject this_room = PremiseServer.RootObject.GetObject(room.OID.ToString("B")).GetAwaiter().GetResult(); var devices = this_room.GetChildren().GetAwaiter().GetResult(); var count = 0; var onCount = 0; Temperature temperature = null; foreach (var device in devices) { if (device.IsOfType("{3470B9B5-E685-4EB2-ABC0-2F4CCD7F686A}").GetAwaiter().GetResult()) { count++; if (device.IsOfType("{65C7B5C2-153D-4711-BAD7-D334FDB12338}").GetAwaiter().GetResult()) { temperature = new Temperature(device.GetValue <double>("Temperature").GetAwaiter().GetResult()); } else if (device.IsOfType("{0B1DA7E1-1731-49AC-9814-47470E78EFAB}").GetAwaiter().GetResult()) { onCount += device.GetValue <bool>("PowerState").GetAwaiter().GetResult() ? 1 : 0; } } } // TODO: Aggregated properties //ICollection<IPremiseObject> i = this_room.GetAggregatedProperties().GetAwaiter().GetResult(); //response.payload.applianceRoomStatus.lastOccupied = room.lastOccupied.ToString(); response.payload.applianceRoomStatus = new RoomStatus { friendlyName = toMatch, occupied = room.Occupancy, occupancyCount = room.OccupancyCount, currentScene = room.CurrentScene, deviceCount = count.ToString() }; if (temperature != null) { response.payload.applianceRoomStatus.currentTemperature = double.Parse(string.Format("{0:N2}", temperature.Fahrenheit)).ToString(); } response.payload.applianceRoomStatus.lightsOnCount = onCount.ToString(); return; } } } if (string.IsNullOrEmpty(toMatch)) { InformLastContact("Get Space Status (space name missing in request)").GetAwaiter().GetResult(); } else { InformLastContact("Get Space Status (no such room): " + alexaRequest.payload.space.name.ToLower()).GetAwaiter().GetResult(); } response.header.@namespace = Faults.QueryNamespace; response.header.name = Faults.NoSuchTargetError; response.payload.exception = new ExceptionResponsePayload(); }