예제 #1
0
        Task <IPremiseObject> IPremiseObject.SetClassAsync(IPremiseObject classObject)
        {
            var future = new SetClassFuture(_objectId, (classObject as PremiseObject)?._objectId);

            _client.Send(future, out Task <IPremiseObject> task);
            return(task);
        }
예제 #2
0
        Task <IPremiseObject> IPremiseObject.CreateObjectAsync(IPremiseObject type, string name)
        {
            var future = new CreateObjectFuture(_objectId, (type as PremiseObject)?._objectId, name);

            _client.Send(future, out Task <IPremiseObject> task);
            return(task);
        }
예제 #3
0
        Task <string> IPremiseObject.GetPropertyAsTextAsync(IPremiseObject property)
        {
            var future = new GetPropertyAsTextFuture(_objectId, (property as PremiseObject)?._objectId);

            _client.Send(future, out Task <string> task);
            return(task);
        }
예제 #4
0
        Task <bool> IPremiseObject.IsOfTypeAsync(IPremiseObject typeId)
        {
            var future = new IsOfTypeFuture(_objectId, (typeId as PremiseObject)?._objectId);

            _client.Send(future, out Task <bool> task);
            return(task);
        }
예제 #5
0
        public void ProcessControllerDirective()
        {
            IPremiseObject switcher = GetSwitcherZone();

            if (switcher == null || !switcher.IsValidObject())
            {
                string name = Endpoint.GetPathAsync().GetAwaiter().GetResult();
                ReportError(AlexaErrorTypes.NO_SUCH_ENDPOINT, $"No switcher child object in MediaZone at {name}.");
                return;
            }

            Dictionary <string, IPremiseObject> inputs = GetAllInputs(switcher);

            if (inputs.ContainsKey(Request.directive.payload.input.ToUpper()))
            {
                // switch inputs
                IPremiseObject newInput   = inputs[Request.directive.payload.input];
                string         newInputId = newInput.GetObjectIDAsync().GetAwaiter().GetResult();
                switcher.SetValueAsync("CurrentSource", newInputId).GetAwaiter().GetResult();
                Response.Event.header.name = "Response";
                Response.context.properties.AddRange(PropertyHelpers.FindRelatedProperties(Endpoint, ""));
            }
            else
            {
                ReportError(AlexaErrorTypes.INVALID_VALUE, $"Input {Request.directive.payload.input} not found!");
            }
        }
예제 #6
0
        public List <AlexaProperty> FindRelatedProperties(IPremiseObject endpoint, string currentController)
        {
            List <AlexaProperty> relatedProperties = new List <AlexaProperty>();

            DiscoveryEndpoint discoveryEndpoint = PremiseServer.GetDiscoveryEndpointAsync(endpoint).GetAwaiter().GetResult();

            if (discoveryEndpoint == null)
            {
                return(relatedProperties);
            }

            foreach (Capability capability in discoveryEndpoint.capabilities)
            {
                if (capability.@interface == currentController)
                {
                    continue;
                }

                if (PremiseServer.Controllers.ContainsKey(capability.@interface))
                {
                    IAlexaController controller = PremiseServer.Controllers[capability.@interface];
                    controller.SetEndpoint(endpoint);
                    relatedProperties.AddRange(controller.GetPropertyStates());
                }
            }

            return(relatedProperties);
        }
예제 #7
0
        public static void ShutdownMonitor()
        {
            WriteToWindowsApplicationEventLog(EventLogEntryType.Information, "Shutdown monitor started.", 3);
            while (!BackgroundTaskManager.Shutdown.IsCancellationRequested)
            {
                Thread.Sleep(2000);
            }
            WriteToWindowsApplicationEventLog(EventLogEntryType.Information, "Shutdown requested by IIS application pool.", 6);

            UnsubscribeAllAsync().GetAwaiter().GetResult();
            _asyncEventSubscription?.UnsubscribeAsync().GetAwaiter().GetResult();
            _asyncEventSubscription = null;

            WriteToWindowsApplicationEventLog(EventLogEntryType.Information, "Removed premise async subscriptions.", 7);

            using (endpointsLock.Lock())
            {
                endpoints?.Clear();
            }

            WriteToWindowsApplicationEventLog(EventLogEntryType.Information, "Disconnect from premise.", 8);

            _sysClient.Disconnect();

            using (HomeObjectLock.Lock())
            {
                _homeObject = null;
            }

            WriteToWindowsApplicationEventLog(EventLogEntryType.Information, "Shutdown complete.", 9);
            BackgroundTaskManager.Shutdown.ThrowIfCancellationRequested();
        }
