FishTank.cpp
/** * (c)2017 CDP Technologies AS */ #include "FishTank.h" using namespace TankControlLib; FishTank::FishTank() : m_feedingInitialized(false) { } FishTank::~FishTank() { } void FishTank::Create(const char* fullName) { CDPComponent:: Create(fullName); FeedingInProgress.Create("FeedingInProgress",this); AlarmLevelLow.Create("AlarmLevelLow",this); AlarmLevelExtremeLow.Create("AlarmLevelExtremeLow",this); MaxValue.Create("MaxValue",this); FillingSpeed.Create("FillingSpeed",this); FillScrewActive.Create("FillScrewActive",this); AlarmLow.Create("AlarmLow",this); AlarmExtremeLow.Create("AlarmExtremeLow",this); BlowerActive.Create("BlowerActive",this); TankLevel.Create("TankLevel",this); ScrewSpeed.Create("ScrewSpeed",this); FillAmount.Create("FillAmount",this); FeedAmount.Create("FeedAmount",this); RemainingTime.Create("RemainingTime",this); StartTime.Create("StartTime",this); ScrewActive.Create("ScrewActive",this); PauseButton.Create("PauseButton",this); MaxLevelAlarm.Create("MaxLevelAlarm",this); TimeFeeded.Create("TimeFeeded",this); AlarmStatus.Create("AlarmStatus",this); } void FishTank::CreateModel() { CDPComponent::CreateModel(); RegisterStateProcess("Null",(CDPCOMPONENT_STATEPROCESS)&FishTank::ProcessNull,"Initial Null state"); RegisterStateProcess("Filling",(CDPCOMPONENT_STATEPROCESS)&FishTank::ProcessFilling,"Fill up the tank with the desired amount of food"); RegisterStateProcess("Feeding",(CDPCOMPONENT_STATEPROCESS)&FishTank::ProcessFeeding,"System will start feeding"); RegisterStateProcess("FeedingStopped",(CDPCOMPONENT_STATEPROCESS)&FishTank::ProcessFeedingStopped,"Feeding and filling are both stopped"); RegisterStateProcess("AutoStarting",(CDPCOMPONENT_STATEPROCESS)&FishTank::ProcessAutoStarting,"Waiting to start after a given time delay"); RegisterStateTransitionHandler("Feeding","FeedingStopped",(CDPCOMPONENT_STATETRANSITIONHANDLER)&FishTank::TransitionFeedingToFeedingStopped,""); RegisterStateTransitionHandler("AutoStarting","Feeding",(CDPCOMPONENT_STATETRANSITIONHANDLER)&FishTank::TransitionAutoStartingToFeeding,""); RegisterStateTransitionHandler("FeedingStopped","Filling",(CDPCOMPONENT_STATETRANSITIONHANDLER)&FishTank::TransitionFeedingStoppedToFilling,""); RegisterStateTransitionHandler("Filling","FeedingStopped",(CDPCOMPONENT_STATETRANSITIONHANDLER)&FishTank::TransitionFillingToFeedingStopped,""); RegisterStateTransitionHandler("FeedingStopped","Feeding",(CDPCOMPONENT_STATETRANSITIONHANDLER)&FishTank::TransitionFeedingStoppedToFeeding,""); RegisterStateTransitionHandler("FeedingStopped","AutoStarting",(CDPCOMPONENT_STATETRANSITIONHANDLER)&FishTank::TransitionFeedingStoppedToAutoStarting,""); RegisterStateTransitionHandler("AutoStarting","FeedingStopped",(CDPCOMPONENT_STATETRANSITIONHANDLER)&FishTank::TransitionAutoStartingToFeedingStopped,""); RegisterStateTransitionHandler("Null","FeedingStopped",(CDPCOMPONENT_STATETRANSITIONHANDLER)&FishTank::TransitionNullToFeedingStopped,""); RegisterMessage(CM_TEXTCOMMAND,"AutoStartFeeding","",(CDPOBJECT_MESSAGEHANDLER)&FishTank::MessageAutoStartFeeding); RegisterMessage(CM_TEXTCOMMAND,"StartFeeding","",(CDPOBJECT_MESSAGEHANDLER)&FishTank::MessageStartFeeding); RegisterMessage(CM_TEXTCOMMAND,"Stop","",(CDPOBJECT_MESSAGEHANDLER)&FishTank::MessageStop); RegisterMessage(CM_TEXTCOMMAND,"StartFilling","",(CDPOBJECT_MESSAGEHANDLER)&FishTank::MessageStartFilling); RegisterMessage(CM_TEXTCOMMAND,"SpeedUp","",(CDPOBJECT_MESSAGEHANDLER)&FishTank::MessageSpeedUp); RegisterMessage(CM_TEXTCOMMAND,"SpeedDown","",(CDPOBJECT_MESSAGEHANDLER)&FishTank::MessageSpeedDown); } void FishTank::Configure(const char* componentXML) { CDPComponent::Configure(componentXML); } void FishTank::processAlarms() { MaxLevelAlarm = TankLevel >= (MaxValue * 0.999); AlarmLow = TankLevel <= AlarmLevelLow; AlarmExtremeLow = TankLevel <= AlarmLevelExtremeLow; AlarmStatus = 0; if(MaxLevelAlarm) AlarmStatus = 3; else if(AlarmExtremeLow) AlarmStatus = 1; else if(AlarmLow) AlarmStatus = 2; } void FishTank::ProcessNull() { } void FishTank::ProcessFilling() { if (FillAmount <= 0) { FillAmount = 0; FillScrewActive = false; requestedState = "FeedingStopped"; } else if (TankLevel >= MaxValue) { TankLevel = MaxValue; FillScrewActive = false; requestedState = "FeedingStopped"; } else { FillScrewActive = true; TankLevel = TankLevel + FillingSpeed/GetFrequency(); FillAmount = FillAmount - FillingSpeed/GetFrequency(); processAlarms(); } } void FishTank::ProcessFeeding() { if (TankLevel <= 0) { TankLevel = 0; FeedingInProgress = false; ScrewActive = false; m_feedingInitialized = false; requestedState = "FeedingStopped"; return; } else if (FeedAmount <= 0) { FeedAmount = 0; FeedingInProgress = false; ScrewActive = false; m_feedingInitialized = false; requestedState = "FeedingStopped"; return; } if (!m_feedingInitialized) { TimeFeeded = 0; m_feedingInitialized = true; } FeedingInProgress = true; TimeFeeded = TimeFeeded + 1.0/GetFrequency(); if (PauseButton) { ScrewActive = false; return; } ScrewActive = true; RemainingTime = (FeedAmount/ScrewSpeed); TankLevel = TankLevel - ScrewSpeed/GetFrequency(); if (TankLevel<0) TankLevel = 0; FeedAmount = FeedAmount - ScrewSpeed/GetFrequency(); if (FeedAmount<0) FeedAmount = 0; processAlarms(); } void FishTank::ProcessFeedingStopped() { FillScrewActive = false; ScrewActive = false; FeedingInProgress = false; RemainingTime = (FeedAmount/ScrewSpeed); processAlarms(); } void FishTank::ProcessAutoStarting() { if (StartTime > 0) StartTime = StartTime - 1.0/GetFrequency(); else { StartTime = 0; requestedState = "Feeding"; } } bool FishTank::TransitionFeedingToFeedingStopped() { return requestedState=="FeedingStopped"; } bool FishTank::TransitionAutoStartingToFeeding() { return requestedState=="Feeding"; } bool FishTank::TransitionFeedingStoppedToFilling() { return requestedState=="Filling"; } bool FishTank::TransitionFillingToFeedingStopped() { return requestedState=="FeedingStopped"; } bool FishTank::TransitionFeedingStoppedToFeeding() { return requestedState=="Feeding"; } bool FishTank::TransitionFeedingStoppedToAutoStarting() { return requestedState=="AutoStarting"; } bool FishTank::TransitionAutoStartingToFeedingStopped() { return requestedState=="FeedingStopped"; } bool FishTank::TransitionNullToFeedingStopped() { return true; } int FishTank::MessageAutoStartFeeding(void* /*message*/) { requestedState="AutoStarting"; return 1; } int FishTank::MessageStartFeeding(void* /*message*/) { requestedState="Feeding"; return 1; } int FishTank::MessageStop(void* /*message*/) { requestedState="FeedingStopped"; return 1; } int FishTank::MessageStartFilling(void* /*message*/) { requestedState="Filling"; return 1; } int FishTank::MessageSpeedUp(void* /*message*/) { if (ScrewSpeed < 5) ScrewSpeed = ScrewSpeed + 0.5; return 1; } int FishTank::MessageSpeedDown(void* /*message*/) { if (ScrewSpeed > 0.5) ScrewSpeed = ScrewSpeed - 0.5; return 1; }
Get started with CDP Studio today
Let us help you take your great ideas and turn them into the products your customer will love.