예제 #1
0
 def onEnter(self):
     self.__durationSeconds = self.configuration['pedestrianTimer']
     self.logger.info('Pedestrian crossing initialized')
     sendNotification(NotificationLevel.INFO, 'Pedestrians can now cross',
                      {'pedestriansCrossing': True})
     self.__nextLightState = self.engine.nextLightDirection + '_green'
     self.__startTimeSeconds = time.time()
예제 #2
0
    def __tryExecuteStateTransition(self):
        '''
        (Internal, for engine use only)
        
        This internal method will actually transition the state machine
        into the state that was requested by 'gotoState'.

        If we are in 'state stepper mode', we will first pause the machine.
        '''
        if self.__nextRequestedState == None:
            return False

        if self.__inStateStepperMode and not self.__hasPausedForStepper:
            self.pause()
            self.__hasPausedForStepper = True
            return True # Return True so that we can get a clean update loop

        self.__hasPausedForStepper = False # We have paused for the stepper at this point, so let's reset it

        if not self.__currentState == None:
            prevState = self.getCurrentState()
            if prevState != None:
                prevState.onLeave()
                prevState.freeCallbacks()

        sendNotification(NotificationLevel.APP_STATE_CHANGE, 'Entered MachineApp state: {}'.format(self.__nextRequestedState))
        self.__currentState = self.__nextRequestedState
        self.__nextRequestedState = None
        nextState = self.getCurrentState()

        if nextState != None:
            nextState.onEnter()

        return True
예제 #3
0
    def __mqttEventCallback(self, topic, msg):
        topicParts = topic.split('/')
        deviceType = topicParts[1]
        if deviceType != 'io-expander':
            return

        if (topicParts[3] == 'available'):
            return

        isInput = False
        if topicParts[3] == 'digital-output':
            isInput = False
        elif topicParts[3] == 'digital-input':
            isInput = True

        device = int(topicParts[2])
        pin = int(topicParts[4])
        value = msg

        for monitorItem in self.__monitorList:
            if monitorItem.isEqual(isInput, device, pin):
                monitorItem.state = value
                sendNotification(NotificationLevel.IO_STATE, '',
                                 monitorItem.toJson())
                break
예제 #4
0
    def onEnter(self):
        self.logger.info('{} direction entered the RED light state'.format(
            self.__direction))
        sendNotification(
            NotificationLevel.INFO,
            'Set light to RED for {} conveyor'.format(self.__direction), {
                "direction": self.__direction,
                "color": 'red',
                "speed": 0
            })

        self.__startTimeSeconds = time.time()
예제 #5
0
    def onEnter(self):
        self.__startTimeSeconds = time.time()
        self.logger.info('{} direction entered the YELLOW light state'.format(
            self.__direction))
        sendNotification(
            NotificationLevel.INFO,
            'Set light to YELLOW for {} conveyor'.format(self.__direction), {
                "direction": self.__direction,
                "color": 'yellow',
                "speed": self.__speed
            })

        def __onPedestrianButtonClicked(topic, msg):
            if msg == 'true':
                self.engine.isPedestrianButtonTriggered = True
                self.engine.nextLightDirection = 'vertical' if self.__direction == 'horizontal' else 'horizontal'

        self.registerCallback(self.engine.primaryMachineMotion,
                              'push_button_1', __onPedestrianButtonClicked)

        self.__machineMotion.setContinuousMove(self.__axis, self.__speed)
예제 #6
0
    def onEnter(self):
        self.logger.info('{} direction entered the GREEN light state'.format(
            self.__direction))

        # Record the time that we entered this state
        self.__startTimeSeconds = time.time()

        # Inform the frontend's console that we've entered this state. See Notifier::sendMessage for more information
        # on the parameters defined here.
        sendNotification(
            NotificationLevel.INFO,
            'Set light to GREEN for {} conveyor'.format(self.__direction), {
                "direction": self.__direction,
                "color": 'green',
                "speed": self.__speed
            })

        # Register a callback that gets set when the push button is clicked
        def __onPedestrianButtonClicked(topic, msg):
            if msg == 'true':
                self.engine.isPedestrianButtonTriggered = True
                self.engine.nextLightDirection = 'vertical' if self.__direction == 'horizontal' else 'horizontal'
                self.gotoState(self.__direction + '_yellow')

        # Register to listen to the hardware IO (like a push button)...
        self.registerCallback(self.engine.primaryMachineMotion,
                              'push_button_1', __onPedestrianButtonClicked)
        # Or register to listern to the software IO (like a button in your web page)!
        self.registerCallbackOnTopic(self.engine.primaryMachineMotion,
                                     'software_button',
                                     __onPedestrianButtonClicked)

        # Set the axis moving
        self.__machineMotion.setContinuousMove(self.__axis, self.__speed)
        sendNotification(
            NotificationLevel.INFO,
            'Green light with axis={}, speed={}'.format(
                self.__axis, self.__speed))