예제 #8
0
        private string GetInputName(IPremiseObject input)
        {
            string inputName = input.GetValueAsync <string>("AlexaInputName").GetAwaiter().GetResult();

            if (string.IsNullOrEmpty(inputName))
            {
                // if the AlexaInputName isn't set then use the object name.
                inputName = input.GetNameAsync().GetAwaiter().GetResult();
            }
            return(inputName.ToUpper());
        }
예제 #9
0
        private IPremiseObject GetSwitcherZone()
        {
            IPremiseObject switcher = null;

            foreach (IPremiseObject child in Endpoint.GetChildrenAsync().GetAwaiter().GetResult())
            {
                // there should be an object of type matrix switcher zone as a child
                if (child.IsOfTypeAsync(PremiseServer.AlexaMatrixSwitcherZone).GetAwaiter().GetResult())
                {
                    switcher = child;
                    break;
                }
            }
            return(switcher);
        }
예제 #10
0
        private static async Task SubscribeAllAsync()
        {
            using (subscriptionsLock.Lock())
            {
                if (endpoints.Count == 0)
                {
                    await GetEndpointsAsync().ConfigureAwait(false);
                }
                if (subscriptions.Count != 0)
                {
                    await UnsubscribeAllAsync().ConfigureAwait(false);
                }
                Action <dynamic> callback = AlexaPropertyChanged;
                using (endpointsLock.Lock())
                {
                    foreach (DiscoveryEndpoint discoveryEndpoint in endpoints)
                    {
                        Guid           premiseId = new Guid(discoveryEndpoint.endpointId);
                        IPremiseObject endpoint  = await HomeObject.GetObjectAsync(premiseId.ToString("B")).ConfigureAwait(false);

                        if (!endpoint.IsValidObject())
                        {
                            await NotifyErrorAsync(EventLogEntryType.Warning, $"Cannot find object {discoveryEndpoint.friendlyName} ({premiseId.ToString()})to subscribe on premise server.", 250).ConfigureAwait(false);

                            continue;
                        }

                        // use reflection to instantiate all device type controllers
                        var interfaceType = typeof(IAlexaDeviceType);
                        var all           = AppDomain.CurrentDomain.GetAssemblies()
                                            .SelectMany(x => x.GetTypes())
                                            .Where(x => interfaceType.IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract)
                                            .Select(Activator.CreateInstance);

                        foreach (IAlexaDeviceType deviceType in all)
                        {
                            Dictionary <string, IPremiseSubscription> subs =
                                deviceType.SubscribeToSupportedProperties(endpoint, discoveryEndpoint, callback);
                            foreach (string key in subs.Keys)
                            {
                                subscriptions.Add(key, subs[key]);
                            }
                        }
                    }
                }
            }
        }
        public List <AlexaProperty> GetPropertyStates(IPremiseObject premiseObject)
        {
            Endpoint = premiseObject;
            List <AlexaProperty> properties = new List <AlexaProperty>();

            //double volume = this.endpoint.GetValue<double>(_premiseProperties[0]).GetAwaiter().GetResult();
            //AlexaProperty volumeProperty = new AlexaProperty
            //{
            //    @namespace = _namespace,
            //    name = _alexaProperties[0],
            //    value = (int)((volume * 100)).LimitToRange(0, 100),
            //    timeOfSample = UtcTimeStamp()
            //};
            //properties.Add(volumeProperty);

            return(properties);
        }
예제 #12
0
        private string GetCurrentInput()
        {
            IPremiseObject switcher = GetSwitcherZone();

            if (!switcher.IsValidObject())
            {
                return("");
            }

            IPremiseObject currentInput = switcher.GetRefValueAsync("CurrentSource").GetAwaiter().GetResult();

            if (!currentInput.IsValidObject())
            {
                return("");
            }
            return(GetInputName(currentInput));
        }
예제 #13
0
        public static async Task <DiscoveryEndpoint> GetDiscoveryEndpointAsync(IPremiseObject endpoint)
        {
            DiscoveryEndpoint discoveryEndpoint;

            try
            {
                string json = await endpoint.GetValueAsync("discoveryJson").ConfigureAwait(false);

                discoveryEndpoint = JsonConvert.DeserializeObject <DiscoveryEndpoint>(json, new JsonSerializerSettings
                {
                    NullValueHandling = NullValueHandling.Ignore
                });
            }
            catch
            {
                discoveryEndpoint = null;
            }

            return(discoveryEndpoint);
        }
