static void Main(string[] args) { BasicConfigurator.Configure(); //instanciate device manager DeviceManager dm = new DeviceManager("192.168.1.200"); //create alarm automation var windowAutomation = new WindowOpenAutomation(dm, AutomationNames.WindowOpenAutomation); //create humidty automation group. both humidity sensors and actuators must be assigned to Humidity function and the same rooms //actuator has to be in all rooms that should have humidity automation enabled var humidityAutomation = new ActuatorSensorAutomation <IHumidityControlDevice>(dm, AutomationNames.HumidityAutomation, Function.Humidity, (a, d) => d.Humidity.Value); humidityAutomation.RefencePoint = 55; //you should check humidity across all devices at home, and take mean + 10% to be safe. humidityAutomation.Hysteresis = 5; humidityAutomation.MaxOnTime = new TimeSpan(0, 1, 0); humidityAutomation.MinOnTime = new TimeSpan(0, 0, 15); humidityAutomation.MinOffTime = new TimeSpan(0, 0, 5); //create heating automation group. both heating sensors and actuators must be assigned to Heating function and the same rooms //actuator has to be in all rooms that should have heating automation enabled var heatingAutomation = new ActuatorSensorAutomation <IValveControlDevice>(dm, AutomationNames.HeatingAutomation, Function.Heating, (a, d) => Convert.ToInt32(Math.Round(d.Level.Value * 100))); heatingAutomation.RefencePoint = 20; //20% valve open heatingAutomation.Hysteresis = 2; heatingAutomation.MaxOnTime = new TimeSpan(0, 6, 0); heatingAutomation.MinOnTime = new TimeSpan(0, 0, 30); heatingAutomation.MinOffTime = new TimeSpan(0, 5, 0); //create master value sync automation, which will sync relevant schedule mastervalues across heating rooms/house. var syncHeatingMastervaluesAutomation = new SyncHeatingMasterValuesAutomation(dm, AutomationNames.SyncHeatingMastervaluesAutomation); for (;;) { //this will refresh data from HM api and run all automations dm.Work(); //log events List <DatapointEvent> eventsSinceLastRefresh = dm.Refresh(); foreach (var e in dm.Events) { LOGGER.InfoFormat("{0} EVENT {1}: ({2}) => ({3})", e.EventTimestamp.ToString("o"), e.Current.Name, e.Previous == null ? "" : e.Previous.Value, e.Current.Value ); } //wait a bit before running again new ManualResetEvent(false).WaitOne(200); } }
static void Main(string[] args) { //instanciate device manager DeviceManager dm = new DeviceManager("192.168.1.200"); //create humidty automation group. both humidity sensors and actuators must be assigned to Humidity function and the same rooms //actuator has to be in all rooms that should have humidity automation enabled var humidityAutomation = new ActuatorSensorAutomation <IHumidityControlDevice>(dm, "Humidity", (d) => d.Humidity.Value); humidityAutomation.RefencePoint = 55; //you should check humidity across all devices at home, and take mean + 10% to be safe. humidityAutomation.Hysteresis = 5; humidityAutomation.MaxOnTime = new TimeSpan(0, 1, 0); humidityAutomation.MinOnTime = new TimeSpan(0, 0, 15); humidityAutomation.MinOffTime = new TimeSpan(0, 0, 15); //create heating automation group. both heating sensors and actuators must be assigned to Heating function and the same rooms //actuator has to be in all rooms that should have heating automation enabled var heatingAutomation = new ActuatorSensorAutomation <IValveControlDevice>(dm, "Heating", (d) => Convert.ToInt32(Math.Round(d.Level.Value * 100))); heatingAutomation.RefencePoint = 20; //20% valve open heatingAutomation.Hysteresis = 2; heatingAutomation.MaxOnTime = new TimeSpan(0, 5, 0); heatingAutomation.MinOnTime = new TimeSpan(0, 0, 30); heatingAutomation.MinOffTime = new TimeSpan(0, 3, 0); for (;;) { //pull latest data from the web services dm.Refresh(); //syncs heating master values across the house and across the rooms //house is synced with all master values except ones related to temperature //each toom is synced with just the temperature related master values //this setup allows very flexiable management of the time zones, but the heat zones are seperate for each room :) SyncHeatingMasterValuesAutomation.SyncHeatingMastervalues(dm); //control the actuators based on the values //logic: //- each control group is controlled by multiple actuators assigned to the room that sensors are in. both sensors and acturators must be in the same function group //- if in any room, function's datapoint goes above a ref point, all function actuators assigned to that room will be turned OFF //- if in any room, function's datapoint goes belove ref point, all function actuators assigned to that room will be turned ON // - actuators that are needed for multiple rooms, will be kept alive, till they are not needed to be ON in all rooms //- hysteresis will be guarding against too frequent on and off humidityAutomation.Work(); heatingAutomation.Work(); //wait a bit before running again Thread.Sleep(3000); } }
static void Main(string[] args) { log4net.Config.XmlConfigurator.Configure(); int restartTries = 0; for (;;) { try { var dm = new DeviceManager(Settings.Default.HomematicServerAddress); LOGGER.Info("Starting external Slack notification service"); Slack s = Slack.TryFromCCU(dm); if (s != null) { dm.RegisterNotificationService(s); } LOGGER.Info("Starting alarm automation"); var alarmAutomation = new AlarmAutomation(dm, AutomationNames.AlarmAutomation); LOGGER.Info("Starting humidity automation"); var humidityAutomation = new ActuatorSensorAutomation <IHumidityControlDevice>(dm, AutomationNames.HumidityAutomation, Function.Humidity, (a, d) => d.Humidity.Value); humidityAutomation.RefencePoint = Settings.Default.HumidityAutomationRefencePoint; humidityAutomation.Hysteresis = Settings.Default.HumidityAutomationHysteresis; humidityAutomation.MaxOnTime = Settings.Default.HumidityAutomationMaxOnTime; humidityAutomation.MinOnTime = Settings.Default.HumidityAutomationMinOnTime; humidityAutomation.MinOffTime = Settings.Default.HumidityAutomationMinOffTime; LOGGER.Info("Starting heating automation"); var heatingAutomation = new ActuatorSensorAutomation <ITempControlDevice>(dm, AutomationNames.HeatingAutomation, Function.Heating, (a, d) => { if (d.Boost_Mode.Value) { a.IgnoreLimits = true; return(100); } int target = Convert.ToInt32(Math.Round(d.Set_Point_Temperature.Value * 10M)); int actual = Convert.ToInt32(Math.Round(d.Actual_Temperature.Value * 10M)); int diff = target - actual; return(diff); } ); heatingAutomation.RefencePoint = Settings.Default.HeatingAutomationRefencePoint; heatingAutomation.Hysteresis = Settings.Default.HeatingAutomationHysteresis; heatingAutomation.MaxOnTime = Settings.Default.HeatingAutomationMaxOnTime; heatingAutomation.MinOnTime = Settings.Default.HeatingAutomationMinOnTime; heatingAutomation.MinOffTime = Settings.Default.heatingAutomationMinOffTime; LOGGER.Info("Starting window open/close automation"); var windowAutomation = new WindowOpenAutomation(dm, AutomationNames.WindowOpenAutomation); LOGGER.Info("Starting heating master valus sync automation"); var syncHeatingMastervaluesAutomation = new SyncHeatingMasterValuesAutomation(dm, AutomationNames.SyncHeatingMastervaluesAutomation); LOGGER.Info("Starting webserver"); //init web server //web server runs in async mode, locking is required around all DM objects var server = new WebServer(Settings.Default.WebServerListenPort); server.WithCors(); RoomController.DeviceManager = dm; server.WithWebApi("/api/room", m => m.WithController <RoomController>()); DeviceController.DeviceManager = dm; server.WithWebApi("/api/device", m => m.WithController <DeviceController>()); AlarmControler.AlarmAutomation = alarmAutomation; server.WithWebApi("/api/alarm", m => m.WithController <AlarmControler>()); server.WithStaticFolder("/", Settings.Default.WebServerRoot, true, m => m.WithContentCaching(true)); server.RunAsync(); LOGGER.Info("Starting entering main loop"); for (;;) { //this will refresh data from HM api and run all automations dm.Work(); //log events foreach (var e in dm.Events) { LOGGER.InfoFormat("{0} EVENT {1}: ({2}) => ({3})", e.EventTimestamp.ToString("o"), e.Current.Name, e.Previous == null ? "" : e.Previous.Value, e.Current.Value ); } //refresh data every so often new ManualResetEvent(false).WaitOne(200); restartTries = 0; } } catch (Exception e) { restartTries++; if (restartTries < 5) { LOGGER.Error($"Got unhandled exception {restartTries} in a row. Restarting imediately", e); } else { LOGGER.Error($"Got unhandled exception {restartTries} in a row. Restarting in 3s..", e); new ManualResetEvent(false).WaitOne(3000); } } } }
static void Main(string[] args) { log4net.Config.XmlConfigurator.Configure(); for (;;) { try { LOGGER.Info($"Starting device manager for {Settings.Default.HomematicServerAddress}"); //init device manager var dm = new DeviceManager(Settings.Default.HomematicServerAddress); LOGGER.Info($"Starting humidity manager"); //init humidity automation, humidity is int from 0 to 100 var humidityAutomation = new ActuatorSensorAutomation <IHumidityControlDevice>(dm, "Humidity", (d) => d.Humidity.Value); humidityAutomation.RefencePoint = Settings.Default.HumidityAutomationRefencePoint; humidityAutomation.Hysteresis = Settings.Default.HumidityAutomationHysteresis; humidityAutomation.MaxOnTime = Settings.Default.HumidityAutomationMaxOnTime; humidityAutomation.MinOnTime = Settings.Default.HumidityAutomationMinOnTime; humidityAutomation.MinOffTime = Settings.Default.HumidityAutomationMinOffTime; LOGGER.Info("Starting heating manager"); var heatingAutomation = new ActuatorSensorAutomation <ITempControlDevice>(dm, "Heating", (d) => { int target = Convert.ToInt32(Math.Round(d.Set_Point_Temperature.Value * 10M)); int actual = Convert.ToInt32(Math.Round(d.Actual_Temperature.Value * 10M)); int diff = target - actual; return(diff); } ); heatingAutomation.RefencePoint = Settings.Default.HeatingAutomationRefencePoint; heatingAutomation.Hysteresis = Settings.Default.HeatingAutomationHysteresis; heatingAutomation.MaxOnTime = Settings.Default.HeatingAutomationMaxOnTime; heatingAutomation.MinOnTime = Settings.Default.HeatingAutomationMinOnTime; heatingAutomation.MinOffTime = Settings.Default.heatingAutomationMinOffTime; LOGGER.Info("Starting webserver"); //init web server //web server runs in async mode, locking is required around all DM objects var server = new WebServer(Settings.Default.WebServerListenPort, RoutingStrategy.Regex); server.RegisterModule(new WebApiModule()); server.Module <CorsModule>(); RoomController.DeviceManager = dm; server.Module <WebApiModule>().RegisterController <RoomController>(); server.RunAsync(); LOGGER.Info("Starting entering main loop"); for (;;) { //has internal smart locking (only locks when data structures are modified, not during xmlapi queries) List <DatapointEvent> eventsSinceLastRefresh = dm.Refresh(); foreach (var e in eventsSinceLastRefresh) { LOGGER.InfoFormat("{0} EVENT {1}: ({2}) => ({3})", e.EventTimestamp.ToString("o"), e.Current.Name, e.Previous == null ? "" : e.Previous.Value, e.Current.Value ); } //dumb locking for now lock (dm.RefreshLock) { SyncHeatingMasterValuesAutomation.SyncHeatingMastervalues(dm); humidityAutomation.Work(); heatingAutomation.Work(); } //refresh data every second new ManualResetEvent(false).WaitOne(1000); } } catch (Exception e) { LOGGER.Error("Error. Restarting device manager in 10s..", e); new ManualResetEvent(false).WaitOne(10000); } } }