示例#1
0
    def __init__(self):
        """Initialise the bentv_ui class - reads the configuration file
        and initialises the screen and GPIO monitor"""
        print "bentv.__init__()"
        configPath = "%s/%s" % (os.path.dirname(
            os.path.realpath(__file__)), self.configFname)
        print configPath
        self.cfg = ConfigUtil(configPath, self.configSection)

        self.debug = self.cfg.getConfigBool("debug")
        if (self.debug): print "Debug Mode"

        self.debounce_ms = self.cfg.getConfigInt("debounce_ms")
        self.shortpress_ms = self.cfg.getConfigInt("shortpress_ms")

        self.hostname, self.ipaddr = self.getHostName()
        print self.hostname, self.ipaddr
        self.timeDown = 0.0
        self.presetNo = 1
        self.shortPress = False
        self.longPress = False
        self.initScreen()
        self.initGPIO()
        self.UIMode = self.CAMERA_MODE  # Next line changes mode to start in
        # FITDECT_MODE.
        self.changeUIMode()  # Initialises the messages.
    def __init__(self):
        """Initialise the bentv_ui class - reads the configuration file
        and initialises the screen and GPIO monitor"""
        print "bentv.__init__()"
        configPath = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)),
                                self.configFname)
        print configPath
        self.cfg = ConfigUtil(configPath,self.configSection)

        self.debug = self.cfg.getConfigBool("debug")
        if (self.debug): print "Debug Mode"
        
        self.debounce_ms = self.cfg.getConfigInt("debounce_ms")
        self.shortpress_ms = self.cfg.getConfigInt("shortpress_ms")
        
        self.hostname, self.ipaddr = self.getHostName()
        print self.hostname, self.ipaddr
        self.timeDown = 0.0
        self.presetNo = 1
        self.shortPress = False
        self.longPress = False
        self.initScreen()
        self.initGPIO()
        self.UIMode = self.CAMERA_MODE  # Next line changes mode to start in
                                        # FITDECT_MODE.
        self.changeUIMode()  # Initialises the messages.
示例#3
0
    def __init__(self):
        """Initialise the bentv_ui class - reads the configuration file
        and initialises the screen and GPIO monitor"""
        print "bentv.__init__()"
        configPath = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)),
                                self.configFname)
        print configPath
        self.cfg = ConfigUtil(configPath,self.configSection)

        self.debug = self.cfg.getConfigBool("debug")
        if (self.debug): print "Debug Mode"
        
        self.hostname, self.ipaddr = self.getHostName()
        print self.hostname, self.ipaddr
        self.presetNo = 1
        self.initScreen()
        self.initGPIO()
示例#4
0
    def __init__(self,port = None):
        print "runServer.__init__()"
        print os.path.realpath(__file__)
        configPath = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)),
                                self.configFname)
        print configPath
        self.cfg = ConfigUtil(configPath,self.configSection)

        self.debug = self.cfg.getConfigBool("debug")
        if (self.debug): print "Debug Mode"

        self._wkdir = self.cfg.getConfigStr("working_directory")
        if (self.debug): print "working_directory=%s\n" % self._wkdir
        self._tmpdir = self.cfg.getConfigStr("tmpdir")
        if (self.debug): print "tmpdir=%s\n" % self._tmpdir


        if (port == None):
            port = '/dev/ttyUSB0'
        print "Opening Serial Connection on %s" % port
        self.ser = serial.Serial(port,9600,timeout=1)
        print "Waiting for serial comms to settle..."
        time.sleep(2)
        print "Reading first line of data, and ignoring it."
        line = self.ser.readline() # throw away any part lines
        print "line=%s" % line

        self.start()
        print "waiting for some data..."
        while(self.ser.inWaiting() < 10): 
            print "waiting - inWaiting()=%d" % self.ser.inWaiting()
            time.sleep(1)
        print "wait over!"
        print "ignoring a few lines for start command to register..."
        for n in range(0,5):
            line = self.ser.readline() # throw away any part lines
            print "line=%s" % line
    
        #Initialise data lists.
        self.t=[] # initialize the data lists
        self.d1=[]
        self.d2=[]
        self.d3=[]
        self.d4=[]
        self.d5=[]
        self.d6=[]


        # Start web server
        self._ws = webServer.WebServer(self)
        webServer.setRoutes(self._ws)

        # Run our main loop.
        self.run()
示例#5
0
    def __init__(self, save=False, inFile=None):
        print "benFinder.__init__()"
        print os.path.realpath(__file__)
        configPath = "%s/%s" % (os.path.dirname(
            os.path.realpath(__file__)), self.configFname)
        print configPath
        self.cfg = ConfigUtil(configPath, self.configSection)

        self.debug = self.cfg.getConfigBool("debug")
        if (self.debug): print "Debug Mode"

        self._wkdir = self.cfg.getConfigStr("working_directory")
        if (self.debug): print "working_directory=%s\n" % self._wkdir
        self._tmpdir = self.cfg.getConfigStr("tmpdir")
        if (self.debug): print "tmpdir=%s\n" % self._tmpdir

        # Check if we are running from live kinect or a file.
        if (inFile):
            device = depth.CV_CAP_FILE
        else:
            device = depth.CV_CAP_FREENECT

        # Initialise the captureManager
        self._captureManager = CaptureManager(device,
                                              None,
                                              True,
                                              inFile=inFile)
        self._captureManager.channel = depth.CV_CAP_OPENNI_DEPTH_MAP

        # If we are runnign from a file, use the first frame as the
        # background image.
        if (inFile):
            self.saveBgImg()

        # If we have asked to save the background image, do that, and exit,
        # otherwise initialise the seizure detector.
        if (save):
            self.saveBgImg()
        else:
            self.loadBgImg()
            self.autoBackgroundImg = None
            self._status = self.ALARM_STATUS_OK
            self._ts = TimeSeries(
                tslen=self.cfg.getConfigInt("timeseries_length"))
            self._frameCount = 0
            self._outputFrameCount = 0
            self._nPeaks = 0
            self._ts_time = 0
            self._rate = 0
            self._ws = webServer.benWebServer(self)
            self._ws.setBgImg(
                "%s/%s" %
                (self._tmpdir, self.cfg.getConfigStr("background_depth")))
            self._ws.setChartImg(
                "%s/%s" % (self._tmpdir, self.cfg.getConfigStr("chart_fname")))
            self._ws.setRawImg(
                "%s/%s" %
                (self._tmpdir, self.cfg.getConfigStr("raw_image_fname")))
            self._ws.setMaskedImg(
                "%s/%s" %
                (self._tmpdir, self.cfg.getConfigStr("masked_image_fname")))
            self._ws.setDataFname(
                "%s/%s" % (self._tmpdir, self.cfg.getConfigStr("data_fname")))
            self._ws.setAnalysisResults({})
            webServer.setRoutes(self._ws)
            self.run()
