예제 #1
0
 internal Brewery(string breweryMacAddress)
 {
     ID          = breweryMacAddress;
     RemoteState = new BreweryState();
     LastMessage = DateTime.Now;
     Settings    = new SettingsData();
 }
예제 #2
0
 private void breweryState_MessageReceived(BreweryState _breweryState)
 {
     if(_breweryState != breweryState)
     {
         breweryState = _breweryState;
         if (breweryState == BreweryState.HLT_Fill) { SessionTimer(); }
         StepTimer();
     }
 }
예제 #3
0
        public TimerViewModel()
        {
            // Initialize local variables
            breweryState = BreweryState.StandBy;
            sessionTime = new TimeSpan();
            sessionStartTime = new TimeSpan();
            stepStartTime = new TimeSpan();
            stepTime = new TimeSpan();

            // Register to incoming messages
            Messenger.Default.Register<BreweryState>(this, breweryState_MessageReceived);

            // Timer Initialisation
            UpdateTimer = new DispatcherTimer();

        }
예제 #4
0
        // Starts a Brew Session when the MenuSubItem : Start Session is selected
        private void startBrewSessionClickCommand()
        {
            // Verify brewery connection
            if (!brewery.IsConnected)
            {
                process.Session.StartRequested = true;
                connectionSetupClickCommand();
                return;
            }

            // Verify Session Status
            if (process.Session.IsStarted)
            {
                process.Session.StartRequested = false;
                process.Session.IsStarted = false;
                RaisePropertyChanged(StartSessionButtonContentPropertyName);
                UpdateTempSensorTimer.Stop();
                UpdateVolSensorTimer.Stop();
                return;
            }

            // Get recipe file if not chosen already
            if (process.Session.TotalWaterNeeded == 0)
            {
                process.Session.StartRequested = true;
                loadRecipeClickCommand();
                return;
            }

            // Set Session properties
            process.Session.IsStarted = true;
            process.Session.StartRequested = false;
            RaisePropertyChanged(StartSessionButtonContentPropertyName);

            // Check if Design Session and skip the sensor update timers if true
            if (DesignMode) { goto SkipDAQTimers; }

            // Setting Temperature Timer Properties
            UpdateTempSensorTimer.Interval = TimeSpan.FromMilliseconds(hardwareSettings.TempRefreshRate);
            UpdateTempSensorTimer.Tick += UpdateTempSensorTimer_Tick;
            UpdateTempSensorTimer.Start();

            // Setting Volume Timer Properties
            UpdateVolSensorTimer.Interval = TimeSpan.FromMilliseconds(hardwareSettings.VolResfreshRate);
            UpdateVolSensorTimer.Tick += UpdateVolSensorTimer_Tick;
            UpdateVolSensorTimer.Start();

        SkipDAQTimers:

            // Run state Machine
            breweryState = BreweryState.StandBy;
            RunAutoStateMachine();
        }