예제 #14
0
        private Dictionary <string, IPremiseObject> GetAllInputs(IPremiseObject switcher)
        {
            Dictionary <string, IPremiseObject> inputs = new Dictionary <string, IPremiseObject>();

            if (switcher == null)
            {
                return(inputs);
            }

            // The bound object of the switcher should be the output zone object at the device level
            IPremiseObject boundObject = switcher.GetRefValueAsync("BoundObject").GetAwaiter().GetResult();

            if (!boundObject.IsValidObject())
            {
                string path = switcher.GetPathAsync().GetAwaiter().GetResult();
                ReportError(AlexaErrorTypes.ENDPOINT_UNREACHABLE, $"No device bound to switcher at {path}.");
                return(inputs);
            }

            // the parent should be the actual switcher
            IPremiseObject actualSwitcher = boundObject.GetParentAsync().GetAwaiter().GetResult();

            if (!actualSwitcher.IsValidObject())
            {
                string path = boundObject.GetPathAsync().GetAwaiter().GetResult();
                ReportError(AlexaErrorTypes.INTERNAL_ERROR, $"Unexpected parent at {path}.");
                return(inputs);
            }

            // walk through the children looking for inputs
            foreach (IPremiseObject child in actualSwitcher.GetChildrenAsync().GetAwaiter().GetResult())
            {
                if (child.IsOfTypeAsync(PremiseServer.AlexaAudioVideoInput).GetAwaiter().GetResult())
                {
                    string inputName = GetInputName(child).ToUpper();
                    inputs.Add(inputName, child);
                }
            }
            return(inputs);
        }
예제 #15
0
 public AlexaEndpointHealthController(IPremiseObject endpoint)
     : base(endpoint)
 {
 }
 public AlexaTemperatureSensor(IPremiseObject endpoint)
     : base(endpoint)
 {
     PropertyHelpers = new AlexaHVAC();
 }
예제 #17
0
 public AlexaSpeaker(IPremiseObject endpoint)
     : base(endpoint)
 {
     PropertyHelpers = new AlexaAV();
 }
 public AlexaSetPowerStateController(IPremiseObject endpoint)
     : base(endpoint)
 {
     PropertyHelpers = new AlexaPower();
 }
예제 #19
0
 public AlexaSetSceneController(IPremiseObject endpoint)
     : base(endpoint)
 {
     PropertyHelpers = new AlexaScene();
 }
예제 #20
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);
        }
예제 #21
0
        public Dictionary <string, IPremiseSubscription> SubscribeToSupportedProperties(IPremiseObject endpoint, DiscoveryEndpoint discoveryEndpoint, Action <dynamic> callback)
        {
            Dictionary <string, IPremiseSubscription> subscriptions = new Dictionary <string, IPremiseSubscription>();

            foreach (Capability capability in discoveryEndpoint.capabilities)
            {
                IPremiseSubscription subscription = null;

                if (capability.HasProperties() == false)
                {
                    continue;
                }

                if (capability.properties.proactivelyReported)
                {
                    switch (capability.@interface)
                    {
                    case "Alexa.EndpointHealth":
                        subscription = endpoint.SubscribeAsync("IsReachable", GetType().AssemblyQualifiedName, callback).GetAwaiter().GetResult();
                        break;
                    }
                }
                if (subscription != null)
                {
                    subscriptions.Add(discoveryEndpoint.endpointId + "." + capability.@interface, subscription);
                }
            }
            return(subscriptions);
        }
 public void SetEndpoint(IPremiseObject premiseObject)
 {
     Endpoint = premiseObject;
 }
예제 #23
0
        public Dictionary <string, IPremiseSubscription> SubscribeToSupportedProperties(IPremiseObject endpoint, DiscoveryEndpoint discoveryEndpoint, Action <dynamic> callback)
        {
            Dictionary <string, IPremiseSubscription> subscriptions = new Dictionary <string, IPremiseSubscription>();

            foreach (Capability capability in discoveryEndpoint.capabilities)
            {
                IPremiseSubscription subscription = null;

                if (!capability.HasProperties()) // scenes are a special cased
                {
                    switch (capability.@interface)
                    {
                    case "Alexa.SceneController":
                        subscription = endpoint.SubscribeAsync("PowerState", GetType().AssemblyQualifiedName, callback).GetAwaiter().GetResult();
                        break;
                    }
                }
                if (subscription != null)
                {
                    subscriptions.Add(discoveryEndpoint.endpointId + "." + capability.@interface, subscription);
                }
            }
            return(subscriptions);
        }