示例#6
0
class BenFinder(object):
    configFname = "config.ini"
    configSection = "benFinder"

    ALARM_STATUS_OK = 0  # All ok, no alarms.
    ALARM_STATUS_WARN = 1  # Warning status
    ALARM_STATUS_FULL = 2  # Full alarm status.
    ALARM_STATUS_NOT_FOUND = 3  # Benjamin not found in image

    # (area below config area_threshold parameter)

    def __init__(self, save=False, inFile=None):
        print "benFinder.__init__()"
        print os.path.realpath(__file__)
        configPath = "%s/%s" % (os.path.dirname(
            os.path.realpath(__file__)), self.configFname)
        print configPath
        self.cfg = ConfigUtil(configPath, self.configSection)

        self.debug = self.cfg.getConfigBool("debug")
        if (self.debug): print "Debug Mode"

        self._wkdir = self.cfg.getConfigStr("working_directory")
        if (self.debug): print "working_directory=%s\n" % self._wkdir
        self._tmpdir = self.cfg.getConfigStr("tmpdir")
        if (self.debug): print "tmpdir=%s\n" % self._tmpdir

        # Check if we are running from live kinect or a file.
        if (inFile):
            device = depth.CV_CAP_FILE
        else:
            device = depth.CV_CAP_FREENECT

        # Initialise the captureManager
        self._captureManager = CaptureManager(device,
                                              None,
                                              True,
                                              inFile=inFile)
        self._captureManager.channel = depth.CV_CAP_OPENNI_DEPTH_MAP

        # If we are runnign from a file, use the first frame as the
        # background image.
        if (inFile):
            self.saveBgImg()

        # If we have asked to save the background image, do that, and exit,
        # otherwise initialise the seizure detector.
        if (save):
            self.saveBgImg()
        else:
            self.loadBgImg()
            self.autoBackgroundImg = None
            self._status = self.ALARM_STATUS_OK
            self._ts = TimeSeries(
                tslen=self.cfg.getConfigInt("timeseries_length"))
            self._frameCount = 0
            self._outputFrameCount = 0
            self._nPeaks = 0
            self._ts_time = 0
            self._rate = 0
            self._ws = webServer.benWebServer(self)
            self._ws.setBgImg(
                "%s/%s" %
                (self._tmpdir, self.cfg.getConfigStr("background_depth")))
            self._ws.setChartImg(
                "%s/%s" % (self._tmpdir, self.cfg.getConfigStr("chart_fname")))
            self._ws.setRawImg(
                "%s/%s" %
                (self._tmpdir, self.cfg.getConfigStr("raw_image_fname")))
            self._ws.setMaskedImg(
                "%s/%s" %
                (self._tmpdir, self.cfg.getConfigStr("masked_image_fname")))
            self._ws.setDataFname(
                "%s/%s" % (self._tmpdir, self.cfg.getConfigStr("data_fname")))
            self._ws.setAnalysisResults({})
            webServer.setRoutes(self._ws)
            self.run()

    def run(self):
        """Run the main loop."""
        while (True):
            self._captureManager.enterFrame()

            frame = self._captureManager.frame

            if frame is not None:
                if (self.autoBackgroundImg == None):
                    self.autoBackgroundImg = numpy.float32(frame)
                rawFrame = frame.copy()
                # First work out the region of interest by
                #    subtracting the fixed background image
                #    to create a mask.
                #print frame
                #print self._background_depth_img
                absDiff = cv2.absdiff(frame, self._background_depth_img)
                benMask, maskArea = filters.getBenMask(absDiff, 8)

                cv2.accumulateWeighted(frame, self.autoBackgroundImg, 0.05)
                # Convert the background image into the same format
                # as the main frame.
                #bg = self.autoBackgroundImg
                bg = cv2.convertScaleAbs(self.autoBackgroundImg, alpha=1.0)
                # Subtract the background from the frame image
                cv2.absdiff(frame, bg, frame)
                # Scale the difference image to make it more sensitive
                # to changes.
                cv2.convertScaleAbs(frame, frame, alpha=100)
                # Apply the mask so we only see the test subject.
                frame = cv2.multiply(frame, benMask, dst=frame, dtype=-1)

                if (maskArea <= self.cfg.getConfigInt('area_threshold')):
                    bri = (0, 0, 0)
                else:
                    # Calculate the brightness of the test subject.
                    bri = filters.getMean(frame, benMask)

                # Add the brightness to the time series ready for analysis.
                self._ts.addSamp(bri[0])
                self._ts.addImg(rawFrame)

                # Write timeseries to a file every 'output_framecount' frames.
                if (self._outputFrameCount >=
                        self.cfg.getConfigInt('output_framecount')):
                    # Write timeseries to file
                    self._ts.writeToFile("%s/%s" % \
                        ( self.cfg.getConfigStr('output_directory'),
                          self.cfg.getConfigStr('ts_fname')
                      ))
                    self._outputFrameCount = 0
                else:
                    self._outputFrameCount = self._outputFrameCount + 1

                # Only do the analysis every 15 frames (0.5 sec), or whatever
                # is specified in configuration file analysis_framecount
                # parameter.
                if (self._frameCount <
                        self.cfg.getConfigInt('analysis_framecount')):
                    self._frameCount = self._frameCount + 1
                else:
                    # Look for peaks in the brightness (=movement).
                    self._nPeaks, self._ts_time, self._rate = self._ts.findPeaks(
                    )
                    #print "%d peaks in %3.2f sec = %3.1f bpm" % \
                    #    (nPeaks,ts_time,rate)

                    oldStatus = self._status
                    if (maskArea > self.cfg.getConfigInt('area_threshold')):
                        # Check for alarm levels
                        if (self._rate > self.cfg.getConfigInt("rate_warn")):
                            self._status = self.ALARM_STATUS_OK
                        elif (self._rate >
                              self.cfg.getConfigInt("rate_alarm")):
                            self._status = self.ALARM_STATUS_WARN
                        else:
                            self._status = self.ALARM_STATUS_FULL
                    else:
                        self._status = self.ALARM_STATUS_NOT_FOUND


                    if (oldStatus == self.ALARM_STATUS_OK and
                        self._status == self.ALARM_STATUS_WARN) or \
                        (oldStatus == self.ALARM_STATUS_WARN and
                         self._status == self.ALARM_STATUS_FULL):
                        # Write timeseries to file
                        self._ts.writeToFile("%s/%s" % \
                            ( self.cfg.getConfigStr('output_directory'),
                              self.cfg.getConfigStr('alarm_ts_fname')
                          ),bgImg=self._background_depth_img)

                    # Collect the analysis results together and send them
                    # to the web server.
                    resultsDict = {}
                    resultsDict['fps'] = "%3.0f" % self.fps
                    resultsDict['bri'] = "%4.0f" % self._ts.mean
                    resultsDict['area'] = "%6.0f" % maskArea
                    resultsDict['nPeaks'] = "%d" % self._nPeaks
                    resultsDict['ts_time'] = self._ts_time
                    resultsDict['rate'] = "%d" % self._rate
                    resultsDict['time_t'] = time.ctime()
                    resultsDict['status'] = self._status
                    self._ws.setAnalysisResults(resultsDict)

                    # Write the results to file as a json string
                    utils.writeJSON(resultsDict,"%s/%s" % \
                                    (self._tmpdir,
                                     self.cfg.getConfigStr("data_fname")))
                    utils.writeLog(resultsDict,"%s/%s" % \
                                    (self._tmpdir,
                                     "benFinder_alarms.log"))
                    # Plot the graph of brightness, and save the images
                    # to disk.
                    self._ts.plotRawData(
                        file=True,
                        fname="%s/%s" % \
                        (self._tmpdir,self.cfg.getConfigStr("chart_fname")))

                    cv2.imwrite(
                        "%s/%s" % (self._tmpdir,
                                   self.cfg.getConfigStr("raw_image_fname")),
                        rawFrame)
                    cv2.imwrite(
                        "%s/%s" %
                        (self._tmpdir,
                         self.cfg.getConfigStr("masked_image_fname")), frame)
                    self._frameCount = 0
            else:
                print "Null frame received - assuming end of file and exiting"
                break
            self._captureManager.exitFrame()

    @property
    def fps(self):
        return self._captureManager.fps

    @property
    def nPeaks(self):
        return self._nPeaks

    @property
    def ts_time(self):
        return self._ts_time

    @property
    def rate(self):
        return self._rate

    @property
    def rawImgFname(self):
        return self.cfg.getConfigStr("raw_image_fname")

    @property
    def maskedImgFname(self):
        return self.cfg.getConfigStr("masked_image_fname")

    @property
    def chartImgFname(self):
        return self.cfg.getConfigStr("chart_fname")

    def saveBgImg(self):
        """ Write a new background image to the appropriate file location."""
        if (self._captureManager.hasEnteredFrame):
            self._captureManager.exitFrame()
        self._captureManager.enterFrame()
        print "Writing image to %s." % self.cfg.getConfigStr(
            "background_depth")
        self._captureManager.writeImage(
            "%s/%s" % (self._wkdir, self.cfg.getConfigStr("background_depth")))
        print self._captureManager.frame
        print self._captureManager.frame.dtype
        self._captureManager.exitFrame()
        self.loadBgImg()

    def loadBgImg(self):
        print "Loading background image %s/%s." % \
            (self._wkdir,self.cfg.getConfigStr("background_depth"))
        self._background_depth_img = cv2.imread("%s/%s" % \
                    (self._wkdir,self.cfg.getConfigStr("background_depth")),
                                                cv2.CV_LOAD_IMAGE_GRAYSCALE)
        #                                        cv2.CV_LOAD_IMAGE_UNCHANGED)
        print self._background_depth_img
        print self._background_depth_img.dtype