예제 #5
0
        private void RunAutoStateMachine()
        {
            switch(breweryState)
            {
                case BreweryState.StandBy:
                    {
                        if(process !=null)
                        {
                            // Set the fill and temp set point and send the data to the HLT view
                            brewery.HLT.Volume.SetPoint = process.Session.TotalWaterNeeded;
                            brewery.HLT.Temp.SetPoint = process.Strike.Temp;
                            brewery.HLT.Temp.SetPointReached = false;
                            brewery.HLT.Volume.SetPointReached = false;

                            Messenger.Default.Send<Brewery>(brewery, "HLTVolumeSetPointUpdate");
                            Messenger.Default.Send<Brewery>(brewery, "HLTVolumeSetPointReachedUpdate");
                            Messenger.Default.Send<Brewery>(brewery, "HLTTempSetPointUpdate");
                            Messenger.Default.Send<Brewery>(brewery, "HLTTempSetPointReachedUpdate");

                            if(!userAlarm.MessageSent) { PlayAlarm("", false, true, true); }
                            if(userAlarm.ProceedIsPressed)
                            {
                                breweryState = BreweryState.HLT_Fill;
                                RaisePropertyChanged(BreweryStateDisplayPropertyName);
                                userAlarm = new UserAlarm();
                            }
                        }
                        break;
                    }

                case BreweryState.HLT_Fill:
                    {
                        // Send User Alarm message to update the UserAction display text
                        if(!userAlarm.MessageSent) { PlayAlarm("", false, false, true); }

                        // Set the fill set point and send the data to the HLT view
                        brewery.HLT.Volume.SetPoint = process.Session.TotalWaterNeeded;
                        brewery.HLT.Temp.SetPoint = process.Strike.Temp;

                        Messenger.Default.Send<Brewery>(brewery, "HLTVolumeSetPointUpdate");
                        Messenger.Default.Send<Brewery>(brewery, "HLTTempSetPointUpdate");

                        // Check if HLT volume reached SetPoint
                        if(brewery.HLT.Volume.Value >= brewery.HLT.Volume.SetPoint)
                        {
                            // Set the SetPointReached property and send the data to the HLT view
                            brewery.HLT.Volume.SetPointReached = true;
                            Messenger.Default.Send<Brewery>(brewery, "HLTVolumeSetPointReachedUpdate");

                            // Go to Strike heat state
                            breweryState = BreweryState.Strike_Heat;
                            RaisePropertyChanged(BreweryStateDisplayPropertyName);
                            userAlarm = new UserAlarm();
                        }

                        break;
                    }

                case BreweryState.Strike_Heat:
                    {
                        // Send Message to light the pilots
                        if (!userAlarm.MessageSent) { PlayAlarm("Pilot", true, true, true); }

                        // Check for user confirmation of pilots
                        if(userAlarm.ProceedIsPressed)
                        {
                            // Get to HLT Set point and Hold
                            breweryCommand.HoldTemp(Vessels.HLT, process.Strike.Temp);
                        }

                        // Check if temperature range is reached
                        if (brewery.HLT.Temp.SetPointReached)
                        {
                            // Change State
                            breweryState = BreweryState.Strike_Transfer;
                            brewery.MLT.Volume.SetPointReached = false;
                            RaisePropertyChanged(BreweryStateDisplayPropertyName);
                            userAlarm = new UserAlarm();

                        }
                        break;
                    }

                case BreweryState.Strike_Transfer:
                    {
                        // Define SetPoint for initial MLT volume (dough in)
                        brewery.MLT.Volume.SetPoint = process.MashSteps[0].Volume;
                        Messenger.Default.Send<Brewery>(brewery, "MLTVolumeSetPointUpdate");
                        Messenger.Default.Send<Brewery>(brewery, "MLTVolumeSetPointReachedUpdate");

                        // Confirm the correct Valves operations are complete before starting the pump
                        if (!userAlarm.MessageSent) { PlayAlarm("Valves", true, true, true); }

                        // Hold Strike Temp
                        breweryCommand.HoldTemp(Vessels.HLT, process.Strike.Temp);

                        // If the user did not confirm, hold temperature and wait
                        if (!userAlarm.ProceedIsPressed)
                        {
                            return;
                        }

                        if (brewery.MLT.Volume.Value < brewery.MLT.Volume.SetPoint)
                        {
                            // Let a delay for pump priming if the pump is off and not primed
                            if (!brewery.Pump1.IsPrimed && !brewery.Pump1.IsOn && !brewery.Pump1.IsPriming)
                            {
                                StartPrimingDelay(1);
                                PlayAlarm("Priming", false, false, false);
                            }

                            // Else if pump is primed but off
                            else if (brewery.Pump1.IsPrimed && !brewery.Pump1.IsOn)
                            {
                                HLTStartVolume = brewery.HLT.Volume.Value;
                                breweryCommand.ActivatePump1(true);
                                PlayAlarm("Transfering", false, false, false);
                            }
                            // Update the transfered volume
                            else if(brewery.Pump1.IsOn)
                            {
                                brewery.MLT.Volume.Value = HLTStartVolume - brewery.HLT.Volume.Value;
                                Messenger.Default.Send<Brewery>(brewery, "MLTVolumeUpdate");
                            }
                        }
                        else
                        {
                            // Stop the transfer
                            if (brewery.Pump1.IsOn)
                            {
                                breweryCommand.ActivatePump1(false);
                            }

                            // Set the Volume Set point reached property
                            brewery.MLT.Volume.SetPointReached = true;
                            Messenger.Default.Send<Brewery>(brewery, "MLTVolumeSetPointReachedUpdate");

                            // Go to dough in state
                            breweryState = BreweryState.DoughIn;
                            RaisePropertyChanged(BreweryStateDisplayPropertyName);
                            userAlarm = new UserAlarm();
                        }
                        break;
                    }

                case BreweryState.DoughIn:
                    {
                        // Ask user to set the valves in recirculation mode and play alarm sound to request user action
                        if (RecirculationConfirmed) { goto SkipRecirculationAlarm; }

                        if (!userAlarm.MessageSent)
                        {
                            PlayAlarm("Recirculation", true, true, true);
                        }
                        else if(userAlarm.ProceedIsPressed)
                        {
                            RecirculationConfirmed = true;
                            userAlarm = new UserAlarm();
                        }

                    SkipRecirculationAlarm:

                        // Hold MLT temp at set point (dough in temp)
                        breweryCommand.HoldTemp(Vessels.MLT, process.Strike.Temp);

                        // Hold HLT temp at set point 
                        breweryCommand.HoldTemp(Vessels.HLT, process.Sparge.Temp);

                        // Check if the temperature is within range and set the SetPointReached property
                        if (brewery.MLT.Temp.SetPointReached)
                        {
                            // Ask user to dough in and confirm BEFORE putting the grains play alarm sound to request user action
                            if (!userAlarm.MessageSent && RecirculationConfirmed)
                            {
                                PlayAlarm("DoughIn", true, true, true);
                            }

                            // If user confirmed go to Mash step #1
                            if(userAlarm.ProceedIsPressed)
                            {
                                // Start the mash process
                                breweryCommand.LightBurner(Vessels.MLT, false);
                                breweryState = BreweryState.Mash;
                                RaisePropertyChanged(BreweryStateDisplayPropertyName);
                                userAlarm = new UserAlarm();
                            }
                        }
                        break;
                    }

                case BreweryState.Mash:
                    {
                        // If first iteration start mash timer
                        if(FirstMashStep)
                        {
                            // Get the step start and end time
                            StepStartTime = DateTime.Now.TimeOfDay;
                            StepEndTime = StepStartTime.Add(TimeSpan.FromMinutes(process.MashSteps[step].Time));

                            // Start the step timer
                            MashStepTimer.Interval = TimeSpan.FromMilliseconds(500);
                            MashStepTimer.Tick += MashStepTimer_Tick;
                            MashStepTimer.Start();
                            FirstMashStep = false;
                        }

                        // If the mash step is completed increment
                        if(MashStepComplete)
                        {
                            // Set the new mash step as incomplete
                            MashStepComplete = false;

                            // Check if all steps are completed
                            if (process.MashSteps.Count <= step+1)
                            {
                                breweryState = BreweryState.Sparge;
                                RaisePropertyChanged(BreweryStateDisplayPropertyName);
                                userAlarm = new UserAlarm();
                                return;
                            }

                            // Get the step start and end time
                            StepStartTime = DateTime.Now.TimeOfDay;
                            StepEndTime = StepStartTime.Add(TimeSpan.FromMinutes(process.MashSteps[step].Time));

                            // Start the step timer
                            MashStepTimer.Interval = TimeSpan.FromMilliseconds(500);
                            MashStepTimer.Tick += MashStepTimer_Tick;
                            MashStepTimer.Start();
                        }

                        // Hold HLT temp set point at mash step temp
                        breweryCommand.HoldTemp(Vessels.MLT, process.MashSteps[step].Temp);

                        // Hold HLT temp at sparge temp
                        breweryCommand.HoldTemp(Vessels.HLT, process.Sparge.Temp);

                        // Start recirculating
                        if(!brewery.Pump2.IsPrimed && !brewery.Pump2.IsPriming)
                        {
                            StartPrimingDelay(2);
                        }
                        else if(brewery.Pump2.IsPrimed && !brewery.Pump2.IsOn)
                        {
                            breweryCommand.ActivatePump2(true);
                        }

                        break;
                    }

                case BreweryState.Sparge:
                    {
                        // Send Sparging Message
                        if(!userAlarm.MessageSent && !SpargeModeOn)
                        {
                            PlayAlarm("ValveSpargeMode", false, false, true);
                            breweryCommand.ActivatePump2(false);
                            SpargeModeOn = true;
                            userAlarm = new UserAlarm();
                        }

                        // Hold HLT at Sparge Temp
                        breweryCommand.HoldTemp(Vessels.HLT, process.Sparge.Temp);

                        // If HLT temp is in range then start the pumps
                        if(brewery.HLT.Temp.SetPointReached && userAlarm.ProceedIsPressed && (!brewery.Pump1.IsOn || !brewery.Pump2.IsOn) && FirstSparge)
                        {
                            // Save the HLT Start Volume and start the pumps
                            HLTStartVolume = brewery.HLT.Volume.Value;
                            breweryCommand.ActivatePump1(true);
                            breweryCommand.ActivatePump2(true);
                            FirstSparge = false;

                            // Turn off MLT Temp monitoring
                            breweryCommand.HoldTemp(Vessels.MLT, 0);

                            // Set The HLT Volume Set Point and save the MLT Start Volume
                            MLTStartVolume = brewery.MLT.Volume.Value;
                            brewery.HLT.Volume.SetPoint = HLTStartVolume - process.Sparge.Volume;
                            if (brewery.HLT.Volume.SetPoint < 0) { brewery.HLT.Volume.SetPoint = 0; }
                            brewery.HLT.Volume.SetPointReached = false;
                            Messenger.Default.Send<Brewery>(brewery, "HLTVolumeSetPointUpdate");
                            Messenger.Default.Send<Brewery>(brewery, "HLTVolumeSetPointReachedUpdate");

                            // Set the BK volume Set Point
                            brewery.BK.Volume.SetPoint = process.Boil.Volume;
                            brewery.BK.Volume.SetPointReached = false;
                            Messenger.Default.Send<Brewery>(brewery, "BKVolumeSetPointUpdate");
                            Messenger.Default.Send<Brewery>(brewery, "BKVolumeSetPointReachedUpdate");
                        }

                        // Update the MLT volume based on the HLT volume pumped out and set the Volume Set Points
                        brewery.MLT.Volume.Value = MLTStartVolume + HLTStartVolume - brewery.HLT.Volume.Value - brewery.BK.Volume.Value;
                        Messenger.Default.Send<Brewery>(brewery, "MLTVolumeUpdate");
                        
                        // Monitor HLT Sparge volume
                        if (brewery.HLT.Volume.Value <= HLTStartVolume-process.Sparge.Volume)
                        {
                            if (brewery.Pump1.IsOn)
                            {
                                breweryCommand.ActivatePump1(false);
                            }

                            if(brewery.HLT.Volume.Value <= 10 && brewery.HLT.Burner.IsOn)
                            {
                                breweryCommand.LightBurner(Vessels.HLT, false);
                                brewery.HLT.Temp.SetPointReached = false;
                                Messenger.Default.Send<Brewery>(brewery, "HLTTempSetPointReachedUpdate");
                            }

                            brewery.HLT.Volume.SetPointReached = true;
                            Messenger.Default.Send<Brewery>(brewery, "HLTVolumeSetPointReachedUpdate");
                        }

                        // Check if sparge water is missing and send alarm
                        else if (brewery.HLT.Volume.SetPoint == 0 && brewery.HLT.Volume.Value == 0 && !userAlarm.MessageSent)
                        {
                            // Send alarm to indicate forced continue and initial water level was low
                            PlayAlarm("MissingSpargeWater", true, true, false, process.Sparge.Volume - HLTStartVolume);

                            if (brewery.Pump1.IsOn)
                            {
                                breweryCommand.ActivatePump1(false);
                            }

                            if (brewery.HLT.Volume.Value <= 10 && brewery.HLT.Burner.IsOn)
                            {
                                breweryCommand.LightBurner(Vessels.HLT, false);
                                brewery.HLT.Temp.SetPointReached = false;
                                Messenger.Default.Send<Brewery>(brewery, "HLTTempSetPointReachedUpdate");
                            }

                            brewery.HLT.Volume.SetPointReached = true;
                            Messenger.Default.Send<Brewery>(brewery, "HLTVolumeSetPointReachedUpdate");
                        }

                        // Monitor BK Volume if over 10 start heating
                        if(brewery.BK.Volume.Value>= 10 && !brewery.BK.Burner.IsOn)
                        {
                            breweryCommand.HoldTemp(Vessels.BK, 100);
                        }

                        // Monitor Bk Volume for process target
                        if(brewery.BK.Volume.Value >= process.Boil.Volume)
                        {
                            if (brewery.Pump2.IsOn)
                            {
                                breweryCommand.ActivatePump2(false);
                            }

                            brewery.BK.Volume.SetPointReached = true;

                            // Switch to boil state
                            breweryState = BreweryState.Boil;
                            RaisePropertyChanged(BreweryStateDisplayPropertyName);
                            userAlarm = new UserAlarm();
                            Messenger.Default.Send<Brewery>(brewery, "BKVolumeSetPointReachedUpdate");
                        }

                        break;
                    }

                case BreweryState.Boil:
                    {
                        // Hold boil temp in BK
                        breweryCommand.HoldTemp(Vessels.BK, 100);

                        // Monitor BK and send an alarm to warn boil over
                        if (brewery.BK.Temp.Value>=97 && !BoilOverSent)
                        {
                            // Send Boil Over Message
                            if (!userAlarm.MessageSent)
                            {
                                PlayAlarm("BoilOver", true, true, false);
                                BoilOverSent = true;
                                userAlarm = new UserAlarm();
                            }
                        }

                        // Boil is reached
                        if (brewery.BK.Temp.Value >= 99.5)
                        {
                            brewery.BK.Temp.BoilReached = true;
                        }

                        // Start Boil Timer if Boil is Reached
                        if(brewery.BK.Temp.BoilReached && !BoilTimer.IsEnabled && !BoilComplete)
                        { 
                            // Get the step start and end time
                            BoilStartTime = DateTime.Now.TimeOfDay;
                            BoilEndTime = StepStartTime.Add(TimeSpan.FromMinutes(process.Boil.Time));

                            // Start the step timer
                            BoilTimer.Interval = TimeSpan.FromMilliseconds(500);
                            BoilTimer.Tick += BoilTimer_Tick;
                            BoilTimer.Start();
                        }

                        // Check if boil is complete
                        if(BoilComplete)
                        {
                            // Turn off BK burner
                            breweryCommand.HoldTemp(Vessels.BK, 0);

                            // Switch to Chill State
                            breweryState = BreweryState.Chill;
                            RaisePropertyChanged(BreweryStateDisplayPropertyName);
                            userAlarm = new UserAlarm();
                        }

                        break;
                    }

                case BreweryState.Chill:
                    {
                        // Send chill temperature info
                        if (!userAlarm.MessageSent)
                        {
                            PlayAlarm("Chill", true, true, false);
                            breweryState = BreweryState.Fermenter_Transfer;
                            userAlarm = new UserAlarm();
                        }
                        break;
                    }

                case BreweryState.Fermenter_Transfer:
                    { 
                        // Monitor BK Level
                        if(brewery.BK.Volume.Value == 0)
                        {
                            PlayAlarm("Ferment", false, false, false);
                            UpdateTempSensorTimer.Stop();
                            UpdateVolSensorTimer.Stop();
                            breweryCommand.Disconnect();
                        }

                        break;
                    }
            }
        }