예제 #24
0
 public AlexaColorTemperatureController(IPremiseObject endpoint)
     : base(endpoint)
 {
     PropertyHelpers = new AlexaLighting();
 }
예제 #25
0
        private static bool CheckStatus()
        {
            try
            {
                if (BackgroundTaskManager.Shutdown.IsCancellationRequested)
                {
                    return(false);
                }
                if (IsClientConnected())
                {
                    return(true);
                }

                if (_homeObject == null)
                {
                    using (HomeObjectLock.Lock())
                    {
                        try
                        {
                            _homeObject = _sysClient.ConnectAsync(PremiseServerAddress)?.GetAwaiter().GetResult();
                        }
                        catch (Exception ex)
                        {
                            Debug.WriteLine(ex.Message);
                            _homeObject = null;
                        }
                    }

                    if (_homeObject == null)
                    {
                        Debug.WriteLine("Cannot connect to Premise server!");
                        return(false);
                    }
                }
                else
                {
                    _sysClient.Disconnect();

                    using (homeObjectSubscriptionLock.Lock())
                    {
                        _asyncEventSubscription = null;
                    }
                    using (subscriptionsLock.Lock())
                    {
                        subscriptions.Clear();
                        _sysClient.Subscriptions.Clear();
                    }
                    using (endpointsLock.Lock())
                    {
                        endpoints.Clear();
                    }
                    using (HomeObjectLock.Lock())
                    {
                        _homeObject = null;
                        try
                        {
                            _homeObject = _sysClient.ConnectAsync(PremiseServerAddress).GetAwaiter().GetResult();
                        }
                        catch
                        {
                            _homeObject = null;
                            return(false);
                        }
                    }
                }
                using (homeObjectSubscriptionLock.Lock())
                {
                    enableAsyncEvents = HomeObject.GetValueAsync <bool>("SendAsyncEventsToAlexa").GetAwaiter().GetResult();
                }
                if (IsAsyncEventsEnabled)
                {
                    Task.Run(SubscribeAllAsync);
                }
                SubScribeToHomeObjectEvents();
                return(true);
            }
            catch (Exception ex)
            {
                _homeObject = null;
                subscriptions.Clear();
                endpoints.Clear();
                Debug.WriteLine(ex.Message);
                return(false);
            }
        }