示例#7
0
class bentv_ui:
    # Basic Configuration
    configFname = "config.ini"
    configSection = "bentv"
    debug = False

    # Initialise some instance variables.
    screen = None
    font = None
    textLine1 = "BenTV_UI"
    textLine2 = "Waiting for Button Press to move camera"
    presetNo = 1
    presetTxt = ['NULL','Behind Door', 'Corner', 'Chair', 'Bed']

    # Alarms
    ALARM_STATUS_OK = 0   # All ok, no alarms.
    ALARM_STATUS_WARN = 1 # Warning status
    ALARM_STATUS_FULL = 2 # Full alarm status.
    ALARM_STATUS_NOT_FOUND = 3 # Benjamin not found in image 
                               # (area below config area_threshold parameter)

    statusStrs = ("OK","Warning","ALARM!!!","Ben Not Found")
    screenBGColours = ( (0,0,255), # Blue for all ok
                        (128,128,0), # Yellow for warning
                        (255,0,0),  # Red for full alarm.
                        (128,128,128) # Grey for not found.
                        )
    alarmStatus = 0   # Current alarm status


    def __init__(self):
        """Initialise the bentv_ui class - reads the configuration file
        and initialises the screen and GPIO monitor"""
        print "bentv.__init__()"
        configPath = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)),
                                self.configFname)
        print configPath
        self.cfg = ConfigUtil(configPath,self.configSection)

        self.debug = self.cfg.getConfigBool("debug")
        if (self.debug): print "Debug Mode"
        
        self.hostname, self.ipaddr = self.getHostName()
        print self.hostname, self.ipaddr
        self.presetNo = 1
        self.initScreen()
        self.initGPIO()

    def getIpAddr(self,ifname):
        """Return the IP Address of the given interface (e.g 'wlan0')
        from http://raspberrypi.stackexchange.com/questions/6714/how-to-get-the-raspberry-pis-ip-address-for-ssh.
        """
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        return socket.inet_ntoa(fcntl.ioctl(
            s.fileno(),
            0x8915,  # SIOCGIFADDR
            struct.pack('256s', ifname[:15])
        )[20:24])

    def getHostName(self):
        """Returns the hostname and IP address of the wireless interface as a tuple.
        """
        hostname = socket.gethostname()
        ipaddr = self.getIpAddr("wlan0")
        return (hostname,ipaddr)

    def initGPIO(self):
        """Initialise the GPIO pins - not we use GPIO pin numbers, not physical
        pin numbers on rpi."""
        haveGPIO = True
        try:
            import RPi.GPIO as GPIO 
        except:
            print "failed to import RPi.GPIO"
            haveGPIO = False
        pinNo = self.cfg.getConfigInt("gpiono")
        if (self.debug): print "gpioNo = %d" % pinNo
        if (haveGPIO):
            GPIO.setmode(GPIO.BCM)
            GPIO.setup(pinNo, GPIO.IN, pull_up_down=GPIO.PUD_UP)
            # very long debounce time to prevent presses while camera is moving.
            GPIO.add_event_detect(pinNo,
                                  GPIO.RISING, 
                                  callback=self.moveCamera, 
                                  bouncetime=1000)
        else:
            print "no GPIO - simulating camera move"
            self.moveCamera(1)


    def display_text(self):
        """ Write the given text onto the display area of the screen"""
        # Clear screen
        self.screen.fill(self.screenBGColours[self.alarmStatus])
        # Line 1 text
        txtImg = self.font.render(self.textLine1,
            True,(255,255,255))
        self.screen.blit(txtImg,(0,380))
        # Line 1 time
        tnow = time.localtime(time.time())
        txtStr = "%02d:%02d:%02d " % (tnow[3],tnow[4],tnow[5])
        w = self.font.size(txtStr)[0]
        txtImg = self.font.render(txtStr,
            True,(255,255,255))
        self.screen.blit(txtImg,(self.fbSize[0]-w,380))
        # Line 2 text
        txtImg = self.smallFont.render(self.textLine2,
            True,(255,255,255))
        self.screen.blit(txtImg,(0,400))
        # Line 2 network info
        txtStr = "Host: %s, IP: %s  " % (self.hostname, self.ipaddr)
        w = self.smallFont.size(txtStr)[0]
        txtImg = self.smallFont.render(txtStr,
                                       True,
                                       (255,255,255))
        
        self.screen.blit(txtImg,(self.fbSize[0]-w,400))
        pygame.display.update()

    def initScreen(self):    
        """Initialise the display using the pygame library"""
        drivers = ['x11', 'fbcon', 'svgalib']
        found = False
        disp_no = os.getenv("DISPLAY")
        if disp_no:
            print "I'm running under X display = {0}".format(disp_no)
        for driver in drivers:
            # Make sure that SDL_VIDEODRIVER is set
            if not os.getenv('SDL_VIDEODRIVER'):
                os.putenv('SDL_VIDEODRIVER', driver)
            try:
                pygame.display.init()
                print 'Using Driver: {0}.'.format(driver)
            except pygame.error:
                print 'Driver: {0} failed.'.format(driver)
                continue
            found = True
            break

        if not found:
            raise Exception('No suitable video driver found!')

        self.fbSize = (pygame.display.Info().current_w, pygame.display.Info().current_h)
        print "Framebuffer size: %d x %d" % self.fbSize
        if (disp_no):
            print "Using X11 window"
            winSize = (640,480)
            self.screen = pygame.display.set_mode(winSize)
            self.fbSize = winSize
        else:
            print "Using full screen framebuffer"
            self.screen = pygame.display.set_mode(self.fbSize, pygame.FULLSCREEN)
        print "blank screen..."
        self.screen.fill((0, 0, 255))        
        print "initialise fonts"
        pygame.font.init()
        self.font = pygame.font.Font(None,30)
        self.smallFont = pygame.font.Font(None,16)
        print "calling display_text()"
        self.display_text()
        print "initScreen complete"

    def moveCamera(self,pinNo):
        """Callback function when button is pressed"""
        print('moveCamera called by pin number %d. PresetNo=%d' % (pinNo,self.presetNo))
        h = httplib2.Http(".cache")
        h.add_credentials(self.cfg.getConfigStr('uname'), 
                          self.cfg.getConfigStr('passwd'))
        #resp, content = h.request("http://192.168.1.24/preset.cgi?-act=goto&-status=1&-number=%d" % self.presetNo,"GET")
        resp, content = h.request("%s/%s%d" % (self.cfg.getConfigStr('camaddr'),
                                               self.cfg.getConfigStr('cammoveurl'),
                                               self.presetNo),"GET")
        print "moved to preset %d - content=%s" % (self.presetNo,content)
        self.textLine1 = "Camera Position %d (%s)" % (self.presetNo, 
                                                       self.presetTxt[self.presetNo])
        self.presetNo += 1
        if (self.presetNo > 4): self.presetNo = 1

 
    def getBenFinderData(self):
        print "getBenfinderData"
        h = httplib2.Http(".cache")
        h.add_credentials(self.cfg.getConfigStr('uname'), 
                          self.cfg.getConfigStr('passwd'))
        requestStr = "%s:%s/%s" % \
                     (self.cfg.getConfigStr('benfinderserver'),
                      self.cfg.getConfigStr('benfinderport'),
                      self.cfg.getConfigStr('benfinderurl'))
        print requestStr
        try:
            resp, content = h.request(requestStr,
                                      "GET")
            dataDict = json.loads(content)
            self.alarmStatus = int(dataDict['status'])
            self.textLine1 = " Rate = %d bpm (status=%d - %s)" % \
                             (int(dataDict['rate']),
                              int(dataDict['status']),
                                  self.statusStrs[int(dataDict['status'])]
                             )
            print dataDict['time_t']
            self.textLine2 = " Fit Detector Time = %s  " % dataDict['time_t']
            print resp,content
            return True
        except:
            print "Error:",sys.exc_info()[0]
            self.textLine1 = "No Connection to Fit Detector"
            return False
