Esempio n. 1
0
        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);
        }