public void Setup(Home home, CCToolsBoardController ccToolsController, IOBoardManager ioBoardManager, DHT22Accessor dht22Accessor)
        {
            var hsrel5 = ccToolsController.CreateHSREL5(Device.ChildrensRoomHSREL5, 63);
            var input0 = ioBoardManager.GetInputBoard(Device.Input0);

            const int SensorPin = 7; //3;

            var childrensRoom = home.AddRoom(Room.ChildrensRoom)
                .WithTemperatureSensor(ChildrensRoom.TemperatureSensor, dht22Accessor.GetTemperatureSensor(SensorPin))
                .WithHumiditySensor(ChildrensRoom.HumiditySensor, dht22Accessor.GetHumiditySensor(SensorPin))
                .WithLamp(ChildrensRoom.LightCeilingMiddle, hsrel5.GetOutput(6).WithInvertedState())
                .WithRollerShutter(ChildrensRoom.RollerShutter, hsrel5.GetOutput(4), hsrel5.GetOutput(3), RollerShutter.DefaultMaxMovingDuration, 20000)
                .WithSocket(ChildrensRoom.SocketWindow, hsrel5.GetOutput(0))
                .WithSocket(ChildrensRoom.SocketWallLeft, hsrel5.GetOutput(1))
                .WithSocket(ChildrensRoom.SocketWallRight, hsrel5.GetOutput(2))
                .WithButton(ChildrensRoom.Button, input0.GetInput(0))
                .WithWindow(ChildrensRoom.Window, w => w.WithCenterCasement(input0.GetInput(5), input0.GetInput(4)))
                .WithRollerShutterButtons(ChildrensRoom.RollerShutterButtons, input0.GetInput(1), input0.GetInput(2));

            childrensRoom.Lamp(ChildrensRoom.LightCeilingMiddle).ConnectToggleActionWith(childrensRoom.Button(ChildrensRoom.Button));

            childrensRoom.SetupAutomaticRollerShutters().WithRollerShutter(childrensRoom.RollerShutter(ChildrensRoom.RollerShutter));
            childrensRoom.RollerShutter(ChildrensRoom.RollerShutter)
                .ConnectWith(childrensRoom.RollerShutterButtons(ChildrensRoom.RollerShutterButtons));
        }
        public void Setup(Home home, CCToolsBoardController ccToolsController, IOBoardManager ioBoardManager, DHT22Accessor dht22Accessor)
        {
            var hspe16_FloorAndLowerBathroom = ioBoardManager.GetOutputBoard(Device.LowerFloorAndLowerBathroomHSPE16);
            var input3 = ioBoardManager.GetInputBoard(Device.Input3);

            const int SensorPin = 3; //5;

            var bathroom = home.AddRoom(Room.LowerBathroom)
                .WithMotionDetector(LowerBathroom.MotionDetector, input3.GetInput(15))
                .WithTemperatureSensor(LowerBathroom.TemperatureSensor, dht22Accessor.GetTemperatureSensor(SensorPin))
                .WithHumiditySensor(LowerBathroom.HumiditySensor, dht22Accessor.GetHumiditySensor(SensorPin))
                .WithLamp(LowerBathroom.LightCeilingDoor, hspe16_FloorAndLowerBathroom.GetOutput(0).WithInvertedState())
                .WithLamp(LowerBathroom.LightCeilingMiddle, hspe16_FloorAndLowerBathroom.GetOutput(1).WithInvertedState())
                .WithLamp(LowerBathroom.LightCeilingWindow, hspe16_FloorAndLowerBathroom.GetOutput(2).WithInvertedState())
                .WithLamp(LowerBathroom.LampMirror, hspe16_FloorAndLowerBathroom.GetOutput(4).WithInvertedState())
                .WithWindow(LowerBathroom.Window, w => w.WithCenterCasement(input3.GetInput(13), input3.GetInput(14)));

            bathroom.CombineActuators(LowerBathroom.CombinedLights)
                .WithActuator(bathroom.Lamp(LowerBathroom.LightCeilingDoor))
                .WithActuator(bathroom.Lamp(LowerBathroom.LightCeilingMiddle))
                .WithActuator(bathroom.Lamp(LowerBathroom.LightCeilingWindow))
                .WithActuator(bathroom.Lamp(LowerBathroom.LampMirror));

            bathroom.SetupAutomaticTurnOnAndOffAction()
                .WithTrigger(bathroom.MotionDetector(LowerBathroom.MotionDetector))
                .WithTarget(bathroom.BinaryStateOutput(LowerBathroom.CombinedLights));
        }
        public void Setup(Home home, CCToolsBoardController ccToolsController, IOBoardManager ioBoardManager, DHT22Accessor dht22Accessor)
        {
            var hsrel5 = ccToolsController.CreateHSREL5(Device.ReadingRoomHSREL5, 62);
            var input2 = ioBoardManager.GetInputBoard(Device.Input2);

            const int SensorPin = 9; //2;

            var readingRoom = home.AddRoom(Room.ReadingRoom)
                .WithTemperatureSensor(ReadingRoom.TemperatureSensor, dht22Accessor.GetTemperatureSensor(SensorPin))
                .WithHumiditySensor(ReadingRoom.HumiditySensor, dht22Accessor.GetHumiditySensor(SensorPin))
                .WithLamp(ReadingRoom.LightCeilingMiddle, hsrel5.GetOutput(6).WithInvertedState())
                .WithRollerShutter(ReadingRoom.RollerShutter, hsrel5.GetOutput(4), hsrel5.GetOutput(3), RollerShutter.DefaultMaxMovingDuration, 20000)
                .WithSocket(ReadingRoom.SocketWindow, hsrel5.GetOutput(0))
                .WithSocket(ReadingRoom.SocketWallLeft, hsrel5.GetOutput(1))
                .WithSocket(ReadingRoom.SocketWallRight, hsrel5.GetOutput(2))
                .WithButton(ReadingRoom.Button, input2.GetInput(13))
                .WithWindow(ReadingRoom.Window, w => w.WithCenterCasement(input2.GetInput(8))) // Tilt = input2.GetInput(9) -- currently broken!
                .WithRollerShutterButtons(ReadingRoom.RollerShutterButtons, input2.GetInput(12), input2.GetInput(11));

            readingRoom.Lamp(ReadingRoom.LightCeilingMiddle).ConnectToggleActionWith(readingRoom.Button(ReadingRoom.Button));

            readingRoom.SetupAutomaticRollerShutters().WithRollerShutter(readingRoom.RollerShutter(ReadingRoom.RollerShutter));
            readingRoom.RollerShutter(ReadingRoom.RollerShutter)
                .ConnectWith(readingRoom.RollerShutterButtons(ReadingRoom.RollerShutterButtons));
        }
        public void Setup(Home home, CCToolsBoardController ccToolsController, IOBoardManager ioBoardManager, DHT22Accessor dht22Reader)
        {
            var hsrel8LowerHeatingValves = ccToolsController.CreateHSREL8(Device.LowerHeatingValvesHSREL8, 16);
            var hsrel5UpperHeatingValves = ccToolsController.CreateHSREL5(Device.UpperHeatingValvesHSREL5, 56);

            var hsrel5Stairway = ioBoardManager.GetOutputBoard(Device.StairwayHSREL5);
            var input3 = ioBoardManager.GetInputBoard(Device.Input3);

            var storeroom = home.AddRoom(Room.Storeroom)
                .WithMotionDetector(Storeroom.MotionDetector, input3.GetInput(12))
                .WithLamp(Storeroom.LightCeiling, hsrel5Stairway.GetOutput(7).WithInvertedState())
                .WithSocket(Storeroom.CatLitterBoxFan, hsrel8LowerHeatingValves.GetOutput(15));

            storeroom.SetupAutomaticTurnOnAndOffAction()
                .WithTrigger(storeroom.MotionDetector(Storeroom.MotionDetector))
                .WithTarget(storeroom.Lamp(Storeroom.LightCeiling))
                .WithTarget(storeroom.Socket(Storeroom.CatLitterBoxFan))
                .WithOnDuration(TimeSpan.FromMinutes(1));

            storeroom.WithSocket(Storeroom.CirculatingPump, hsrel5UpperHeatingValves.GetOutput(3));

            storeroom.SetupAutomaticTurnOnAndOffAction()
                .WithTrigger(home.Room(Room.Kitchen).MotionDetector(KitchenConfiguration.Kitchen.MotionDetector))
                .WithTrigger(home.Room(Room.LowerBathroom).MotionDetector(LowerBathroomConfiguration.LowerBathroom.MotionDetector))
                .WithTarget(storeroom.Socket(Storeroom.CirculatingPump))
                .WithOnDuration(TimeSpan.FromMinutes(1))
                .WithEnabledAtDay(home.WeatherStation);
        }
        public void ConnectActuators(Home home)
        {
            if (home == null) throw new ArgumentNullException(nameof(home));

            foreach (var actuator in home.Actuators.Values)
            {
                var binaryStateOutput = actuator as IBinaryStateOutputActuator;
                if (binaryStateOutput != null)
                {
                    HandleBinaryStateOutputActuator(binaryStateOutput);
                    continue;
                }

                var stateMachineOutput = actuator as StateMachine;
                if (stateMachineOutput != null)
                {
                    HandleStateMachineOutputActuator(stateMachineOutput);
                    continue;
                }

                var sensor = actuator as SingleValueSensorBase;
                if (sensor != null)
                {
                    sensor.ValueChanged += (s, e) =>
                    {
                        OnSensorValueChanged(sensor);
                    };

                    continue;
                }

                var motionDetector = actuator as IMotionDetector;
                if (motionDetector != null)
                {
                    motionDetector.MotionDetected += (s, e) =>
                    {
                        OnMotionDetected(motionDetector);
                    };

                    continue;
                }

                var button = actuator as IButton;
                if (button != null)
                {
                    button.PressedShort += (s, e) =>
                    {
                        OnButtonPressed(button, ButtonPressedDuration.Short);
                    };

                    button.PressedLong += (s, e) =>
                    {
                        OnButtonPressed(button, ButtonPressedDuration.Long);
                    };
                }
            }
        }
        protected override void Initialize()
        {
            InitializeHealthMonitor(22);

            var pi2PortController = new Pi2PortController();
            
            var i2CBus = new I2cBusAccessor(NotificationHandler);

            IWeatherStation weatherStation = CreateWeatherStation();

            var i2CHardwareBridge = new I2CHardwareBridge(50, i2CBus);
            var sensorBridgeDriver = new DHT22Accessor(i2CHardwareBridge, Timer);

            var ioBoardManager = new IOBoardManager(HttpApiController, NotificationHandler);
            var ccToolsBoardController = new CCToolsBoardController(i2CBus, ioBoardManager, NotificationHandler);

            ccToolsBoardController.CreateHSPE16InputOnly(Device.Input0, 42);
            ccToolsBoardController.CreateHSPE16InputOnly(Device.Input1, 43);
            ccToolsBoardController.CreateHSPE16InputOnly(Device.Input2, 47);
            ccToolsBoardController.CreateHSPE16InputOnly(Device.Input3, 45);
            ccToolsBoardController.CreateHSPE16InputOnly(Device.Input4, 46);
            ccToolsBoardController.CreateHSPE16InputOnly(Device.Input5, 44);

            RemoteSwitchController remoteSwitchController = SetupRemoteSwitchController(i2CHardwareBridge);

            var home = new Home(Timer, HealthMonitor, weatherStation, HttpApiController, NotificationHandler);

            new BedroomConfiguration().Setup(home, ccToolsBoardController, ioBoardManager, sensorBridgeDriver);
            new OfficeConfiguration().Setup(home, ccToolsBoardController, ioBoardManager, sensorBridgeDriver, remoteSwitchController);
            new UpperBathroomConfiguration().Setup(home, ccToolsBoardController, ioBoardManager, sensorBridgeDriver);
            new ReadingRoomConfiguration().Setup(home, ccToolsBoardController, ioBoardManager, sensorBridgeDriver);
            new ChildrensRoomRoomConfiguration().Setup(home, ccToolsBoardController, ioBoardManager, sensorBridgeDriver);
            new KitchenConfiguration().Setup(home, ccToolsBoardController, ioBoardManager, sensorBridgeDriver);
            new FloorConfiguration().Setup(home, ccToolsBoardController, ioBoardManager, sensorBridgeDriver);
            new LowerBathroomConfiguration().Setup(home, ccToolsBoardController, ioBoardManager, sensorBridgeDriver);
            new StoreroomConfiguration().Setup(home, ccToolsBoardController, ioBoardManager, sensorBridgeDriver);
            new LivingRoomConfiguration().Setup(home, ccToolsBoardController, ioBoardManager, sensorBridgeDriver);

            home.PublishStatisticsNotification();

            AttachAzureEventHubPublisher(home);

            var localCsvFileWriter = new LocalCsvFileWriter(NotificationHandler);
            localCsvFileWriter.ConnectActuators(home);

            var ioBoardsInterruptMonitor = new InterruptMonitor(pi2PortController.GetInput(4));
            Timer.Tick += (s, e) => ioBoardsInterruptMonitor.Poll();
            ioBoardsInterruptMonitor.InterruptDetected += (s, e) => ioBoardManager.PollInputBoardStates();
        }
        public void Setup(Home home, CCToolsBoardController ccToolsController, IOBoardManager ioBoardManager, DHT22Accessor dht22Accessor)
        {
            var hsrel5 = ccToolsController.CreateHSREL5(Device.UpperBathroomHSREL5, 61);
            var input5 = ioBoardManager.GetInputBoard(Device.Input5);

            const int SensorPin = 4; //7;

            var bathroom = home.AddRoom(Room.UpperBathroom)
                .WithTemperatureSensor(UpperBathroom.TemperatureSensor, dht22Accessor.GetTemperatureSensor(SensorPin))
                .WithHumiditySensor(UpperBathroom.HumiditySensor, dht22Accessor.GetHumiditySensor(SensorPin))
                .WithMotionDetector(UpperBathroom.MotionDetector, input5.GetInput(15))
                .WithLamp(UpperBathroom.LightCeilingDoor, hsrel5.GetOutput(0))
                .WithLamp(UpperBathroom.LightCeilingEdge, hsrel5.GetOutput(1))
                .WithLamp(UpperBathroom.LightCeilingMirrorCabinet, hsrel5.GetOutput(2))
                .WithLamp(UpperBathroom.LampMirrorCabinet, hsrel5.GetOutput(3));

            var combinedLights =
                bathroom.CombineActuators(UpperBathroom.CombinedCeilingLights)
                    .WithActuator(bathroom.Lamp(UpperBathroom.LightCeilingDoor))
                    .WithActuator(bathroom.Lamp(UpperBathroom.LightCeilingEdge))
                    .WithActuator(bathroom.Lamp(UpperBathroom.LightCeilingMirrorCabinet))
                    .WithActuator(bathroom.Lamp(UpperBathroom.LampMirrorCabinet));

            bathroom.SetupAutomaticTurnOnAndOffAction()
                .WithTrigger(bathroom.MotionDetector(UpperBathroom.MotionDetector))
                .WithTarget(combinedLights)
                .WithOnDuration(TimeSpan.FromMinutes(8));

            var fanPort0 = hsrel5.GetOutput(4);
            var fanPort1 = hsrel5.GetOutput(5);
            var fan = bathroom.AddStateMachine(UpperBathroom.Fan);
            fan.AddOffState().WithPort(fanPort0, BinaryState.Low).WithPort(fanPort1, BinaryState.Low);
            fan.AddState("1").WithPort(fanPort0, BinaryState.High).WithPort(fanPort1, BinaryState.Low);
            fan.AddState("2").WithPort(fanPort0, BinaryState.High).WithPort(fanPort1, BinaryState.High);
            fan.TurnOff();

            new AutomaticBathroomFanAutomation(home.Timer)
                .WithSlowDuration(TimeSpan.FromMinutes(8))
                .WithFastDuration(TimeSpan.FromMinutes(12))
                .WithMotionDetector(bathroom.MotionDetector(UpperBathroom.MotionDetector))
                .WithActuator(fan);
        }
        public void Setup(Home home, CCToolsBoardController ccToolsController, IOBoardManager ioBoardManager, DHT22Accessor dht22Accessor)
        {
            var hsrel8 = ccToolsController.CreateHSREL8(Device.LivingRoomHSREL8, 18);
            var hsrel5 = ccToolsController.CreateHSREL5(Device.LivingRoomHSREL5, 57);
            
            var input0 = ioBoardManager.GetInputBoard(Device.Input0);
            var input1 = ioBoardManager.GetInputBoard(Device.Input1);

            const int SensorPin = 12; // 0;

            var livingRoom = home.AddRoom(Room.LivingRoom)
                .WithTemperatureSensor(LivingRoom.TemperatureSensor, dht22Accessor.GetTemperatureSensor(SensorPin))
                .WithHumiditySensor(LivingRoom.HumiditySensor, dht22Accessor.GetHumiditySensor(SensorPin))
                .WithLamp(LivingRoom.LampCouch, hsrel8.GetOutput(8).WithInvertedState())
                .WithLamp(LivingRoom.LampDiningTable, hsrel8.GetOutput(9).WithInvertedState())
                .WithSocket(LivingRoom.SocketWindowLeftLower, hsrel8.GetOutput(1))
                .WithSocket(LivingRoom.SocketWindowMiddleLower, hsrel8.GetOutput(2))
                .WithSocket(LivingRoom.SocketWindowRightLower, hsrel8.GetOutput(3))
                .WithSocket(LivingRoom.SocketWallRightEdgeRight, hsrel8.GetOutput(4))
                .WithSocket(LivingRoom.SocketWindowLeftUpper, hsrel8.GetOutput(5))
                .WithSocket(LivingRoom.SocketWindowRightUpper, hsrel8.GetOutput(7))
                .WithButton(LivingRoom.ButtonUpper, input0.GetInput(15))
                .WithButton(LivingRoom.ButtonMiddle, input0.GetInput(14))
                .WithButton(LivingRoom.ButtonLower, input0.GetInput(13))
                .WithButton(LivingRoom.ButtonPassage, input1.GetInput(10))
                .WithWindow(LivingRoom.WindowLeft,
                    w => w.WithLeftCasement(input0.GetInput(10), input0.GetInput(11)).WithRightCasement(input0.GetInput(9), input0.GetInput(8)))
                .WithWindow(LivingRoom.WindowRight,
                    w => w.WithLeftCasement(input1.GetInput(14), input1.GetInput(15)).WithRightCasement(input1.GetInput(13), input1.GetInput(12)));

            livingRoom.Lamp(LivingRoom.LampDiningTable)
                .ConnectToggleActionWith(livingRoom.Button(LivingRoom.ButtonUpper))
                .ConnectToggleActionWith(livingRoom.Button(LivingRoom.ButtonPassage));

            livingRoom.Lamp(LivingRoom.LampCouch).
                ConnectToggleActionWith(livingRoom.Button(LivingRoom.ButtonMiddle));

            livingRoom.Socket(LivingRoom.SocketWallRightEdgeRight).
                ConnectToggleActionWith(livingRoom.Button(LivingRoom.ButtonLower));
        }
        public void Setup(Home home, CCToolsBoardController ccToolsController, IOBoardManager ioBoardManager, DHT22Accessor dht22Accessor, RemoteSwitchController remoteSwitchController)
        {
            var hsrel8 = ccToolsController.CreateHSREL8(Device.OfficeHSREL8, 20);
            var hspe8 = ccToolsController.CreateHSPE8OutputOnly(Device.UpperFloorAndOfficeHSPE8, 37);
            var input4 = ioBoardManager.GetInputBoard(Device.Input4);
            var input5 = ioBoardManager.GetInputBoard(Device.Input5);

            const int SensorPin = 2; //6;

            var office = home.AddRoom(Room.Office)
                .WithMotionDetector(Office.MotionDetector, input4.GetInput(13))
                .WithTemperatureSensor(Office.TemperatureSensor, dht22Accessor.GetTemperatureSensor(SensorPin))
                .WithHumiditySensor(Office.HumiditySensor, dht22Accessor.GetHumiditySensor(SensorPin))
                .WithLamp(Office.LightCeilingFrontRight, hsrel8.GetOutput(8).WithInvertedState())
                .WithLamp(Office.LightCeilingFrontMiddle, hspe8.GetOutput(2).WithInvertedState())
                .WithLamp(Office.LightCeilingFrontLeft, hspe8.GetOutput(0).WithInvertedState())
                .WithLamp(Office.LightCeilingMiddleRight, hsrel8.GetOutput(9).WithInvertedState())
                .WithLamp(Office.LightCeilingMiddleMiddle, hspe8.GetOutput(3).WithInvertedState())
                .WithLamp(Office.LightCeilingMiddleLeft, hspe8.GetOutput(1).WithInvertedState())
                .WithLamp(Office.LightCeilingRearRight, hsrel8.GetOutput(12).WithInvertedState())
                .WithLamp(Office.LightCeilingRearLeft, hsrel8.GetOutput(13).WithInvertedState())
                .WithSocket(Office.SocketFrontLeft, hsrel8.GetOutput(0))
                .WithSocket(Office.SocketFrontRight, hsrel8.GetOutput(6))
                .WithSocket(Office.SocketWindowLeft, hsrel8.GetOutput(10).WithInvertedState())
                .WithSocket(Office.SocketWindowRight, hsrel8.GetOutput(11).WithInvertedState())
                .WithSocket(Office.SocketRearLeftEdge, hsrel8.GetOutput(7))
                .WithSocket(Office.SocketRearLeft, hsrel8.GetOutput(2))
                .WithSocket(Office.SocketRearRight, hsrel8.GetOutput(1))
                .WithButton(Office.ButtonUpperLeft, input5.GetInput(0))
                .WithButton(Office.ButtonLowerLeft, input5.GetInput(1))
                .WithButton(Office.ButtonLowerRight, input4.GetInput(14))
                .WithButton(Office.ButtonUpperRight, input4.GetInput(15))
                .WithWindow(Office.WindowLeft, w => w.WithLeftCasement(input4.GetInput(11)).WithRightCasement(input4.GetInput(12), input4.GetInput(10)))
                .WithWindow(Office.WindowRight, w => w.WithLeftCasement(input4.GetInput(8)).WithRightCasement(input4.GetInput(9), input5.GetInput(8)));

            office.WithSocket(Office.RemoteSocketDesk, remoteSwitchController.GetOutput(0));

            var lightsCouchOnly = office.CombineActuators(Office.CombinedCeilingLightsCouchOnly)
                .WithActuator(office.Actuator<Lamp>(Office.LightCeilingRearRight));

            var lightsDeskOnly = office.CombineActuators(Office.CombinedCeilingLightsDeskOnly)
                .WithActuator(office.Actuator<Lamp>(Office.LightCeilingFrontMiddle))
                .WithActuator(office.Actuator<Lamp>(Office.LightCeilingFrontLeft))
                .WithActuator(office.Actuator<Lamp>(Office.LightCeilingMiddleLeft));

            var lightsOther = office.CombineActuators(Office.CombinedCeilingLightsOther)
                .WithActuator(office.Actuator<Lamp>(Office.LightCeilingFrontRight))
                .WithActuator(office.Actuator<Lamp>(Office.LightCeilingMiddleMiddle))
                .WithActuator(office.Actuator<Lamp>(Office.LightCeilingMiddleRight))
                .WithActuator(office.Actuator<Lamp>(Office.LightCeilingRearLeft));

            var light = office.AddStateMachine(Office.CombinedCeilingLights)
                .WithTurnOffIfStateIsAppliedTwice();

            light.AddOffState()
                .WithActuator(lightsDeskOnly, BinaryActuatorState.Off)
                .WithActuator(lightsCouchOnly, BinaryActuatorState.Off)
                .WithActuator(lightsOther, BinaryActuatorState.Off);

            light.AddOnState()
                .WithActuator(lightsDeskOnly, BinaryActuatorState.On)
                .WithActuator(lightsCouchOnly, BinaryActuatorState.On)
                .WithActuator(lightsOther, BinaryActuatorState.On).
                ConnectApplyStateWith(office.Actuator<Button>(Office.ButtonUpperLeft));

            light.AddState("DeskOnly")
                .WithActuator(lightsDeskOnly, BinaryActuatorState.On)
                .WithActuator(lightsCouchOnly, BinaryActuatorState.Off)
                .WithActuator(lightsOther, BinaryActuatorState.Off)
                .ConnectApplyStateWith(office.Actuator<Button>(Office.ButtonLowerLeft));

            light.AddState("CouchOnly")
                .WithActuator(lightsDeskOnly, BinaryActuatorState.Off)
                .WithActuator(lightsCouchOnly, BinaryActuatorState.On)
                .WithActuator(lightsOther, BinaryActuatorState.Off)
                .ConnectApplyStateWith(office.Actuator<Button>(Office.ButtonLowerRight));

            office.Button(Office.ButtonUpperLeft).WithLongAction(() =>
            {
                light.TurnOff();
                office.Socket(Office.SocketRearLeftEdge).TurnOff();
                office.Socket(Office.SocketRearLeft).TurnOff();
                office.Socket(Office.SocketFrontLeft).TurnOff();
            });
        }
        private void AttachAzureEventHubPublisher(Home home)
        {
            try
            {
                var configuration = JsonObject.Parse(File.ReadAllText(Path.Combine(ApplicationData.Current.LocalFolder.Path, "EventHubConfiguration.json")));

                var azureEventHubPublisher = new AzureEventHubPublisher(
                    configuration.GetNamedString("eventHubNamespace"),
                    configuration.GetNamedString("eventHubName"),
                    configuration.GetNamedString("sasToken"),
                    NotificationHandler);

                azureEventHubPublisher.ConnectActuators(home);
                NotificationHandler.PublishFrom(this, NotificationType.Info, "AzureEventHubPublisher initialized successfully.");
            }
            catch (Exception exception)
            {
                NotificationHandler.PublishFrom(this, NotificationType.Warning, "Unable to create azure event hub publisher. " + exception.Message);
            }
        }
        protected override void Initialize()
        {
            InitializeHealthMonitor(22);

            var pi2PortController = new Pi2PortController();

            IWeatherStation weatherStation = CreateWeatherStation();
            var i2CBus = new I2cBusAccessor(NotificationHandler);

            var ioBoardManager = new IOBoardManager(HttpApiController, NotificationHandler);
            var ccToolsFactory = new CCToolsBoardController(i2CBus, ioBoardManager, NotificationHandler);
            var hsrt16 = ccToolsFactory.CreateHSRT16(Device.CellarHSRT16, 32);

            var home = new Home(Timer, HealthMonitor, weatherStation, HttpApiController, NotificationHandler);

            var garden = home.AddRoom(Room.Garden)
                .WithLamp(Garden.LampTerrace, hsrt16.GetOutput(15))
                .WithLamp(Garden.LampGarage, hsrt16.GetOutput(14))
                .WithLamp(Garden.LampTap, hsrt16.GetOutput(13))
                .WithLamp(Garden.SpotlightRoof, hsrt16.GetOutput(12))
                .WithLamp(Garden.LampRearArea, hsrt16.GetOutput(11))
                .WithSocket(Garden.SocketPavillion, hsrt16.GetOutput(10))
                // 9 = free
                .WithLamp(Garden.LampParkingLot1, hsrt16.GetOutput(8))
                .WithLamp(Garden.LampParkingLot2, hsrt16.GetOutput(6))
                .WithLamp(Garden.LampParkingLot3, hsrt16.GetOutput(7))

                .WithButton(Garden.Button, pi2PortController.GetInput(4).WithInvertedState());

            var stateMachine = garden.AddStateMachine(Garden.StateMachine);

            stateMachine.AddOffState()
                .WithActuator(garden.Lamp(Garden.LampTerrace), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.LampGarage), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.LampTap), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.SpotlightRoof), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.LampRearArea), BinaryActuatorState.Off);

            stateMachine.AddState()
                .WithActuator(garden.Lamp(Garden.LampTerrace), BinaryActuatorState.On)
                .WithActuator(garden.Lamp(Garden.LampGarage), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.LampTap), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.SpotlightRoof), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.LampRearArea), BinaryActuatorState.Off);

            stateMachine.AddState()
                .WithActuator(garden.Lamp(Garden.LampTerrace), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.LampGarage), BinaryActuatorState.On)
                .WithActuator(garden.Lamp(Garden.LampTap), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.SpotlightRoof), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.LampRearArea), BinaryActuatorState.Off);

            stateMachine.AddState()
                .WithActuator(garden.Lamp(Garden.LampTerrace), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.LampGarage), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.LampTap), BinaryActuatorState.On)
                .WithActuator(garden.Lamp(Garden.SpotlightRoof), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.LampRearArea), BinaryActuatorState.Off);

            stateMachine.AddState()
                .WithActuator(garden.Lamp(Garden.LampTerrace), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.LampGarage), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.LampTap), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.SpotlightRoof), BinaryActuatorState.On)
                .WithActuator(garden.Lamp(Garden.LampRearArea), BinaryActuatorState.Off);

            stateMachine.AddState()
                .WithActuator(garden.Lamp(Garden.LampTerrace), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.LampGarage), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.LampTap), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.SpotlightRoof), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.LampRearArea), BinaryActuatorState.On);

            stateMachine.AddState()
                .WithActuator(garden.Lamp(Garden.LampTerrace), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.LampGarage), BinaryActuatorState.On)
                .WithActuator(garden.Lamp(Garden.LampTap), BinaryActuatorState.On)
                .WithActuator(garden.Lamp(Garden.SpotlightRoof), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.LampRearArea), BinaryActuatorState.Off);

            stateMachine.AddState()
                .WithActuator(garden.Lamp(Garden.LampTerrace), BinaryActuatorState.On)
                .WithActuator(garden.Lamp(Garden.LampGarage), BinaryActuatorState.On)
                .WithActuator(garden.Lamp(Garden.LampTap), BinaryActuatorState.On)
                .WithActuator(garden.Lamp(Garden.SpotlightRoof), BinaryActuatorState.Off)
                .WithActuator(garden.Lamp(Garden.LampRearArea), BinaryActuatorState.Off);

            stateMachine.AddState()
                .WithActuator(garden.Lamp(Garden.LampTerrace), BinaryActuatorState.On)
                .WithActuator(garden.Lamp(Garden.LampGarage), BinaryActuatorState.On)
                .WithActuator(garden.Lamp(Garden.LampTap), BinaryActuatorState.On)
                .WithActuator(garden.Lamp(Garden.SpotlightRoof), BinaryActuatorState.On)
                .WithActuator(garden.Lamp(Garden.LampRearArea), BinaryActuatorState.On);

            garden.StateMachine(Garden.StateMachine).ConnectMoveNextAndToggleOffWith(garden.Button(Garden.Button));

            garden.CombineActuators(Garden.CombinedParkingLotLamps)
                .WithActuator(garden.Lamp(Garden.LampParkingLot1))
                .WithActuator(garden.Lamp(Garden.LampParkingLot2)) // Mitte
                .WithActuator(garden.Lamp(Garden.LampParkingLot3));

            garden.SetupAlwaysOn()
                .WithActuator(garden.BinaryStateOutput(Garden.CombinedParkingLotLamps))
                .WithOnlyAtNightRange(home.WeatherStation)
                .WithOffBetweenRange(TimeSpan.FromHours(22).Add(TimeSpan.FromMinutes(30)), TimeSpan.FromHours(5));

            home.PublishStatisticsNotification();

            Timer.Tick += (s, e) => { pi2PortController.PollOpenInputPorts(); };
        }
        public void Setup(Home home, CCToolsBoardController ccToolsController, IOBoardManager ioBoardManager, DHT22Accessor dht22Accessor)
        {
            var hsrel5 = ccToolsController.CreateHSREL5(Device.BedroomHSREL5, 38);
            var hsrel8 = ccToolsController.CreateHSREL8(Device.BedroomHSREL8, 21);
            var input5 = ioBoardManager.GetInputBoard(Device.Input5);
            var input4 = ioBoardManager.GetInputBoard(Device.Input4);

            const int SensorPin = 6; //8;

            var bedroom = home.AddRoom(Room.Bedroom)
                .WithTemperatureSensor(Bedroom.TemperatureSensor, dht22Accessor.GetTemperatureSensor(SensorPin))
                .WithHumiditySensor(Bedroom.HumiditySensor, dht22Accessor.GetHumiditySensor(SensorPin))
                .WithMotionDetector(Bedroom.MotionDetector, input5.GetInput(12))
                .WithLamp(Bedroom.LightCeiling, hsrel5.GetOutput(5).WithInvertedState())
                .WithLamp(Bedroom.LightCeilingWindow, hsrel5.GetOutput(6).WithInvertedState())
                .WithLamp(Bedroom.LightCeilingWall, hsrel5.GetOutput(7).WithInvertedState())
                .WithSocket(Bedroom.SocketWindowLeft, hsrel5.GetOutput(0))
                .WithSocket(Bedroom.SocketWindowRight, hsrel5.GetOutput(1))
                .WithSocket(Bedroom.SocketWall, hsrel5.GetOutput(2))
                .WithSocket(Bedroom.SocketWallEdge, hsrel5.GetOutput(3))
                .WithSocket(Bedroom.SocketBedLeft, hsrel8.GetOutput(7))
                .WithSocket(Bedroom.SocketBedRight, hsrel8.GetOutput(9))
                .WithLamp(Bedroom.LampBedLeft, hsrel5.GetOutput(4))
                .WithLamp(Bedroom.LampBedRight, hsrel8.GetOutput(8).WithInvertedState())
                .WithButton(Bedroom.ButtonDoor, input5.GetInput(11))
                .WithButton(Bedroom.ButtonWindowUpper, input5.GetInput(10))
                .WithButton(Bedroom.ButtonWindowLower, input5.GetInput(13))
                .WithButton(Bedroom.ButtonBedLeftInner, input4.GetInput(2))
                .WithButton(Bedroom.ButtonBedLeftOuter, input4.GetInput(0))
                .WithButton(Bedroom.ButtonBedRightInner, input4.GetInput(1))
                .WithButton(Bedroom.ButtonBedRightOuter, input4.GetInput(3))
                .WithRollerShutter(Bedroom.RollerShutterLeft, hsrel8.GetOutput(6), hsrel8.GetOutput(5), TimeSpan.FromSeconds(20), 17000)
                .WithRollerShutter(Bedroom.RollerShutterRight, hsrel8.GetOutput(3), hsrel8.GetOutput(4), TimeSpan.FromSeconds(20), 17000)
                .WithRollerShutterButtons(Bedroom.RollerShutterButtonsUpper, input5.GetInput(6), input5.GetInput(7))
                .WithRollerShutterButtons(Bedroom.RollerShutterButtonsLower, input5.GetInput(4), input5.GetInput(5))
                .WithWindow(Bedroom.WindowLeft, w => w.WithCenterCasement(input5.GetInput(2)))
                .WithWindow(Bedroom.WindowRight, w => w.WithCenterCasement(input5.GetInput(3)));

            bedroom.RollerShutter(Bedroom.RollerShutterLeft)
                .ConnectWith(bedroom.RollerShutterButtons(Bedroom.RollerShutterButtonsUpper));
            bedroom.RollerShutter(Bedroom.RollerShutterRight)
                .ConnectWith(bedroom.RollerShutterButtons(Bedroom.RollerShutterButtonsLower));

            bedroom.CombineActuators(Bedroom.CombinedCeilingLights)
                .WithActuator(bedroom.Lamp(Bedroom.LightCeilingWall))
                .WithActuator(bedroom.Lamp(Bedroom.LightCeilingWindow))
                .ConnectToggleActionWith(bedroom.Button(Bedroom.ButtonDoor))
                .ConnectToggleActionWith(bedroom.Button(Bedroom.ButtonWindowUpper));

            bedroom.Button(Bedroom.ButtonDoor).WithLongAction(() =>
            {
                bedroom.Lamp(Bedroom.LampBedLeft).TurnOff();
                bedroom.Lamp(Bedroom.LampBedRight).TurnOff();
                bedroom.Lamp(Bedroom.CombinedCeilingLights).TurnOff();
            });

            bedroom.SetupAutomaticRollerShutters()
                .WithRollerShutter(bedroom.RollerShutter(Bedroom.RollerShutterLeft))
                .WithRollerShutter(bedroom.RollerShutter(Bedroom.RollerShutterRight))
                .WithDoNotOpenBefore(TimeSpan.FromHours(7).Add(TimeSpan.FromMinutes(15)))
                .WithCloseIfOutsideTemperatureIsGreaterThan(28);

            bedroom.SetupAutomaticTurnOnAndOffAction()
                .WithTrigger(bedroom.MotionDetector(Bedroom.MotionDetector))
                .WithTarget(bedroom.Actuator<BinaryStateOutputActuator>(Bedroom.LightCeiling))
                .WithOnDuration(TimeSpan.FromSeconds(15))
                .WithTurnOnIfAllRollerShuttersClosed(bedroom.RollerShutter(Bedroom.RollerShutterLeft), bedroom.RollerShutter(Bedroom.RollerShutterRight))
                .WithEnabledAtNight(home.WeatherStation)
                .WithSkipIfAnyActuatorIsAlreadyOn(bedroom.Lamp(Bedroom.LampBedLeft), bedroom.Lamp(Bedroom.LampBedRight));
               
            var fanPort1 = hsrel8.GetOutput(0);
            var fanPort2 = hsrel8.GetOutput(1);
            var fanPort3 = hsrel8.GetOutput(2);
            var fan = bedroom.AddStateMachine(Bedroom.Fan);
            fan.AddOffState()
                .WithLowPort(fanPort1)
                .WithLowPort(fanPort2)
                .WithLowPort(fanPort3);
            fan.AddState("1").WithHighPort(fanPort1).WithLowPort(fanPort2).WithHighPort(fanPort3);
            fan.AddState("2").WithHighPort(fanPort1).WithHighPort(fanPort2).WithLowPort(fanPort3);
            fan.AddState("3").WithHighPort(fanPort1).WithHighPort(fanPort2).WithHighPort(fanPort3);
            fan.TurnOff();
            fan.ConnectMoveNextAndToggleOffWith(bedroom.Button(Bedroom.ButtonWindowLower));

            bedroom.Button(Bedroom.ButtonBedLeftInner).WithShortAction(() => bedroom.Lamp(Bedroom.LampBedLeft).Toggle());
            bedroom.Button(Bedroom.ButtonBedLeftInner).WithLongAction(() => bedroom.BinaryStateOutput(Bedroom.CombinedCeilingLights).Toggle());
            bedroom.Button(Bedroom.ButtonBedLeftOuter).WithShortAction(() => bedroom.StateMachine(Bedroom.Fan).ApplyNextState());
            bedroom.Button(Bedroom.ButtonBedLeftOuter).WithLongAction(() => bedroom.StateMachine(Bedroom.Fan).TurnOff());

            bedroom.Button(Bedroom.ButtonBedRightInner).WithShortAction(() => bedroom.Lamp(Bedroom.LampBedRight).Toggle());
            bedroom.Button(Bedroom.ButtonBedRightInner).WithLongAction(() => bedroom.BinaryStateOutput(Bedroom.CombinedCeilingLights).Toggle());
            bedroom.Button(Bedroom.ButtonBedRightOuter).WithShortAction(() => bedroom.StateMachine(Bedroom.Fan).ApplyNextState());
            bedroom.Button(Bedroom.ButtonBedRightOuter).WithLongAction(() => bedroom.StateMachine(Bedroom.Fan).TurnOff());
        }