示例#8
0
class bentv_ui:
    # Basic Configuration
    configFname = "config.ini"
    configSection = "bentv"
    debug = False

    # Initialise some instance variables.
    screen = None
    font = None
    textLine1 = "Camera_Mode"
    textLine2 = "Waiting for Button Press to move camera"
    presetNo = 1
    presetTxt = ['NULL', 'Behind Door', 'Corner', 'Chair', 'Bed']

    # UI Modes
    CAMERA_MODE = 0
    FITDECT_MODE = 1

    # Alarms
    ALARM_STATUS_OK = 0  # All ok, no alarms.
    ALARM_STATUS_WARN = 1  # Warning status
    ALARM_STATUS_FULL = 2  # Full alarm status.
    ALARM_STATUS_NOT_FOUND = 3  # Benjamin not found in image
    # (area below config area_threshold parameter)

    statusStrs = ("OK", "Warning", "ALARM!!!", "Ben Not Found")
    screenBGColours = (
        (0, 0, 255),  # Blue for all ok
        (128, 128, 0),  # Yellow for warning
        (255, 0, 0),  # Red for full alarm.
        (128, 128, 128)  # Grey for not found.
    )
    alarmStatus = 0  # Current alarm status

    def __init__(self):
        """Initialise the bentv_ui class - reads the configuration file
        and initialises the screen and GPIO monitor"""
        print "bentv.__init__()"
        configPath = "%s/%s" % (os.path.dirname(
            os.path.realpath(__file__)), self.configFname)
        print configPath
        self.cfg = ConfigUtil(configPath, self.configSection)

        self.debug = self.cfg.getConfigBool("debug")
        if (self.debug): print "Debug Mode"

        self.debounce_ms = self.cfg.getConfigInt("debounce_ms")
        self.shortpress_ms = self.cfg.getConfigInt("shortpress_ms")

        self.hostname, self.ipaddr = self.getHostName()
        print self.hostname, self.ipaddr
        self.timeDown = 0.0
        self.presetNo = 1
        self.shortPress = False
        self.longPress = False
        self.initScreen()
        self.initGPIO()
        self.UIMode = self.CAMERA_MODE  # Next line changes mode to start in
        # FITDECT_MODE.
        self.changeUIMode()  # Initialises the messages.

    def getIpAddr(self, ifname):
        """Return the IP Address of the given interface (e.g 'wlan0')
        from http://raspberrypi.stackexchange.com/questions/6714/how-to-get-the-raspberry-pis-ip-address-for-ssh.
        """
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        return socket.inet_ntoa(
            fcntl.ioctl(
                s.fileno(),
                0x8915,  # SIOCGIFADDR
                struct.pack('256s', ifname[:15]))[20:24])

    def getHostName(self):
        """Returns the hostname and IP address of the wireless interface as a tuple.
        """
        hostname = socket.gethostname()
        ipaddr = self.getIpAddr("wlan0")
        return (hostname, ipaddr)

    def initGPIO(self):
        """Initialise the GPIO pins - note we use GPIO pin numbers, not physical
        pin numbers on rpi."""
        global haveGPIO
        pinNo = self.cfg.getConfigInt("gpiono")
        self.pinNo = pinNo
        if (self.debug): print "gpioNo = %d" % pinNo
        if (haveGPIO):
            GPIO.setmode(GPIO.BCM)
            GPIO.setup(pinNo, GPIO.IN, pull_up_down=GPIO.PUD_UP)
            # very long debounce time to prevent presses while camera is moving.
            #GPIO.add_event_detect(pinNo,
            #                      GPIO.FALLING,
            #                      callback=self.buttonCallback
            #                      ,bouncetime=100)
        else:
            print "no GPIO - simulating camera move"
            self.moveCamera(1)

        self.lastButtonVal = 1
        self.lastButtonTime = time.time()

    def buttonCallback(self, pinNo):
        """ called on falling edge - it waits for rising edge to see how long
        the button press was. """
        print "Button Down"
        self.timeDown = time.time()
        GPIO.wait_for_edge(pinNo, GPIO.RISING)
        print "Button Up"
        print "time of press = %f" % (time.time() - self.timeDown)

    def pollButtons(self):
        """poll the buttons, and set a variable to say if we have detected
        a single, double or long click."""
        global haveGPIO

        if (haveGPIO):
            ip = GPIO.input(self.pinNo)
            tnow = time.time()
            if (ip != self.lastButtonVal):
                print "button state changed"
                if (ip):
                    keyPressLength = (tnow - self.lastButtonTime) * 1000.  #ms
                    print "Keypress Length = %f sec" % (keyPressLength)
                    if (keyPressLength < self.debounce_ms):
                        print "Ignoring very short keypress"
                        self.shortPress = False
                        self.longPress = False
                    elif (keyPressLength < self.shortpress_ms):
                        print "short press"
                        self.shortPress = True
                        self.longPress = False
                    else:
                        self.shortPress = False
                        self.longPress = True
                self.lastButtonVal = ip
                self.lastButtonTime = tnow
        else:
            pass
            # do nothing if we do not have GPIO access.

    def serviceUI(self):
        """Respond to button presses."""
        if (self.longPress):
            if (self.UIMode == self.CAMERA_MODE):
                self.moveCamera(self.pinNo)
            elif (self.UIMode == self.FITDECT_MODE):
                self.setFitDectBackground()
            else:
                print "Unrecognised UIMode %d." % self.UIMode
            self.longPress = False

        if (self.shortPress):
            self.changeUIMode()
            self.shortPress = False

    def changeUIMode(self):
        """Change the UI mode - toggle between camera and fit detector"""
        if (self.UIMode == self.CAMERA_MODE):
            print "Entering FitDetector Mode"
            self.textLine1 = "Fit Detector Mode"
            self.textLine2 = " Press long button press to reset background.  Short press to change mode."
            self.UIMode = self.FITDECT_MODE
        else:
            print "Entering Camera Mode"
            self.textLine1 = "Camera Mode"
            self.textLine2 = " Press long button press to move camera.  Short press to change mode."
            self.UIMode = self.CAMERA_MODE
            self.alarmStatus = self.ALARM_STATUS_NOT_FOUND
        self.lastDisplayUpdateTime = time.time()  #Force message to display for
        # a little while before being
        # overwritten.
        self.display_text()

    def display_text(self):
        """ Write the given text onto the display area of the screen"""
        # Clear screen
        self.screen.fill(self.screenBGColours[self.alarmStatus])
        # Line 1 text
        txtImg = self.font.render(self.textLine1, True, (255, 255, 255))
        self.screen.blit(txtImg, (0, 380))
        # Line 1 time
        tnow = time.localtime(time.time())
        txtStr = "%02d:%02d:%02d " % (tnow[3], tnow[4], tnow[5])
        w = self.font.size(txtStr)[0]
        txtImg = self.font.render(txtStr, True, (255, 255, 255))
        self.screen.blit(txtImg, (self.fbSize[0] - w, 380))
        # Line 2 text
        txtImg = self.smallFont.render(self.textLine2, True, (255, 255, 255))
        self.screen.blit(txtImg, (0, 400))
        # Line 2 network info
        txtStr = "Host: %s, IP: %s  " % (self.hostname, self.ipaddr)
        w = self.smallFont.size(txtStr)[0]
        txtImg = self.smallFont.render(txtStr, True, (255, 255, 255))

        self.screen.blit(txtImg, (self.fbSize[0] - w, 400))
        pygame.display.update()

    def initScreen(self):
        """Initialise the display using the pygame library"""
        drivers = ['x11', 'fbcon', 'svgalib']
        found = False
        disp_no = os.getenv("DISPLAY")
        if disp_no:
            print "I'm running under X display = {0}".format(disp_no)
        for driver in drivers:
            # Make sure that SDL_VIDEODRIVER is set
            if not os.getenv('SDL_VIDEODRIVER'):
                os.putenv('SDL_VIDEODRIVER', driver)
            try:
                pygame.display.init()
                print 'Using Driver: {0}.'.format(driver)
            except pygame.error:
                print 'Driver: {0} failed.'.format(driver)
                continue
            found = True
            break

        if not found:
            raise Exception('No suitable video driver found!')

        self.fbSize = (pygame.display.Info().current_w,
                       pygame.display.Info().current_h)
        print "Framebuffer size: %d x %d" % self.fbSize
        if (disp_no):
            print "Using X11 window"
            winSize = (640, 480)
            self.screen = pygame.display.set_mode(winSize)
            self.fbSize = winSize
        else:
            print "Using full screen framebuffer"
            self.screen = pygame.display.set_mode(self.fbSize,
                                                  pygame.FULLSCREEN)
        print "blank screen..."
        self.screen.fill((0, 0, 255))
        print "initialise fonts"
        pygame.font.init()
        self.font = pygame.font.Font(None, 30)
        self.smallFont = pygame.font.Font(None, 16)
        print "calling display_text()"
        self.display_text()
        print "initScreen complete"

    def moveCamera(self, pinNo):
        """Callback function when button is pressed"""
        print('moveCamera called by pin number %d. PresetNo=%d' %
              (pinNo, self.presetNo))
        h = httplib2.Http(".cache")
        h.add_credentials(self.cfg.getConfigStr('uname'),
                          self.cfg.getConfigStr('passwd'))
        #resp, content = h.request("http://192.168.1.24/preset.cgi?-act=goto&-status=1&-number=%d" % self.presetNo,"GET")
        resp, content = h.request(
            "%s/%s%d" % (self.cfg.getConfigStr('camaddr'),
                         self.cfg.getConfigStr('cammoveurl'), self.presetNo),
            "GET")
        print "moved to preset %d - content=%s" % (self.presetNo, content)
        self.textLine1 = "Camera Position %d (%s)" % (
            self.presetNo, self.presetTxt[self.presetNo])
        self.presetNo += 1
        if (self.presetNo > 4): self.presetNo = 1

    def getBenFinderData(self):
        #print "getBenfinderData"
        h = httplib2.Http(".cache")
        h.add_credentials(self.cfg.getConfigStr('uname'),
                          self.cfg.getConfigStr('passwd'))
        requestStr = "%s:%s/%s" % \
                     (self.cfg.getConfigStr('benfinderserver'),
                      self.cfg.getConfigStr('benfinderport'),
                      self.cfg.getConfigStr('benfinderurl'))
        #print requestStr
        try:
            resp, content = h.request(requestStr, "GET")
            dataDict = json.loads(content)
            self.alarmStatus = int(dataDict['status'])
            self.textLine1 = " Rate = %d bpm (status=%d - %s)" % \
                             (int(dataDict['rate']),
                              int(dataDict['status']),
                                  self.statusStrs[int(dataDict['status'])]
                             )
            #print dataDict['time_t']
            self.textLine2 = " Fit Detector Time = %s  " % dataDict['time_t']
            #print resp,content
            return True
        except:
            print "Error:", sys.exc_info()[0]
            self.textLine1 = "No Connection to Fit Detector"
            return False

    def setFitDectBackground(self):
        """Tell the fit detector to initialise its background image from
        the current image."""
        print "setFitDectBackground()"
        h = httplib2.Http(".cache")
        h.add_credentials(self.cfg.getConfigStr('uname'),
                          self.cfg.getConfigStr('passwd'))
        requestStr = "%s:%s/%s" % \
                     (self.cfg.getConfigStr('benfinderserver'),
                      self.cfg.getConfigStr('benfinderport'),
                      self.cfg.getConfigStr('benfinderbackgroundurl'))
        print requestStr
        try:
            resp, content = h.request(requestStr, "GET")
            print resp, content
            self.textLine1 = "Fit Detector Background Image Reset"
            self.textLine2 = " Press button to reset background.  Long press to change mode."
        except:
            print "Error:", sys.exc_info()[0]
            self.textLine1 = "Error Initialising Fit Detector Background"
            self.textLine2 = " Press button to reset background.  Long press to change mode."
        self.lastDisplayUpdateTime = time.time()  #Force message to display for
        # a little while before being
        # overwritten.
        self.display_text()

    def run(self):
        """bentv main loop"""
        self.lastDisplayUpdateTime = time.time()
        while 1:
            tnow = time.time()
            self.pollButtons()
            self.serviceUI()
            if (tnow - self.lastDisplayUpdateTime >= 1.0):
                if (self.UIMode == self.FITDECT_MODE):
                    self.getBenFinderData()
            if (tnow - self.lastDisplayUpdateTime >= 1.0):
                self.display_text()
                self.lastDisplayUpdateTime = tnow
            #print "main loop..."
            time.sleep(0.2)
