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);
        }
Esempio n. 2
0
        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();
            }
        }
Esempio n. 3
0
        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();
        }