static void Main(string[] args) { var smartHub = new SmartHub { Environment = EnvironmentConfig.Load(), LightAdapters = new List <ILightAdapter> { new HueLightAdapter() }, SensorAdapters = new List <ISensorAdapter> { new HueSensorAdapater() } }; HomeLogger.WriteLine("Loading rules"); string path = "rules.json"; if (!File.Exists(path)) { path = "../../../../config/rules.json"; if (!File.Exists(path)) { throw new Exception("Could not find rules!"); } } var rules = JsonConvert.DeserializeObject <Rule[]>(File.ReadAllText(path)); HomeLogger.WriteLine("Initializing smarthub"); smartHub.Initialize(); HomeLogger.WriteLine("Starting rule engine loop"); var ruleProcessor = new RuleProcessor(rules, smartHub); ruleProcessor.Run(); Console.ReadLine(); ruleProcessor.Stop(); }
private void UpdateLoop() { Dictionary <string, ISmartSensor> prevSensorState = GetSensorState(); IList <ISmartLight> prevLightState = _smartHub.PollLights(); IList <ISmartLight> currLightState = prevLightState; HomeLogger.WriteLine("Pulled initial sensor and light states"); while (_active) { Dictionary <string, ISmartSensor> currSensorState = GetSensorState(); if (_lightRefreshCounter > 5) { currLightState = _smartHub.PollLights(); bool externalChangeDetected = false; for (var i = 0; i < currLightState.Count; i++) { ISmartLight currLight = currLightState[i]; ISmartLight prevLight = prevLightState[i]; // Light has changed outside of orchestration if (currLight.State.On != prevLight.State.On || Math.Abs(currLight.State.Brightness - prevLight.State.Brightness) > 10) { _externalInputMap[_lightRoomMap[currLight.Id]] = DateTime.Now; externalChangeDetected = true; } } if (externalChangeDetected) { HomeLogger.WriteLine("External change detected", ConsoleColor.Yellow); } _lightRefreshCounter = 0; } int currentTime = DateTime.Now.Hour; foreach (Rule rule in _rules) { int satisfiedRules = 0; // Iterate over each condition and check if they are satisifed foreach (RuleCondition condition in rule.Conditions) { switch (condition.Type) { case RuleConditionType.TimeRange: if (condition.TimeRange.Start <= currentTime && condition.TimeRange.End >= currentTime) { satisfiedRules++; } break; case RuleConditionType.MotionDetection: if (!prevSensorState[condition.RoomId].DetectMotion && currSensorState[condition.RoomId].DetectMotion) { satisfiedRules++; } break; case RuleConditionType.NoMotionDetection: TimeSpan timeSinceActivity = DateTime.Now - _activityMap[condition.RoomId]; if (timeSinceActivity.TotalSeconds > condition.DurationInSeconds) { satisfiedRules++; } break; case RuleConditionType.LightState: foreach (ISmartLight light in currLightState) { if (_lightRoomMap[light.Id] == condition.RoomId && light.State.On == condition.LightState.On) { satisfiedRules++; break; } } break; case RuleConditionType.NoExternalInput: break; } } // All rules were satisfied, run the actions if (satisfiedRules == rule.Conditions.Length) { foreach (RuleAction ruleAction in rule.Actions) { HomeLogger.WriteLine("Executing rule " + rule.Name, ruleAction.LightState.On ? ConsoleColor.Green : ConsoleColor.Red); if (ruleAction.RoomIds != null) { foreach (string roomId in ruleAction.RoomIds) { _smartHub.UpdateLightsInRooms(new[] { roomId }, ruleAction.LightState); } } } // Force an update to light states currLightState = _smartHub.PollLights(); } } _lightRefreshCounter++; prevSensorState = currSensorState; prevLightState = currLightState; Thread.Sleep(500); } }