示例#9
0
class bentv_ui:
    # Basic Configuration
    configFname = "config.ini"
    configSection = "bentv"
    debug = False

    # Initialise some instance variables.
    screen = None
    font = None
    textLine1 = "Camera_Mode"
    textLine2 = "Waiting for Button Press to move camera"
    presetNo = 1
    presetTxt = ['NULL', 'Behind Door', 'Corner', 'Chair', 'Bed']

    # UI Modes
    CAMERA_MODE = 0
    FITDECT_MODE = 1

    # Alarms
    ALARM_STATUS_OK = 0  # All ok, no alarms.
    ALARM_STATUS_WARN = 1  # Warning status
    ALARM_STATUS_FULL = 2  # Full alarm status.
    ALARM_STATUS_NOT_FOUND = 3  # Benjamin not found in image
    # (area below config area_threshold parameter)

    statusStrs = ("OK", "Warning", "ALARM!!!", "Ben Not Found")
    screenBGColours = (
        (0, 0, 255),  # Blue for all ok (0)
        (128, 128, 0),  # Yellow for warning (1)
        (255, 0, 0),  # Red for full alarm. (2)
        (255, 0, 0),  # Red for fall alarm. (3)
        (128, 128, 0),  # Yellow for fault (4)
        (255, 0, 0),  # Red for manual alarm. (5)
        (128, 128, 128),  # Grey for mute. (6)
    )
    alarmStatus = 0  # Current alarm status

    # Dimensions of the status bar at the bottom of the screen.
    statusBar_x = 0
    statusBar_y = 380
    statusbar_w = 640
    statusbar_h = 100

    alarmRatioThresh = 1
    alarmRatio = 0
    specRatio = 0
    specPower = 0
    alarmPhrase = ""
    dataTime = ""

    def __init__(self):
        """Initialise the bentv_ui class - reads the configuration file
        and initialises the screen and GPIO monitor"""
        print "bentv.__init__()"
        configPath = "%s/%s" % (os.path.dirname(
            os.path.realpath(__file__)), self.configFname)
        print configPath
        self.cfg = ConfigUtil(configPath, self.configSection)

        self.debug = self.cfg.getConfigBool("debug")
        if (self.debug): print "Debug Mode"

        self.debounce_ms = self.cfg.getConfigInt("debounce_ms")
        self.shortpress_ms = self.cfg.getConfigInt("shortpress_ms")

        self.hostname, self.ipaddr = self.getHostName()
        print self.hostname, self.ipaddr
        self.timeDown = 0.0
        self.presetNo = 1
        self.shortPress = False
        self.longPress = False
        self.initScreen()
        self.initGPIO()
        self.UIMode = self.CAMERA_MODE  # Next line changes mode to start in
        # FITDECT_MODE.
        self.changeUIMode()  # Initialises the messages.

    def getHostName(self):
        """Returns the hostname and IP address of the first physical 
        (non loopback) network interface as a tuple, using the 
        netifaces library..
        """
        hostname = socket.gethostname()
        ifList = netifaces.interfaces()
        print ifList
        ipAddr = "xxx.xxx.xxx.xxx"
        for ifName in ifList:
            print ifName
            if not ifName.startswith('lo'):
                print "non lo interface found ", ifName
                ifInfo = netifaces.ifaddresses(ifName).get(
                    netifaces.AF_INET, [])
                print ifInfo
                if len(ifInfo) > 0:
                    ipAddr = ifInfo[0]['addr']
                print ipAddr
        return (hostname, ipAddr)

    def initGPIO(self):
        """Initialise the GPIO pins - note we use GPIO pin numbers, not physical
        pin numbers on rpi."""
        global haveGPIO
        pinNo = self.cfg.getConfigInt("gpiono")
        self.pinNo = pinNo
        if (self.debug): print "gpioNo = %d" % pinNo
        if (haveGPIO):
            GPIO.setmode(GPIO.BCM)
            GPIO.setup(pinNo, GPIO.IN, pull_up_down=GPIO.PUD_UP)
            # very long debounce time to prevent presses while camera is moving.
            #GPIO.add_event_detect(pinNo,
            #                      GPIO.FALLING,
            #                      callback=self.buttonCallback
            #                      ,bouncetime=100)
        else:
            print "no GPIO - simulating camera move"
            self.moveCamera(1)

        self.lastButtonVal = 1
        self.lastButtonTime = time.time()

    def buttonCallback(self, pinNo):
        """ called on falling edge - it waits for rising edge to see how long
        the button press was. """
        print "Button Down"
        self.timeDown = time.time()
        GPIO.wait_for_edge(pinNo, GPIO.RISING)
        print "Button Up"
        print "time of press = %f" % (time.time() - self.timeDown)

    def pollButtons(self):
        """poll the buttons, and set a variable to say if we have detected
        a single, double or long click."""
        global haveGPIO

        if (haveGPIO):
            ip = GPIO.input(self.pinNo)
            tnow = time.time()
            if (ip != self.lastButtonVal):
                print "button state changed"
                if (ip):
                    keyPressLength = (tnow - self.lastButtonTime) * 1000.  #ms
                    print "Keypress Length = %f sec" % (keyPressLength)
                    if (keyPressLength < self.debounce_ms):
                        print "Ignoring very short keypress"
                        self.shortPress = False
                        self.longPress = False
                    elif (keyPressLength < self.shortpress_ms):
                        print "short press"
                        self.shortPress = True
                        self.longPress = False
                    else:
                        self.shortPress = False
                        self.longPress = True
                self.lastButtonVal = ip
                self.lastButtonTime = tnow
        else:
            pass
            # do nothing if we do not have GPIO access.

    def serviceUI(self):
        """Respond to button presses."""
        if (self.longPress):
            if (self.UIMode == self.CAMERA_MODE):
                self.moveCamera(self.pinNo)
            elif (self.UIMode == self.FITDECT_MODE):
                self.setFitDectBackground()
            else:
                print "Unrecognised UIMode %d." % self.UIMode
            self.longPress = False

        if (self.shortPress):
            self.changeUIMode()
            self.shortPress = False

    def changeUIMode(self):
        """Change the UI mode - toggle between camera and fit detector"""
        if (self.UIMode == self.CAMERA_MODE):
            print "Entering FitDetector Mode"
            self.textLine1 = "Fit Detector Mode"
            self.textLine2 = " Short press to change mode."
            self.UIMode = self.FITDECT_MODE
        else:
            print "Entering Camera Mode"
            self.textLine1 = "Camera Mode"
            self.textLine2 = " Press long button press to move camera.  Short press to change mode."
            self.UIMode = self.CAMERA_MODE
            self.alarmStatus = self.ALARM_STATUS_NOT_FOUND
        self.lastDisplayUpdateTime = time.time()  #Force message to display for
        # a little while before being
        # overwritten.
        self.drawStatusBar()

    def drawStatusBar(self):
        """ Write the given text onto the display area of the screen"""
        try:
            # Clear screen
            self.screen.fill(self.screenBGColours[self.alarmStatus])
            # Line 1 text
            txtImg = self.font.render(self.textLine1, True, (255, 255, 255))
            self.screen.blit(txtImg, (self.statusBar_x, self.statusBar_y))
            # Line 1 time
            tnow = time.localtime(time.time())
            txtStr = "%02d:%02d:%02d " % (tnow[3], tnow[4], tnow[5])
            w = self.font.size(txtStr)[0]
            txtImg = self.font.render(txtStr, True, (255, 255, 255))
            self.screen.blit(txtImg, (self.fbSize[0] - w, self.statusBar_y))
            # Line 2 text
            txtImg = self.smallFont.render(self.textLine2, True,
                                           (255, 255, 255))
            self.screen.blit(txtImg, (self.statusBar_x, self.statusBar_y + 20))
            # Line 2 network info
            txtStr = "Host: %s, IP: %s  " % (self.hostname, self.ipaddr)
            w = self.smallFont.size(txtStr)[0]
            txtImg = self.smallFont.render(txtStr, True, (255, 255, 255))

            self.screen.blit(txtImg,
                             (self.fbSize[0] - w, self.statusBar_y + 20))

            #Draw the spectrum ratio bar graph in middle of status bar.
            rx = 300
            ry = self.statusBar_y
            rw = 20
            rh = 40
            pygame.draw.rect(self.screen, (0, 0, 0), (rx, ry, rw, rh))
            marginPc = 100 * self.specRatio / self.alarmRatioThresh
            if marginPc > 100:
                marginPc = 100
            barh = rh * marginPc / 100
            if barh < 2:
                barh = 2
            #print marginPc,barh
            pygame.draw.rect(self.screen, (255, 0, 0),
                             (rx, ry + rh - barh, rw, barh))

            pygame.display.update()
        except:
            print "Error in DrawStatusBar()"

    def initScreen(self):
        """Initialise the display using the pygame library"""
        drivers = ['x11', 'fbcon', 'svgalib']
        found = False
        disp_no = os.getenv("DISPLAY")
        if disp_no:
            print "I'm running under X display = {0}".format(disp_no)
        for driver in drivers:
            # Make sure that SDL_VIDEODRIVER is set
            if not os.getenv('SDL_VIDEODRIVER'):
                os.putenv('SDL_VIDEODRIVER', driver)
            try:
                pygame.display.init()
                print 'Using Driver: {0}.'.format(driver)
            except pygame.error:
                print 'Driver: {0} failed.'.format(driver)
                continue
            found = True
            break

        if not found:
            raise Exception('No suitable video driver found!')

        self.fbSize = (pygame.display.Info().current_w,
                       pygame.display.Info().current_h)
        print "Framebuffer size: %d x %d" % self.fbSize
        if (disp_no):
            print "Using X11 window"
            winSize = (640, 480)
            self.screen = pygame.display.set_mode(winSize)
            self.fbSize = winSize
        else:
            print "Using full screen framebuffer"
            self.screen = pygame.display.set_mode(self.fbSize,
                                                  pygame.FULLSCREEN)
            #print "using small screen"
            #winSize = (640,480)
            #self.screen = pygame.display.set_mode(winSize)
            #self.fbSize = winSize

        print "blank screen..."
        self.screen.fill((0, 0, 255))
        print "initialise fonts"
        pygame.font.init()
        self.font = pygame.font.Font(None, 30)
        self.smallFont = pygame.font.Font(None, 16)
        print "calling drawStatusBar()"
        self.drawStatusBar()
        print "initScreen complete"

    def moveCamera(self, pinNo):
        """Callback function when button is pressed"""
        print('moveCamera called by pin number %d. PresetNo=%d' %
              (pinNo, self.presetNo))
        try:
            h = httplib2.Http(".cache")
            h.add_credentials(self.cfg.getConfigStr('uname'),
                              self.cfg.getConfigStr('passwd'))
            #resp, content = h.request("http://192.168.1.24/preset.cgi?-act=goto&-status=1&-number=%d" % self.presetNo,"GET")
            resp, content = h.request(
                "%s/%s%d" %
                (self.cfg.getConfigStr('camaddr'),
                 self.cfg.getConfigStr('cammoveurl'), self.presetNo), "GET")
            print "moved to preset %d - content=%s" % (self.presetNo, content)
        except:
            print "Exception moving camera", sys.exc_info()[0]

        self.textLine1 = "Camera Position %d (%s)" % (
            self.presetNo, self.presetTxt[self.presetNo])
        self.presetNo += 1
        if (self.presetNo > 4): self.presetNo = 1

    def getOpenSeizureDetectorData(self):
        """ Use HTTP GET request to retrieve seizure detector
        data from an OpenSeizureDetector web interface.
        """
        #print "getOpenSeizureDetectorData"
        h = httplib2.Http(".cache")
        h.add_credentials(self.cfg.getConfigStr('uname'),
                          self.cfg.getConfigStr('passwd'))
        requestStr = "%s:%s/%s" % \
                     (self.cfg.getConfigStr('benfinderserver'),
                      self.cfg.getConfigStr('benfinderport'),
                      self.cfg.getConfigStr('benfinderurl'))
        #print requestStr
        try:
            resp, content = h.request(requestStr, "GET")
            dataDict = json.loads(content)
            self.alarmStatus = int(dataDict['alarmState'])
            self.specPower = int(dataDict['specPower'])
            self.roiPower = int(dataDict['roiPower'])
            self.alarmThresh = int(dataDict['alarmThresh'])
            self.alarmRatioThresh = int(dataDict['alarmRatioThresh'])
            self.alarmPhrase = dataDict['alarmPhrase']
            self.dataTime = dataDict['dataTime']
            if (self.roiPower > self.alarmThresh):
                self.specRatio = 10 * self.roiPower / self.specPower
            else:
                self.specRatio = 0
            #print "specPower=%d, roiPower=%d, specRatio=%d" % \
            #    (specPower,roiPower,specRatio)

            self.textLine1 = " Ratio = %d / %d (%s)" % \
                             (self.specRatio,self.alarmRatioThresh,
                              self.alarmPhrase)
            #print dataDict['time_t']
            self.textLine2 = " Fit Detector Time = %s  " % self.dataTime
            #print resp,content
            return True
        except:
            print "getOpenSeizureDetectorData Error:", sys.exc_info()[0]
            print "getOpenSeizureDetectorData Error"
            self.textLine1 = "No Connection to Fit Detector"
            return False

    def run(self):
        """bentv main loop"""
        self.lastDisplayUpdateTime = time.time()
        while 1:
            tnow = time.time()
            self.pollButtons()
            self.serviceUI()
            if (tnow - self.lastDisplayUpdateTime >= 1.0):
                if (self.UIMode == self.FITDECT_MODE):
                    self.getOpenSeizureDetectorData()
            if (tnow - self.lastDisplayUpdateTime >= 1.0):
                self.drawStatusBar()
                self.lastDisplayUpdateTime = tnow
            #print "main loop..."
            time.sleep(0.2)