예제 #26
0
        public static void AlexaPropertyChanged(dynamic @params)
        {
            Subscription sub = (Subscription)@params;

            using (deDupeLock.Lock())
            {
                // Premise can send multiple notifications for a single object, one for each
                // subscribed property that changes. The state report function here will capture
                // states of all properties, so the DeDupeDictionary prevents multiple state reports
                // from being sent for essentially the same event.
                if (DeDupeDictionary.ContainsKey(sub.sysObjectId))
                {
                    return;
                }

                DeDupeDictionary.Add(sub.sysObjectId, sub);
            }

            Task.Run(() =>
            {
                // get the endpoint and endpoint capabilities
                Guid premiseId          = new Guid(sub.sysObjectId);
                IPremiseObject endpoint = HomeObject.GetObjectAsync(premiseId.ToString("B")).GetAwaiter().GetResult();
                if (!endpoint.IsValidObject())
                {
                    return;
                }

                DiscoveryEndpoint discoveryEndpoint = GetDiscoveryEndpointAsync(endpoint).GetAwaiter().GetResult();
                if (discoveryEndpoint == null)
                {
                    return;
                }

                // get the authorization code for the notification
                string authCode;
                using (asyncObjectsLock.Lock())
                {
                    authCode = (string)HomeObject.GetValueAsync("AlexaAsyncAuthorizationCode").GetAwaiter().GetResult();
                }

                // build the change report
                AlexaChangeReport changeReport                = new AlexaChangeReport();
                [email protected]          = Guid.NewGuid().ToString("D");
                [email protected].@namespace         = "Alexa";
                [email protected]     = "3";
                [email protected]       = "BearerToken";
                [email protected]      = authCode;
                [email protected]       = premiseId.ToString("D").ToUpper();
                [email protected]           = discoveryEndpoint.cookie;
                [email protected] = "PHYSICAL_INTERACTION";

                // get the device type and controller (e.g. AlexaAV, AlexaHVAC)
                IAlexaDeviceType deviceType = null;
                IAlexaController controller = null;
                List <AlexaProperty> relatedPropertyStates = null;

                bool hasScene = false;

                foreach (IAlexaController controllerToTest in Controllers.Values)
                {
                    if (!controllerToTest.HasPremiseProperty(sub.propertyName))
                    {
                        continue;
                    }

                    controller = controllerToTest;
                    Type type  = Type.GetType(controller.GetAssemblyTypeName());
                    if (type == null)
                    {
                        continue;
                    }

                    // found a controller, get an instance of the assembly
                    deviceType = (IAlexaDeviceType)Activator.CreateInstance(type);

                    // Determine if this deviceType supports the desired capability
                    // note: This handles situation where the same property name is used by different
                    // controllers. e.g. "brightness" is used in both ColorController and BrightnessController
                    relatedPropertyStates = deviceType.FindRelatedProperties(endpoint, "");
                    foreach (AlexaProperty property in relatedPropertyStates)
                    {
                        // if so, this is the correct type
                        if (property.@namespace == controller.GetNameSpace())
                        {
                            break;
                        }
                    }
                }

                // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                if ((deviceType == null) || (controller == null || relatedPropertyStates == null))
                {
                    return;
                }

                foreach (AlexaProperty prop in relatedPropertyStates)
                {
                    if (prop.@namespace == "Alexa.SceneController")
                    {
                        hasScene = true;
                        continue;
                    }

                    if (([email protected] == 0) && (prop.name == controller.MapPremisePropertyToAlexaProperty(sub.propertyName)))
                    {
                        [email protected](prop);
                    }
                    else
                    {
                        string propKey = prop.@namespace + "." + prop.name;
                        changeReport.context.propertiesInternal.Add(propKey, prop);
                    }
                }

                [email protected] = "ChangeReport";

                // scenes are special case
                if (hasScene)
                {
                    AlexaSetSceneController sceneController = new AlexaSetSceneController(endpoint);
                    changeReport = sceneController.AlterChangeReport(changeReport);
                }

                StateChangeReportWrapper item = new StateChangeReportWrapper
                {
                    ChangeReport = changeReport
                };

                stateReportQueue.Enqueue(item);

                using (deDupeLock.Lock())
                {
                    DeDupeDictionary.Remove(sub.sysObjectId);
                }
            });
        }
 public AlexaDiscoveryController(IPremiseObject endpoint)
     : base(endpoint)
 {
 }
 public AlexaThermostatController(IPremiseObject endpoint)
     : base(endpoint)
 {
     PropertyHelpers = new AlexaHVAC();
 }
 public AlexaChannelController(IPremiseObject endpoint)
     : base(endpoint)
 {
     PropertyHelpers = new AlexaAV();
 }
예제 #30
0
        public Dictionary <string, IPremiseSubscription> SubscribeToSupportedProperties(IPremiseObject endpoint, DiscoveryEndpoint discoveryEndpoint, Action <dynamic> callback)
        {
            Dictionary <string, IPremiseSubscription> subscriptions = new Dictionary <string, IPremiseSubscription>();

            foreach (Capability capability in discoveryEndpoint.capabilities)
            {
                if (capability.HasProperties() == false)
                {
                    continue;
                }

                if (!capability.properties.proactivelyReported)
                {
                    continue;
                }

                IAlexaController controller = null;

                switch (capability.@interface)
                {
                case "Alexa.ChannelController":
                    controller = new AlexaChannelController();
                    break;

                case "Alexa.InputController":
                    controller = new AlexaInputController();
                    break;

                case "Alexa.PlaybackController":
                    controller = new AlexaPlaybackController();
                    break;

                case "Alexa.Speaker":
                    controller = new AlexaSpeaker();
                    break;
                }

                if (controller == null)
                {
                    continue;
                }

                foreach (string premiseProperty in controller.GetPremiseProperties())
                {
                    string index = discoveryEndpoint.endpointId + $".{premiseProperty}." + capability.@interface;
                    if (subscriptions.ContainsKey(index))
                    {
                        continue;
                    }

                    IPremiseSubscription subscription = endpoint.SubscribeAsync(premiseProperty, GetType().AssemblyQualifiedName, callback).GetAwaiter().GetResult();
                    if (subscription != null)
                    {
                        subscriptions.Add(index, subscription);
                    }
                }
            }
            return(subscriptions);
        }