예제 #6
0
        // MainViewModel Class Constructor
        public MainViewModel()
        {
            // Creating new instance of model
            breweryCommand = new BreweryCommands();
            hardwareSettings = new HardwareSettings();
            brewery = new Brewery();
            process = new Process();
            probes = new Probes();
            userAlarm = new UserAlarm(); 

            // Initializing RelayCommand Instances
            ConnectionSetupClickCommand = new RelayCommand(connectionSetupClickCommand);
            HardwareSetupClickCommand = new RelayCommand(hardwareSetupClickCommand);
            StartBrewSessionClickCommand = new RelayCommand(startBrewSessionClickCommand);
            MainClosingCommand = new RelayCommand(mainClosing);
            LoadRecipeClickCommand = new RelayCommand(loadRecipeClickCommand);
            DebugDesignSessionClickCommand = new RelayCommand(debugDesignClickCommand);

            // Initializing Timers
            UpdateTempSensorTimer = new DispatcherTimer();
            UpdateVolSensorTimer = new DispatcherTimer();
            AlarmTimer = new DispatcherTimer();
            PrimingTimer = new DispatcherTimer();
            MashStepTimer = new DispatcherTimer();
            BoilTimer = new DispatcherTimer();

            // Initializing Sound Player
            Player = new MediaPlayer();

            // Initializing Machine State Variables
            MashStepComplete = false;
            FirstMashStep = true;
            FirstSparge = true;
            SpargeModeOn = false;
            BoilOverSent = false;
            BoilComplete = false;
            StepStartTime = new TimeSpan();
            RemainingTime = new TimeSpan();
            StepEndTime = new TimeSpan();

            // Initializing the brewery State
            breweryState = BreweryState.StandBy;
            RaisePropertyChanged(BreweryStateDisplayPropertyName);

            // Initializing Messenger Registers
            Messenger.Default.Register<NotificationMessage>(this, "BreweryCommand", BreweryCommand_MessageReceived);
            Messenger.Default.Register<Brewery>(this, "ConnectionUpdate" , ConnectionUpdate_MessageReceived);
            Messenger.Default.Register<HardwareSettings>(this, "HardwareSettingsUpdate", HardwareSettings_MessageReceived);
            Messenger.Default.Register<Brewery>(this, "TemperatureUpdate", TemperatureUpdate_MessageReceived);
            Messenger.Default.Register<Brewery>(this, "VolumeUpdate", VolumeUpdate_MessageReceived);
            Messenger.Default.Register<Brewery>(this, "HLTBurnerUpdate", HLTBurnerUpdate_MessageReceived);
            Messenger.Default.Register<Brewery>(this, "MLTBurnerUpdate", MLTBurnerUpdate_MessageReceived);
            Messenger.Default.Register<Brewery>(this, "BKBurnerUpdate", BKBurnerUpdate_MessageReceived);
            Messenger.Default.Register<Brewery>(this, "Pump1Update", Pump1Update_MessageReceived);
            Messenger.Default.Register<Brewery>(this, "Pump2Update", Pump2Update_MessageReceived);
            Messenger.Default.Register<string>(this, "SelectedcomPort", SelectedcomPort_MessageReceived);
            Messenger.Default.Register<Process>(this, Process_MessageReceived);
            Messenger.Default.Register<Probes>(this, "GetConnectedProbes", GetConnectedProbes_MessageReceived);
            Messenger.Default.Register<UserAlarm>(this, "UserAlarmReturn", UserAlarmReturn_MessageReceived);
            Messenger.Default.Register<Brewery>(this, "HLTTempSetPointUpdate", HLTTempSetPointUpdate_MessageReceived);
            Messenger.Default.Register<Brewery>(this, "MLTTempSetPointUpdate", MLTTempSetPointUpdate_MessageReceived);
            Messenger.Default.Register<Brewery>(this, "BKTempSetPointUpdate", BKTempSetPointUpdate_MessageReceived);
            Messenger.Default.Register<Brewery>(this, "HLTTempSetPointReachedUpdate", HLTTempSetPointReachedUpdate_MessageReceived);
            Messenger.Default.Register<Brewery>(this, "MLTTempSetPointReachedUpdate", MLTTempSetPointReachedUpdate_MessageReceived);
            Messenger.Default.Register<Brewery>(this, "BKTempSetPointReachedUpdate", BKTempSetPointReachedUpdate_MessageReceived);
        }