示例#10
0
class runServer(object):
    configFname = "config.ini"
    configSection = "server"
    MAXLEN = 300

    def __init__(self,port = None):
        print "runServer.__init__()"
        print os.path.realpath(__file__)
        configPath = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)),
                                self.configFname)
        print configPath
        self.cfg = ConfigUtil(configPath,self.configSection)

        self.debug = self.cfg.getConfigBool("debug")
        if (self.debug): print "Debug Mode"

        self._wkdir = self.cfg.getConfigStr("working_directory")
        if (self.debug): print "working_directory=%s\n" % self._wkdir
        self._tmpdir = self.cfg.getConfigStr("tmpdir")
        if (self.debug): print "tmpdir=%s\n" % self._tmpdir


        if (port == None):
            port = '/dev/ttyUSB0'
        print "Opening Serial Connection on %s" % port
        self.ser = serial.Serial(port,9600,timeout=1)
        print "Waiting for serial comms to settle..."
        time.sleep(2)
        print "Reading first line of data, and ignoring it."
        line = self.ser.readline() # throw away any part lines
        print "line=%s" % line

        self.start()
        print "waiting for some data..."
        while(self.ser.inWaiting() < 10): 
            print "waiting - inWaiting()=%d" % self.ser.inWaiting()
            time.sleep(1)
        print "wait over!"
        print "ignoring a few lines for start command to register..."
        for n in range(0,5):
            line = self.ser.readline() # throw away any part lines
            print "line=%s" % line
    
        #Initialise data lists.
        self.t=[] # initialize the data lists
        self.d1=[]
        self.d2=[]
        self.d3=[]
        self.d4=[]
        self.d5=[]
        self.d6=[]


        # Start web server
        self._ws = webServer.WebServer(self)
        webServer.setRoutes(self._ws)

        # Run our main loop.
        self.run()
    
    def run(self):
        """Run the main loop."""
        while(True):
            line = self.ser.readline() # read a line of text
            mylist = line.split('\r')[0].split(",") # parse it into CSV tokens
            if (mylist[0]=='data'):
                print mylist
                now = float(mylist[1])/1000 # time now in seconds
                self.t.append(float(mylist[1])/1000) # from first element as milliseconds
                self.d1.append(float(mylist[2])) # six data elements added to lists
                self.d2.append(float(mylist[3]))
                self.d3.append(float(mylist[4]))
                self.d4.append(float(mylist[5]))
                self.d5.append(float(mylist[6]))

                #Trim the lists to avoid using up all the memory!
                lenLists = len(self.t)
                if (lenLists>self.MAXLEN):
                    del self.t[0:(lenLists-self.MAXLEN)]
                    del self.d1[0:(lenLists-self.MAXLEN)]
                    del self.d2[0:(lenLists-self.MAXLEN)]
                    del self.d3[0:(lenLists-self.MAXLEN)]
                    del self.d4[0:(lenLists-self.MAXLEN)]
                    del self.d5[0:(lenLists-self.MAXLEN)]

                if(self.ser.inWaiting() < 100): # redraw only if you are caught up
                    plt.clf() # clear the figure
                    plt.plot(self.t,self.d1) # plot a line for each set of data
                    plt.plot(self.t,self.d2)
                    plt.plot(self.t,self.d3)
                    plt.plot(self.t,self.d4)
                    plt.plot(self.t,self.d5)
                    #plt.axis([now-300,now,min(d1)-50,max(d1)+50])
                    plt.axis([now-300,now,0,1000])
                    plt.xlabel("Time Since Boot [s]")
                    plt.grid(b=True, which='both', color='0.65',linestyle='-')
                    #plt.draw()
                    plt.savefig('www/out.png')
            elif (mylist[0]=='Set'):
                    self.settingsStr = line  # used by 'settings' function.
                    self.haveSettings = True
            else:
                if (len(line.split('\n')[0])>0):
                    print "Message %s" % line.split('\n')[0]

    def setSetPoint(self,setpoint):
        print "setSetPoint(%d)" % setpoint
        self.ser.write("setpoint=%d" % setpoint)

    def setKp(self,gain):
        print "setKp(%d)" % gain
        self.ser.write("kp=%d" % gain)

    def setKi(self,gain):
        print "setKi(%d)" % gain
        self.ser.write("ki=%d" % gain)

    def setKd(self,gain):
        print "setKd(%d)" % gain
        self.ser.write("kd=%d" % gain)

    def start(self):
        print "Sending start command"
        self.ser.write("start")
        print "returning to main loop...."

    def stop(self):
        print "sending stop command"
        self.ser.write("stop")

    def pumpstart(self):
        print "Sending start command"
        self.ser.write("pump=on")
        print "returning to main loop...."

    def pumpstop(self):
        print "sending stop command"
        self.ser.write("pump=off")

    def settings(self):
        self.haveSettings = False    # Flag - set by main loop if settings received.
        print "Requesting settings"
        self.ser.write("settings")

        print "Waiting for settings to be returned..."
        # wait for main loop to set haveSettings.
        while (not self.haveSettings):  
            pass
        print "found settings: %s" % self.settingsStr
        return self.settingsStr