예제 #7
0
    def loop(self, inStateStepperMode, configuration):
        '''
        Main loop of your MachineApp.
        '''
        if self.__isRunning:
            return False

        sendNotification(NotificationLevel.APP_START, 'MachineApp started')
        self.logger.info('Starting the main MachineApp loop')

        # Configure run time variables
        self.__inStateStepperMode = inStateStepperMode
        self.configuration = configuration
        self.__isRunning = True

        # Run initialization sequence
        self.initialize()
        self.__stateDictionary = self.buildStateDictionary()

        # Begin the Application by moving to the default state
        self.gotoState(self.getDefaultState())

        # Inner Loop running the actual MachineApp program
        while self.__isRunning:
            if self.__shouldStop:  # Running stop behavior
                self.__shouldStop = False
                self.__isRunning = False

                self.onStop()

                currentState = self.getCurrentState()
                if currentState != None:
                    currentState.onStop()

                break

            if self.__shouldPause:  # Running pause behavior
                if self.__hasPausedForStepper:
                    sendNotification(
                        NotificationLevel.APP_PAUSE,
                        'Paused for stepper mode: Moving from {} state to {} state'
                        .format(self.__currentState,
                                self.__nextRequestedState))
                else:
                    sendNotification(NotificationLevel.APP_PAUSE,
                                     'MachineApp paused')

                self.__shouldPause = False
                self.__isPaused = True

                if not self.__hasPausedForStepper:  # Only do pause behavior if we're not doing the stepper-mandated pause
                    self.onPause()

                    currentState = self.getCurrentState()
                    if currentState != None:
                        currentState.onPause()

            if self.__shouldResume:  # Running resume behavior
                sendNotification(NotificationLevel.APP_RESUME,
                                 'MachineApp resumed')
                self.__shouldResume = False
                self.__isPaused = False

                if not self.__hasPausedForStepper:  # Only do resume behavior if we're not doing the stepper-mandated pause
                    self.onResume()

                    currentState = self.getCurrentState()
                    if currentState != None:
                        currentState.onResume()

            if self.__isPaused:  # While paused, don't do anything
                time.sleep(BaseMachineAppEngine.UPDATE_INTERVAL_SECONDS)
                continue

            if self.__nextRequestedState != None:  # Running state transition behavior
                if self.__tryExecuteStateTransition():
                    continue  # If the transition is executed successfully, let's get a clean update loop

            currentState = self.getCurrentState()
            if currentState == None:
                self.logger.error('Currently in an invalid state')
                continue

            currentState.updateCallbacks()
            currentState.update()

            time.sleep(BaseMachineAppEngine.UPDATE_INTERVAL_SECONDS)

        self.logger.info('Exiting MachineApp loop')
        sendNotification(NotificationLevel.APP_COMPLETE,
                         'MachineApp completed')
        self.afterRun()
        return True
예제 #8
0
 def onLeave(self):
     sendNotification(NotificationLevel.INFO,
                      'Pedestrians can NOT cross anymore',
                      {'pedestriansCrossing': False})
     self.engine.isPedestrianButtonTriggered = False
예제 #9
0
 def onEnter(self):
     self.engine.primaryMachineMotion.emitSpeed(25)
     self.engine.primaryMachineMotion.emitCombinedAxisRelativeMove(
         [1, 2], ['positive', 'positive'], [250, 250])
     sendNotification(NotificationLevel.INFO,
                      'Moving to the start position')
예제 #10
0
 def onEnter(self):
     self.engine.primaryMachineMotion.emitHomeAll()
     sendNotification(NotificationLevel.INFO, 'Moving to home')
     self.gotoState('horizontal_green')