示例#11
0
class bentv_ui:
    # Basic Configuration
    configFname = "config.ini"
    configSection = "bentv"
    debug = False

    # Initialise some instance variables.
    screen = None
    font = None
    textLine1 = "Camera_Mode"
    textLine2 = "Waiting for Button Press to move camera"
    presetNo = 1
    presetTxt = ['NULL','Behind Door', 'Corner', 'Chair', 'Bed']

    # UI Modes
    CAMERA_MODE = 0
    FITDECT_MODE = 1

    # Alarms
    ALARM_STATUS_OK = 0   # All ok, no alarms.
    ALARM_STATUS_WARN = 1 # Warning status
    ALARM_STATUS_FULL = 2 # Full alarm status.
    ALARM_STATUS_NOT_FOUND = 3 # Benjamin not found in image 
                               # (area below config area_threshold parameter)

    statusStrs = ("OK","Warning","ALARM!!!","Ben Not Found")
    screenBGColours = ( (0,0,255), # Blue for all ok
                        (128,128,0), # Yellow for warning
                        (255,0,0),  # Red for full alarm.
                        (128,128,128) # Grey for not found.
                        )
    alarmStatus = 0   # Current alarm status


    def __init__(self):
        """Initialise the bentv_ui class - reads the configuration file
        and initialises the screen and GPIO monitor"""
        print "bentv.__init__()"
        configPath = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)),
                                self.configFname)
        print configPath
        self.cfg = ConfigUtil(configPath,self.configSection)

        self.debug = self.cfg.getConfigBool("debug")
        if (self.debug): print "Debug Mode"
        
        self.debounce_ms = self.cfg.getConfigInt("debounce_ms")
        self.shortpress_ms = self.cfg.getConfigInt("shortpress_ms")
        
        self.hostname, self.ipaddr = self.getHostName()
        print self.hostname, self.ipaddr
        self.timeDown = 0.0
        self.presetNo = 1
        self.shortPress = False
        self.longPress = False
        self.initScreen()
        self.initGPIO()
        self.UIMode = self.CAMERA_MODE  # Next line changes mode to start in
                                        # FITDECT_MODE.
        self.changeUIMode()  # Initialises the messages.

    def getIpAddr(self,ifname):
        """Return the IP Address of the given interface (e.g 'wlan0')
        from http://raspberrypi.stackexchange.com/questions/6714/how-to-get-the-raspberry-pis-ip-address-for-ssh.
        """
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        return socket.inet_ntoa(fcntl.ioctl(
            s.fileno(),
            0x8915,  # SIOCGIFADDR
            struct.pack('256s', ifname[:15])
        )[20:24])

    def getHostName(self):
        """Returns the hostname and IP address of the wireless interface as a tuple.
        """
        hostname = socket.gethostname()
        ipaddr = self.getIpAddr("wlan0")
        return (hostname,ipaddr)

    def initGPIO(self):
        """Initialise the GPIO pins - note we use GPIO pin numbers, not physical
        pin numbers on rpi."""
        global haveGPIO
        pinNo = self.cfg.getConfigInt("gpiono")
        self.pinNo = pinNo
        if (self.debug): print "gpioNo = %d" % pinNo
        if (haveGPIO):
            GPIO.setmode(GPIO.BCM)
            GPIO.setup(pinNo, GPIO.IN, pull_up_down=GPIO.PUD_UP)
            # very long debounce time to prevent presses while camera is moving.
            #GPIO.add_event_detect(pinNo,
            #                      GPIO.FALLING, 
            #                      callback=self.buttonCallback
            #                      ,bouncetime=100)
        else:
            print "no GPIO - simulating camera move"
            self.moveCamera(1)

        self.lastButtonVal = 1
        self.lastButtonTime = time.time()

    def buttonCallback(self,pinNo):
        """ called on falling edge - it waits for rising edge to see how long
        the button press was. """
        print "Button Down"
        self.timeDown = time.time()
        GPIO.wait_for_edge(pinNo,GPIO.RISING)
        print "Button Up"
        print "time of press = %f" % (time.time()-self.timeDown)

    def pollButtons(self):
        """poll the buttons, and set a variable to say if we have detected
        a single, double or long click."""
        global haveGPIO
    
        if (haveGPIO):
            ip = GPIO.input(self.pinNo)
            tnow = time.time()
            if (ip != self.lastButtonVal):
                print "button state changed"
                if (ip):
                    keyPressLength = (tnow - self.lastButtonTime)*1000. #ms
                    print "Keypress Length = %f sec" % (keyPressLength)
                    if (keyPressLength<self.debounce_ms):
                        print "Ignoring very short keypress"
                        self.shortPress = False
                        self.longPress = False
                    elif (keyPressLength<self.shortpress_ms):
                        print "short press"
                        self.shortPress = True
                        self.longPress = False
                    else:
                        self.shortPress = False
                        self.longPress = True
                self.lastButtonVal = ip
                self.lastButtonTime = tnow
        else:
            pass
            # do nothing if we do not have GPIO access.

    def serviceUI(self):
        """Respond to button presses."""
        if (self.longPress):
            if (self.UIMode == self.CAMERA_MODE):
                self.moveCamera(self.pinNo)
            elif (self.UIMode == self.FITDECT_MODE):
                self.setFitDectBackground()
            else:
                print "Unrecognised UIMode %d." % self.UIMode
            self.longPress = False

        if (self.shortPress):
            self.changeUIMode()
            self.shortPress = False

    def changeUIMode(self):
        """Change the UI mode - toggle between camera and fit detector"""
        if (self.UIMode == self.CAMERA_MODE):
            print "Entering FitDetector Mode"
            self.textLine1 = "Fit Detector Mode"
            self.textLine2 = " Press long button press to reset background.  Short press to change mode."
            self.UIMode = self.FITDECT_MODE
        else:
            print "Entering Camera Mode"
            self.textLine1 = "Camera Mode"
            self.textLine2 = " Press long button press to move camera.  Short press to change mode."
            self.UIMode = self.CAMERA_MODE
            self.alarmStatus = self.ALARM_STATUS_NOT_FOUND
        self.lastDisplayUpdateTime = time.time() #Force message to display for
                                                 # a little while before being
                                                 # overwritten.
        self.display_text()

    def display_text(self):
        """ Write the given text onto the display area of the screen"""
        # Clear screen
        self.screen.fill(self.screenBGColours[self.alarmStatus])
        # Line 1 text
        txtImg = self.font.render(self.textLine1,
            True,(255,255,255))
        self.screen.blit(txtImg,(0,380))
        # Line 1 time
        tnow = time.localtime(time.time())
        txtStr = "%02d:%02d:%02d " % (tnow[3],tnow[4],tnow[5])
        w = self.font.size(txtStr)[0]
        txtImg = self.font.render(txtStr,
            True,(255,255,255))
        self.screen.blit(txtImg,(self.fbSize[0]-w,380))
        # Line 2 text
        txtImg = self.smallFont.render(self.textLine2,
            True,(255,255,255))
        self.screen.blit(txtImg,(0,400))
        # Line 2 network info
        txtStr = "Host: %s, IP: %s  " % (self.hostname, self.ipaddr)
        w = self.smallFont.size(txtStr)[0]
        txtImg = self.smallFont.render(txtStr,
                                       True,
                                       (255,255,255))
        
        self.screen.blit(txtImg,(self.fbSize[0]-w,400))
        pygame.display.update()

    def initScreen(self):    
        """Initialise the display using the pygame library"""
        drivers = ['x11', 'fbcon', 'svgalib']
        found = False
        disp_no = os.getenv("DISPLAY")
        if disp_no:
            print "I'm running under X display = {0}".format(disp_no)
        for driver in drivers:
            # Make sure that SDL_VIDEODRIVER is set
            if not os.getenv('SDL_VIDEODRIVER'):
                os.putenv('SDL_VIDEODRIVER', driver)
            try:
                pygame.display.init()
                print 'Using Driver: {0}.'.format(driver)
            except pygame.error:
                print 'Driver: {0} failed.'.format(driver)
                continue
            found = True
            break

        if not found:
            raise Exception('No suitable video driver found!')

        self.fbSize = (pygame.display.Info().current_w, pygame.display.Info().current_h)
        print "Framebuffer size: %d x %d" % self.fbSize
        if (disp_no):
            print "Using X11 window"
            winSize = (640,480)
            self.screen = pygame.display.set_mode(winSize)
            self.fbSize = winSize
        else:
            print "Using full screen framebuffer"
            self.screen = pygame.display.set_mode(self.fbSize, pygame.FULLSCREEN)
        print "blank screen..."
        self.screen.fill((0, 0, 255))        
        print "initialise fonts"
        pygame.font.init()
        self.font = pygame.font.Font(None,30)
        self.smallFont = pygame.font.Font(None,16)
        print "calling display_text()"
        self.display_text()
        print "initScreen complete"

    def moveCamera(self,pinNo):
        """Callback function when button is pressed"""
        print('moveCamera called by pin number %d. PresetNo=%d' % (pinNo,self.presetNo))
        h = httplib2.Http(".cache")
        h.add_credentials(self.cfg.getConfigStr('uname'), 
                          self.cfg.getConfigStr('passwd'))
        #resp, content = h.request("http://192.168.1.24/preset.cgi?-act=goto&-status=1&-number=%d" % self.presetNo,"GET")
        resp, content = h.request("%s/%s%d" % (self.cfg.getConfigStr('camaddr'),
                                               self.cfg.getConfigStr('cammoveurl'),
                                               self.presetNo),"GET")
        print "moved to preset %d - content=%s" % (self.presetNo,content)
        self.textLine1 = "Camera Position %d (%s)" % (self.presetNo, 
                                                       self.presetTxt[self.presetNo])
        self.presetNo += 1
        if (self.presetNo > 4): self.presetNo = 1

 
    def getBenFinderData(self):
        #print "getBenfinderData"
        h = httplib2.Http(".cache")
        h.add_credentials(self.cfg.getConfigStr('uname'), 
                          self.cfg.getConfigStr('passwd'))
        requestStr = "%s:%s/%s" % \
                     (self.cfg.getConfigStr('benfinderserver'),
                      self.cfg.getConfigStr('benfinderport'),
                      self.cfg.getConfigStr('benfinderurl'))
        #print requestStr
        try:
            resp, content = h.request(requestStr,
                                      "GET")
            dataDict = json.loads(content)
            self.alarmStatus = int(dataDict['status'])
            self.textLine1 = " Rate = %d bpm (status=%d - %s)" % \
                             (int(dataDict['rate']),
                              int(dataDict['status']),
                                  self.statusStrs[int(dataDict['status'])]
                             )
            #print dataDict['time_t']
            self.textLine2 = " Fit Detector Time = %s  " % dataDict['time_t']
            #print resp,content
            return True
        except:
            print "Error:",sys.exc_info()[0]
            self.textLine1 = "No Connection to Fit Detector"
            return False

    def setFitDectBackground(self):
        """Tell the fit detector to initialise its background image from
        the current image."""
        print "setFitDectBackground()"
        h = httplib2.Http(".cache")
        h.add_credentials(self.cfg.getConfigStr('uname'), 
                          self.cfg.getConfigStr('passwd'))
        requestStr = "%s:%s/%s" % \
                     (self.cfg.getConfigStr('benfinderserver'),
                      self.cfg.getConfigStr('benfinderport'),
                      self.cfg.getConfigStr('benfinderbackgroundurl'))
        print requestStr
        try:
            resp, content = h.request(requestStr,
                                      "GET")
            print resp,content
            self.textLine1 = "Fit Detector Background Image Reset"
            self.textLine2 = " Press button to reset background.  Long press to change mode."
        except:
            print "Error:",sys.exc_info()[0]
            self.textLine1 = "Error Initialising Fit Detector Background"
            self.textLine2 = " Press button to reset background.  Long press to change mode."
        self.lastDisplayUpdateTime = time.time() #Force message to display for
                                                 # a little while before being
                                                 # overwritten.
        self.display_text()


    def run(self):
        """bentv main loop"""
        self.lastDisplayUpdateTime = time.time()
        while 1: 
            tnow = time.time()
            self.pollButtons()
            self.serviceUI()
            if (tnow-self.lastDisplayUpdateTime >= 1.0):
                if (self.UIMode == self.FITDECT_MODE):
                    self.getBenFinderData()
            if (tnow-self.lastDisplayUpdateTime >= 1.0):
                self.display_text()
                self.lastDisplayUpdateTime = tnow
            #print "main loop..."
            time.sleep(0.2)
    def __init__(self,save=False, inFile = None):
        print "benFinder.__init__()"
        print os.path.realpath(__file__)
        configPath = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)),
                                self.configFname)
        print configPath
        self.cfg = ConfigUtil(configPath,self.configSection)

        self.debug = self.cfg.getConfigBool("debug")
        if (self.debug): print "Debug Mode"

        self._wkdir = self.cfg.getConfigStr("working_directory")
        if (self.debug): print "working_directory=%s\n" % self._wkdir
        self._tmpdir = self.cfg.getConfigStr("tmpdir")
        if (self.debug): print "tmpdir=%s\n" % self._tmpdir


        # Check if we are running from live kinect or a file.
        if (inFile):
            device = depth.CV_CAP_FILE
        else:
            device = depth.CV_CAP_FREENECT

        # Initialise the captureManager
        self._captureManager = CaptureManager(
            device, None, True, inFile=inFile)
        self._captureManager.channel = depth.CV_CAP_OPENNI_DEPTH_MAP

        # If we are runnign from a file, use the first frame as the
        # background image.
        if (inFile):
            self.saveBgImg()

        # If we have asked to save the background image, do that, and exit,
        # otherwise initialise the seizure detector.
        if (save):
            self.saveBgImg()
        else:
            self.loadBgImg()
            self.autoBackgroundImg = None
            self._status = self.ALARM_STATUS_OK
            self._ts = TimeSeries(tslen=self.cfg.getConfigInt("timeseries_length"))
            self._frameCount = 0
            self._outputFrameCount = 0
            self._nPeaks = 0
            self._ts_time = 0
            self._rate = 0
            self._ws = webServer.benWebServer(self)
            self._ws.setBgImg("%s/%s" % (self._tmpdir,
                    self.cfg.getConfigStr("background_depth")))
            self._ws.setChartImg("%s/%s" % (self._tmpdir,
                    self.cfg.getConfigStr("chart_fname")))
            self._ws.setRawImg("%s/%s" % (self._tmpdir,
                    self.cfg.getConfigStr("raw_image_fname")))
            self._ws.setMaskedImg("%s/%s" % (self._tmpdir,
                    self.cfg.getConfigStr("masked_image_fname")))
            self._ws.setDataFname("%s/%s" % (self._tmpdir,
                    self.cfg.getConfigStr("data_fname")))
            self._ws.setAnalysisResults({})
            webServer.setRoutes(self._ws)
            self.run()
class BenFinder(object):
    configFname = "config.ini"
    configSection = "benFinder"

    ALARM_STATUS_OK = 0   # All ok, no alarms.
    ALARM_STATUS_WARN = 1 # Warning status
    ALARM_STATUS_FULL = 2 # Full alarm status. 
    ALARM_STATUS_NOT_FOUND = 3 # Benjamin not found in image 
                               # (area below config area_threshold parameter)

    def __init__(self,save=False, inFile = None):
        print "benFinder.__init__()"
        print os.path.realpath(__file__)
        configPath = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)),
                                self.configFname)
        print configPath
        self.cfg = ConfigUtil(configPath,self.configSection)

        self.debug = self.cfg.getConfigBool("debug")
        if (self.debug): print "Debug Mode"

        self._wkdir = self.cfg.getConfigStr("working_directory")
        if (self.debug): print "working_directory=%s\n" % self._wkdir
        self._tmpdir = self.cfg.getConfigStr("tmpdir")
        if (self.debug): print "tmpdir=%s\n" % self._tmpdir


        # Check if we are running from live kinect or a file.
        if (inFile):
            device = depth.CV_CAP_FILE
        else:
            device = depth.CV_CAP_FREENECT

        # Initialise the captureManager
        self._captureManager = CaptureManager(
            device, None, True, inFile=inFile)
        self._captureManager.channel = depth.CV_CAP_OPENNI_DEPTH_MAP

        # If we are runnign from a file, use the first frame as the
        # background image.
        if (inFile):
            self.saveBgImg()

        # If we have asked to save the background image, do that, and exit,
        # otherwise initialise the seizure detector.
        if (save):
            self.saveBgImg()
        else:
            self.loadBgImg()
            self.autoBackgroundImg = None
            self._status = self.ALARM_STATUS_OK
            self._ts = TimeSeries(tslen=self.cfg.getConfigInt("timeseries_length"))
            self._frameCount = 0
            self._outputFrameCount = 0
            self._nPeaks = 0
            self._ts_time = 0
            self._rate = 0
            self._ws = webServer.benWebServer(self)
            self._ws.setBgImg("%s/%s" % (self._tmpdir,
                    self.cfg.getConfigStr("background_depth")))
            self._ws.setChartImg("%s/%s" % (self._tmpdir,
                    self.cfg.getConfigStr("chart_fname")))
            self._ws.setRawImg("%s/%s" % (self._tmpdir,
                    self.cfg.getConfigStr("raw_image_fname")))
            self._ws.setMaskedImg("%s/%s" % (self._tmpdir,
                    self.cfg.getConfigStr("masked_image_fname")))
            self._ws.setDataFname("%s/%s" % (self._tmpdir,
                    self.cfg.getConfigStr("data_fname")))
            self._ws.setAnalysisResults({})
            webServer.setRoutes(self._ws)
            self.run()
    
    def run(self):
        """Run the main loop."""
        while(True):
            self._captureManager.enterFrame()

            frame = self._captureManager.frame
            
            if frame is not None:
                if (self.autoBackgroundImg == None):
                    self.autoBackgroundImg = numpy.float32(frame)
                rawFrame = frame.copy()
                # First work out the region of interest by 
                #    subtracting the fixed background image 
                #    to create a mask.
                #print frame
                #print self._background_depth_img
                absDiff = cv2.absdiff(frame,self._background_depth_img)
                benMask,maskArea = filters.getBenMask(absDiff,8)

                cv2.accumulateWeighted(frame,
                                       self.autoBackgroundImg,0.05)
                # Convert the background image into the same format
                # as the main frame.
                #bg = self.autoBackgroundImg
                bg = cv2.convertScaleAbs(self.autoBackgroundImg,
                                         alpha=1.0)
                # Subtract the background from the frame image
                cv2.absdiff(frame,bg,frame)
                # Scale the difference image to make it more sensitive
                # to changes.
                cv2.convertScaleAbs(frame,frame,alpha=100)
                # Apply the mask so we only see the test subject.
                frame = cv2.multiply(frame,benMask,dst=frame,dtype=-1)

                if (maskArea <= self.cfg.getConfigInt('area_threshold')):
                    bri=(0,0,0)
                else:
                    # Calculate the brightness of the test subject.
                    bri = filters.getMean(frame,benMask)

                # Add the brightness to the time series ready for analysis.
                self._ts.addSamp(bri[0])
                self._ts.addImg(rawFrame)

                # Write timeseries to a file every 'output_framecount' frames.
                if (self._outputFrameCount >= self.cfg.getConfigInt('output_framecount')):
                    # Write timeseries to file
                    self._ts.writeToFile("%s/%s" % \
                        ( self.cfg.getConfigStr('output_directory'),
                          self.cfg.getConfigStr('ts_fname')
                      ))
                    self._outputFrameCount = 0
                else:
                    self._outputFrameCount = self._outputFrameCount + 1
                    

                # Only do the analysis every 15 frames (0.5 sec), or whatever
                # is specified in configuration file analysis_framecount
                # parameter.
                if (self._frameCount < self.cfg.getConfigInt('analysis_framecount')):
                    self._frameCount = self._frameCount +1
                else:
                    # Look for peaks in the brightness (=movement).
                    self._nPeaks,self._ts_time,self._rate = self._ts.findPeaks()
                    #print "%d peaks in %3.2f sec = %3.1f bpm" % \
                    #    (nPeaks,ts_time,rate)

                    oldStatus = self._status
                    if (maskArea > self.cfg.getConfigInt('area_threshold')):
                        # Check for alarm levels
                        if (self._rate > self.cfg.getConfigInt(
                                "rate_warn")):
                            self._status= self.ALARM_STATUS_OK
                        elif (self._rate > self.cfg.getConfigInt(
                                "rate_alarm")):
                            self._status= self.ALARM_STATUS_WARN
                        else:
                            self._status= self.ALARM_STATUS_FULL
                    else:
                        self._status = self.ALARM_STATUS_NOT_FOUND


                    if (oldStatus == self.ALARM_STATUS_OK and
                        self._status == self.ALARM_STATUS_WARN) or \
                        (oldStatus == self.ALARM_STATUS_WARN and 
                         self._status == self.ALARM_STATUS_FULL):
                                # Write timeseries to file
                                self._ts.writeToFile("%s/%s" % \
                                    ( self.cfg.getConfigStr('output_directory'),
                                      self.cfg.getConfigStr('alarm_ts_fname')
                                  ),bgImg=self._background_depth_img)
                        

                    # Collect the analysis results together and send them
                    # to the web server.
                    resultsDict = {}
                    resultsDict['fps'] = "%3.0f" % self.fps
                    resultsDict['bri'] = "%4.0f" % self._ts.mean
                    resultsDict['area'] = "%6.0f" % maskArea
                    resultsDict['nPeaks'] = "%d" % self._nPeaks
                    resultsDict['ts_time'] = self._ts_time
                    resultsDict['rate'] = "%d" % self._rate
                    resultsDict['time_t'] = time.ctime()
                    resultsDict['status'] = self._status
                    self._ws.setAnalysisResults(resultsDict)

                    # Write the results to file as a json string
                    utils.writeJSON(resultsDict,"%s/%s" % \
                                    (self._tmpdir,
                                     self.cfg.getConfigStr("data_fname")))
                    utils.writeLog(resultsDict,"%s/%s" % \
                                    (self._tmpdir,
                                     "benFinder_alarms.log"))
                    # Plot the graph of brightness, and save the images
                    # to disk.
                    self._ts.plotRawData(
                        file=True,
                        fname="%s/%s" % \
                        (self._tmpdir,self.cfg.getConfigStr("chart_fname")))
                        
                    cv2.imwrite("%s/%s" % (self._tmpdir,
                                           self.cfg.getConfigStr(
                                               "raw_image_fname")),
                                rawFrame)
                    cv2.imwrite("%s/%s" % (self._tmpdir,self.cfg.getConfigStr(
                        "masked_image_fname")),
                        frame)
                    self._frameCount = 0
            else:
                print "Null frame received - assuming end of file and exiting"
                break
            self._captureManager.exitFrame()
                

    @property
    def fps(self):
        return self._captureManager.fps

    @property
    def nPeaks(self):
        return self._nPeaks

    @property
    def ts_time(self):
        return self._ts_time

    @property
    def rate(self):
        return self._rate

    @property
    def rawImgFname(self):
        return self.cfg.getConfigStr("raw_image_fname")

    @property
    def maskedImgFname(self):
        return self.cfg.getConfigStr("masked_image_fname")

    @property
    def chartImgFname(self):
        return self.cfg.getConfigStr("chart_fname")

    def saveBgImg(self):
        """ Write a new background image to the appropriate file location."""
        if (self._captureManager.hasEnteredFrame):
            self._captureManager.exitFrame()
        self._captureManager.enterFrame()
        print "Writing image to %s." % self.cfg.getConfigStr("background_depth")
        self._captureManager.writeImage("%s/%s" % 
                                        (self._wkdir,
                                         self.cfg.getConfigStr("background_depth")
                                     ))
        print self._captureManager.frame
        print self._captureManager.frame.dtype
        self._captureManager.exitFrame()
        self.loadBgImg()

    def loadBgImg(self):
        print "Loading background image %s/%s." % \
            (self._wkdir,self.cfg.getConfigStr("background_depth"))
        self._background_depth_img = cv2.imread("%s/%s" % \
                    (self._wkdir,self.cfg.getConfigStr("background_depth")),
                                                cv2.CV_LOAD_IMAGE_GRAYSCALE)
        #                                        cv2.CV_LOAD_IMAGE_UNCHANGED)
        print self._background_depth_img
        print self._background_depth_img.dtype