Exemple #1
0
def main():
    reqArgs = [
        ['o', 'outputFile', 'filename for output CSV of fire x camera matches with available archives'],
    ]
    optionalArgs = [
        ['g', 'longitude', 'longitude of fire', float],
        ['t', 'latitude', 'latitude of fire', float],
        ['s', 'startTime', 'start time of fire'],
    ]
    args = collect_args.collectArgs(reqArgs, optionalArgs=optionalArgs, parentParsers=[goog_helper.getParentParser()])
    googleServices = goog_helper.getGoogleServices(settings, args)
    dbManager = db_manager.DbManager(sqliteFile=settings.db_file)
    outputFile = open(args.outputFile, 'w', newline='')
    outputCsv = csv.writer(outputFile, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)

    camArchives = img_archive.getHpwrenCameraArchives(googleServices['sheet'], settings)

    locMatches = getLocationMatches(dbManager, args.longitude, args.latitude, args.startTime)
    totalMatches = len(locMatches)
    numOutput = 0
    for rowNum,locMatch in enumerate(locMatches):
        timeDT = datetime.datetime.fromtimestamp(locMatch['timestamp'])
        cams = locMatch['cameraids'].split(',')
        availCams = []
        for cameraID in cams:
            if isCamArchiveAvailable(camArchives, cameraID, timeDT):
                availCams.append(cameraID)
        # logging.warning('availCams %d: %s', len(availCams), availCams)
        if len(availCams) > 0:
            outputRow(outputCsv, locMatch, timeDT, availCams)
            numOutput += 1
        if (rowNum % 10) == 0:
            logging.warning('Processing %d of %d, output %d', rowNum, totalMatches, numOutput)

    logging.warning('Processed %d, output %d', totalMatches, numOutput)
def main():
    reqArgs = []
    args = collect_args.collectArgs(
        reqArgs,
        optionalArgs=[],
        parentParsers=[goog_helper.getParentParser()])
    dbManager = db_manager.DbManager(sqliteFile=settings.db_file)
    fires = getUnparsedFires(dbManager)
    parseDates(dbManager, fires)
Exemple #3
0
def main():
    reqArgs = [
        ["f", "fileName", "name of file containing fire_coords.py output"],
    ]
    args = collect_args.collectArgs(
        reqArgs,
        optionalArgs=[],
        parentParsers=[goog_helper.getParentParser()])
    dbManager = db_manager.DbManager(sqliteFile=settings.db_file)
    insertFires(dbManager, args.fileName)
def main():
    reqArgs = [
        ["m", "mode", "basemaps, city"],
    ]
    optArgs = [
        ["l", "locationID", "camera locationID"],
    ]
    args = collect_args.collectArgs(reqArgs, optionalArgs=optArgs)
    dbManager = db_manager.DbManager(sqliteFile=settings.db_file,
                                     psqlHost=settings.psqlHost,
                                     psqlDb=settings.psqlDb,
                                     psqlUser=settings.psqlUser,
                                     psqlPasswd=settings.psqlPasswd)
    gmaps = googlemaps.Client(key=settings.mapsKey)
    locations = getCameraLocations(dbManager)
    if args.locationID:
        locations = list(
            filter(lambda x: x['locationid'] == args.locationID.strip(),
                   locations))
    for location in locations:
        logging.warning('loc %s', location)
        if args.mode == 'basemaps':
            mapFiles = []
            for zoom in range(settings.MAP_ZOOM_MIN,
                              settings.MAP_ZOOM_MAX + 1):
                mapFileGCS = uploadMapGCS(location['latitude'],
                                          location['longitude'],
                                          location['locationid'], zoom)
                mapFiles.append(mapFileGCS)
            if len(mapFiles) > 0:
                logging.warning('updating DB %s', location['locationid'])
                updateCameraMaps(dbManager, location['locationid'], mapFiles)
        elif args.mode == 'city':
            geoCodeRes = gmaps.reverse_geocode(
                (location['latitude'], location['longitude']))
            for geoCodeComp in geoCodeRes:
                cityName = cityNameFromComp(geoCodeComp)
                if re.findall('^[A-Za-z ]+$',
                              cityName):  # contains only alphabet and spaces
                    break
            logging.warning('city for %s is %s', location['locationid'],
                            cityName)
            updateCameraCity(dbManager, location['locationid'], cityName)
Exemple #5
0
def main():
    reqArgs = [
        ["m", "mapFile", "base map"],
        ["l", "leftLongitude", "longitude of left edge", float],
        ["r", "rightLongitude", "longitude of right edge", float],
        ["t", "topLatitude", "latitude of top edge", float],
        ["b", "bottomLatitude", "latitude of bottom edge", float],
    ]
    optArgs = []
    args = collect_args.collectArgs(reqArgs, optionalArgs=optArgs)
    dbManager = db_manager.DbManager(sqliteFile=settings.db_file,
                                     psqlHost=settings.psqlHost,
                                     psqlDb=settings.psqlDb,
                                     psqlUser=settings.psqlUser,
                                     psqlPasswd=settings.psqlPasswd)
    locations = getCameraLocations(dbManager)
    logging.warning('Found %d locations', len(locations))
    mapImg = Image.open(args.mapFile)
    assert args.leftLongitude < args.rightLongitude
    assert args.topLatitude > args.bottomLatitude
    diffLat = args.topLatitude - args.bottomLatitude
    diffLong = args.rightLongitude - args.leftLongitude
    radiusDegrees = 0.3

    for location in locations:
        numNearby = len(
            list(
                filter(
                    lambda x: ((x['longitude'] - location['longitude'])**2 +
                               (x['latitude'] - location['latitude'])**2) <
                    radiusDegrees**2, locations)))
        # logging.warning('loc %s, %s', location, numNearby)
        centerX = (location['longitude'] -
                   args.leftLongitude) / diffLong * mapImg.size[0]
        centerY = mapImg.size[1] - (location['latitude'] - args.bottomLatitude
                                    ) / diffLat * mapImg.size[1]
        opacityRatio = min(4 / numNearby, 1)
        mapImg = drawCircle(mapImg, centerX, centerY,
                            radiusDegrees / diffLat * mapImg.size[1],
                            opacityRatio)

    mapImg.save('amap.jpg', quality=95)
def main():
    reqArgs = [
        ["m", "mode", "list, add, checkdb"],
    ]
    optArgs = [
        ["s", "startTime", "starting date and time in ISO format (e.g., 2019-02-22T14:34:56 in Pacific time zone)"],
        ["c", "cameraID", "ID of the camera (e.g., mg-n-mobo-c)"],
        ["a", "heading", "view heading", int],
        ["w", "angularWidth", "ignored view width", int],
        ["n", "noState", "(optional) no changes to state"],
        ["f", "maxFalse", "(optional) maximum false positives to check (default 10)", int],
        ["r", "restrictType", "Only process images from cameras of given type"],
    ]
    args = collect_args.collectArgs(reqArgs, optionalArgs=optArgs)
    dbManager = db_manager.DbManager(sqliteFile=settings.db_file,
                                     psqlHost=settings.psqlHost, psqlDb=settings.psqlDb,
                                     psqlUser=settings.psqlUser, psqlPasswd=settings.psqlPasswd)
    ignoredViews = dbManager.get_ignoredViews()
    logging.warning('Num views: %d', len(ignoredViews))
    numFalse = args.maxFalse if args.maxFalse else 10
    if args.mode == 'list':
        logging.warning('All views: %s', ignoredViews)
    elif args.mode == 'add':
        addNew(dbManager, ignoredViews, args.cameraID, args.heading, args.angularWidth)
    elif args.mode == 'checkdb':
        recents = getRecentFalse(dbManager, numFalse, startTimeStr=args.startTime, restrictType=args.restrictType)
        for entry in recents:
            logging.warning('count %d: cam %s, camHead %s, min %s, max %s', entry['ct'], entry['cameraname'], entry['camheading'], entry['minx'], entry['maxx'])
            fov = img_archive.getCameraFov(entry['cameraname'])
            imgSizeX = img_archive.getCameraSizeX(entry['cameraname'])
            # logging.warning('cam %s: fov %s, sizeX %s', entry['cameraname'], fov, imgSizeX)
            (fireHeading, rangeAngle) = img_archive.getHeadingRange(entry['camheading'], fov, entry['minx'], entry['maxx'], imgSizeX)
            logging.warning('cam %s: fireHeading %s, rangeAngle %s', entry['cameraname'], round(fireHeading), round(rangeAngle))
            if not args.noState:
                addNew(dbManager, ignoredViews, entry['cameraname'], fireHeading, rangeAngle)
                ignoredViews = dbManager.get_ignoredViews() # update state
    else:
        logging.error('unexpected mode: %s', args.mode)
        exit(1)
    return
Exemple #7
0
Takes csv export of Images table and push it to sqlite DB

"""

import os, sys
from firecam.lib import settings
from firecam.lib import collect_args
from firecam.lib import db_manager

import time
import csv
import dateutil.parser

manager = db_manager.DbManager(sqliteFile=settings.db_file,
                               psqlHost=settings.psqlHost,
                               psqlDb=settings.psqlDb,
                               psqlUser=settings.psqlUser,
                               psqlPasswd=settings.psqlPasswd)


def insert_entire_images(csvFile):
    csvreader = csv.reader(csvFile)
    for row in csvreader:
        dt = dateutil.parser.parse(row[4])
        unixTime = int(time.mktime(dt.timetuple()))
        parsed = {
            'ImageID': row[0],
            'ImageClass': row[1],
            'FireName': row[2],
            'CameraName': row[3],
            'Timestamp': unixTime,
Exemple #8
0
def main():
    reqArgs = [
        [
            "s", "startTime",
            "starting date and time in ISO format (e.g., 2019-02-22T14:34:56 in Pacific time zone)"
        ],
    ]
    optArgs = [
        ["c", "cameraID", "ID (code name) of camera"],
        ['n', 'longitude', 'longitude of fire', float],
        ['t', 'latitude', 'latitude of fire', float],
        [
            'm', 'maxDistance',
            '(optional default=20) max distance in miles from fire', float
        ],
        [
            "e", "endTime",
            "ending date and time in ISO format (e.g., 2019-02-22T14:34:56 in Pacific time zone)"
        ],
        [
            "d", "durationMinutes",
            "alternative spec for endTime as start + duration", int
        ],
        [
            "g", "gapMinutes",
            "override default of 1 minute gap between images to download"
        ],
        ["o", "outputDir", "directory to save the output image"],
    ]

    args = collect_args.collectArgs(
        reqArgs,
        optionalArgs=optArgs,
        parentParsers=[goog_helper.getParentParser()])
    googleServices = goog_helper.getGoogleServices(settings, args)
    gapMinutes = int(args.gapMinutes) if args.gapMinutes else 1
    distanceMiles = float(args.maxDistance if args.maxDistance else 20)
    outputDir = args.outputDir if args.outputDir else settings.downloadDir
    startTimeDT = dateutil.parser.parse(args.startTime)
    if args.endTime:
        endTimeDT = dateutil.parser.parse(args.endTime)
    elif args.durationMinutes:
        durationDelta = datetime.timedelta(seconds=60 * args.durationMinutes)
        endTimeDT = startTimeDT + durationDelta
    else:
        endTimeDT = startTimeDT
    assert startTimeDT.year == endTimeDT.year
    assert startTimeDT.month == endTimeDT.month
    assert startTimeDT.day == endTimeDT.day
    assert endTimeDT >= startTimeDT
    if args.cameraID:
        assert (not args.latitude) and (not args.longitude)
        cameras = [args.cameraID]
    else:
        assert args.latitude and args.longitude
        dbManager = db_manager.DbManager(sqliteFile=settings.db_file,
                                         psqlHost=settings.psqlHost,
                                         psqlDb=settings.psqlDb,
                                         psqlUser=settings.psqlUser,
                                         psqlPasswd=settings.psqlPasswd)
        cameras = getNearbyCameras(dbManager, args.latitude, args.longitude,
                                   distanceMiles)
        logging.warning('Matched cmaeras: %s', cameras)

    camArchives = img_archive.getHpwrenCameraArchives(settings.hpwrenArchives)
    allFiles = []
    for cameraID in cameras:
        camFiles = img_archive.getHpwrenImages(googleServices, settings,
                                               outputDir, camArchives,
                                               cameraID, startTimeDT,
                                               endTimeDT, gapMinutes)
        if camFiles:
            allFiles += camFiles
    if allFiles:
        logging.warning('Found %d files.', len(allFiles))
    else:
        logging.error('No filed matched')
def main():
    reqArgs = [
        ["o", "outputFile", "output file name"],
        ["i", "inputCsv", "csvfile with fire/detection data"],
        ['m', "mode", "mode: votepoly or camdir or pruned"],
    ]
    optArgs = [
        ["s", "startRow", "starting row"],
        ["e", "endRow", "ending row"],
    ]
    args = collect_args.collectArgs(reqArgs, optionalArgs=optArgs, parentParsers=[goog_helper.getParentParser()])
    startRow = int(args.startRow) if args.startRow else 0
    endRow = int(args.endRow) if args.endRow else 1e9
    mode = args.mode
    assert mode == 'votepoly' or mode == 'camdir' or mode == 'pruned'
    outFile = open(args.outputFile, 'w')
    dbManager = db_manager.DbManager(sqliteFile=settings.db_file,
                                     psqlHost=settings.psqlHost, psqlDb=settings.psqlDb,
                                     psqlUser=settings.psqlUser, psqlPasswd=settings.psqlPasswd)

    lastCam = None
    lastTime = None
    random.seed(0)
    with open(args.inputCsv) as csvFile:
        csvreader = csv.reader(csvFile)
        for (rowIndex, csvRow) in enumerate(csvreader):
            if rowIndex < startRow:
                continue
            if rowIndex > endRow:
                print('Reached end row', rowIndex, endRow)
                break
            if mode == 'votepoly':
                [cameraID, timestamp, score, polygon, sourcePolygons, isRealFire] = csvRow[:6]
                timestamp = int(timestamp)
                logging.warning('Processing row: %d, cam: %s, ts: %s', rowIndex, cameraID, timestamp)
                if cameraID == lastCam and timestamp == lastTime:
                    logging.warning('Duplicate row: %d, cam: %s, ts: %s', rowIndex, cameraID, timestamp)
                lastCam = cameraID
                lastTime = timestamp
                centroid = getCentroid(polygon)
                if timestamp < 1607786165: #sourcePolygons didn't exist before this
                    if isRealFire:
                        numPolys = round(getRandInterpolatedVal(settings.percentilesNumPolyFire))
                    else:
                        numPolys = round(getRandInterpolatedVal(settings.percentilesNumPolyOther))
                else:
                    numPolys = 1
                    if sourcePolygons:
                        sourcePolygonsArr = json.loads(sourcePolygons)
                        numPolys = len(sourcePolygonsArr)
                cameraID = patchCameraId(cameraID)
                camInfo = dbManager.getCameraMapLocation(cameraID)
                if camInfo == None:
                    logging.warning('Skipping row with camera without meta %s', cameraID)
                    continue
                (mapImgGCS, camLatitude, camLongitude) = camInfo
            else:
                if mode == 'camdir':
                    [cameraID, isoTime, direction] = csvRow[:3]
                    logging.warning('Processing row: %d, cam: %s, ts: %s', rowIndex, cameraID, isoTime)
                    timestamp = time.mktime(dateutil.parser.parse(isoTime).timetuple())
                    if 'center left' in direction:
                        offset = -20
                    elif 'center right' in direction:
                        offset = 20
                    elif 'center' in direction:
                        offset = 0
                    elif 'left' in direction:
                        offset = -40
                    elif 'right' in direction:
                        offset = 40
                    else:
                        logging.error('Unexpected dir row: %d, dir: %s', rowIndex, direction)
                        continue
                elif mode == 'pruned':
                    [_cropName, minX, _minY, maxX, _maxY, fileName] = csvRow[:6]
                    minX = int(minX)
                    maxX = int(maxX)
                    nameParsed = img_archive.parseFilename(fileName)
                    cameraID = nameParsed['cameraID']
                    cameraID = patchCameraId(cameraID)
                    timestamp = nameParsed['unixTime']
                    dateStr = nameParsed['isoStr'][:nameParsed['isoStr'].index('T')]
                    if dateStr == lastTime and cameraID == lastCam:
                        # logging.warning('Skip same fire. row %s', rowIndex)
                        continue
                    lastCam = cameraID
                    lastTime = dateStr
                    localFilePath = os.path.join(settings.downloadDir, fileName)
                    if not os.path.isfile(localFilePath):
                        logging.warning('Skip missing file %s, row %s', fileName, rowIndex)
                        continue
                    img = Image.open(localFilePath)
                    degreesInView = img_archive.getCameraFov(cameraID)
                    centerX = (minX + maxX) / 2
                    offset = centerX / img.size[0] * degreesInView - degreesInView/2
                    img.close()
                (mapImgGCS, camLatitude, camLongitude) = dbManager.getCameraMapLocation(cameraID)
                camHeading = img_archive.getHeading(cameraID)
                heading = (camHeading + offset) % 360
                angle = 90 - heading
                distanceDegrees = 0.2 # approx 14 miles
                fireLat = camLatitude + math.sin(angle*math.pi/180)*distanceDegrees
                fireLong = camLongitude + math.cos(angle*math.pi/180)*distanceDegrees
                centroid = (fireLat, fireLong)
                score = getRandInterpolatedVal(settings.percentilesScoreFire)
                numPolys = round(getRandInterpolatedVal(settings.percentilesNumPolyFire))
                isRealFire = 1
                logging.warning('Processing row: %d, heading: %s, centroid: %s, score: %s, numpoly: %s', rowIndex, heading, centroid, score, numPolys)
            if not keepData(score, centroid, numPolys, isRealFire):
                logging.warning('Skipping Mexico fire row %d, camera %s', rowIndex, cameraID)
                continue
            (weatherCentroid, weatherCamera) = weather.getWeatherData(dbManager, cameraID, timestamp, centroid, (camLatitude, camLongitude))
            if not weatherCentroid:
                logging.warning('Skipping row %d', rowIndex)
                continue
            # logging.warning('Weather %s', weatherCentroid)
            outputWithWeather(outFile, score, timestamp, centroid, numPolys, weatherCentroid, weatherCamera, isRealFire)

            logging.warning('Processed row: %d, cam: %s, ts: %s', rowIndex, cameraID, timestamp)
    outFile.close()
Exemple #10
0
def main():
    reqArgs = [
        ["o", "operation", "add (includes update), delete, list"],
    ]
    optArgs = [
        ["n", "name", "name (ID) of user"],
        ["m", "email", "email address of user"],
        ["p", "phone", "phone number of user"],
        ["s", "startTime", "starting date and time in ISO format (e.g., 2019-02-22T14:34:56 in Pacific time zone)"],
        ["e", "endTime", "ending date and time in ISO format (e.g., 2019-02-22T14:34:56 in Pacific time zone)"],
    ]
    args = collect_args.collectArgs(reqArgs, optionalArgs=optArgs)
    startTime = parseTimeStr(args.startTime) if args.startTime else None
    endTime = parseTimeStr(args.endTime) if args.endTime else None
    dbManager = db_manager.DbManager(sqliteFile=settings.db_file,
                                    psqlHost=settings.psqlHost, psqlDb=settings.psqlDb,
                                    psqlUser=settings.psqlUser, psqlPasswd=settings.psqlPasswd)
    notifications = dbManager.getNotifications()
    activeEmails = dbManager.getNotifications(filterActiveEmail=True)
    activePhones = dbManager.getNotifications(filterActivePhone=True)
    logging.warning('Num all notifications: %d.  Active emails: %d.  Active phones: %d',
                     len(notifications), len(activeEmails), len(activePhones))
    if args.operation == 'list':
        for n in notifications:
            printNoficiation(n)
        return
    assert args.name
    matching = list(filter(lambda x: x['name'] == args.name, notifications))
    logging.warning('Found %d matching for name %s', len(matching), args.name)
    if matching:
        printNoficiation(matching[0])
    if args.operation == 'add':
        assert startTime and endTime
        assert endTime >= startTime
        assert args.email or args.phone
        if not matching:
            # insert new entry
            dbRow = {
                'name': args.name,
            }
            if args.email:
                dbRow['email'] = args.email
                dbRow['EmailStartTime'] = startTime
                dbRow['EmailEndTime'] = endTime
            if args.phone:
                dbRow['phone'] = args.phone
                dbRow['PhoneStartTime'] = startTime
                dbRow['PhoneEndTime'] = endTime
            dbManager.add_data('notifications', dbRow)
            logging.warning('Successfully added notification for %s', args.name)
        else:
            # update existing entry
            if args.email:
                sqlTemplate = """UPDATE notifications SET email='%s',EmailStartTime=%s,EmailEndTime=%s WHERE name = '%s' """
                sqlStr = sqlTemplate % (args.email, startTime, endTime, args.name)
                dbManager.execute(sqlStr)
            if args.phone:
                sqlTemplate = """UPDATE notifications SET phone='%s',PhoneStartTime=%s,PhoneEndTime=%s WHERE name = '%s' """
                sqlStr = sqlTemplate % (args.phone, startTime, endTime, args.name)
                dbManager.execute(sqlStr)
            logging.warning('Successfully updated notification for %s', args.name)
        notifications = dbManager.getNotifications()
        matching = list(filter(lambda x: x['name'] == args.name, notifications))
        printNoficiation(matching[0])
    elif args.operation == 'delete':
        sqlTemplate = """DELETE FROM notifications WHERE name = '%s' """
        sqlStr = sqlTemplate % (args.name)
        dbManager.execute(sqlStr)
    else:
        logging.error('Unexpected operation: %s', args.operation)
Exemple #11
0
def main():
    reqArgs = [
        ["m", "mode", "add, delete, enable, disable, stats, or list"],
    ]
    optArgs = [
        ["c", "cameraID", "ID of the camera (e.g., mg-n-mobo-c)"],
        ["u", "url", "url to get images from camera"],
    ]
    args = collect_args.collectArgs(reqArgs, optionalArgs=optArgs)
    dbManager = db_manager.DbManager(sqliteFile=settings.db_file,
                                     psqlHost=settings.psqlHost, psqlDb=settings.psqlDb,
                                     psqlUser=settings.psqlUser, psqlPasswd=settings.psqlPasswd)
    cameraInfos = dbManager.get_sources(activeOnly=False)
    logging.warning('Num all cameras: %d', len(cameraInfos))
    logging.warning('Num active cameras: %d', len(list(filter(lambda x: x['dormant'] == 0, cameraInfos))))
    if args.mode == 'list':
        logging.warning('All cameras: %s', list(map(lambda x: x['name'], cameraInfos)))
        return
    matchingCams = list(filter(lambda x: x['name'] == args.cameraID, cameraInfos))
    logging.warning('Found %d matching cams for ID %s', len(matchingCams), args.cameraID)

    if args.mode == 'add':
        if len(matchingCams) != 0:
            logging.error('Camera with ID %s already exists: %s', args.cameraID, matchingCams)
            exit(1)
        dbRow = {
            'name': args.cameraID,
            'url': args.url,
            'dormant': 0,
            'randomID': random.random(),
            'last_date': datetime.datetime.now().isoformat()
        }
        dbManager.add_data('sources', dbRow)
        logging.warning('Successfully added camera %s', args.cameraID)
        return

    if len(matchingCams) != 1:
        logging.error('Cannot find camera with ID %s: %s', args.cameraID, matchingCams)
        exit(1)
    camInfo = matchingCams[0]
    logging.warning('Cam details: %s', camInfo)

    if args.mode == 'delete':
        sqlTemplate = """DELETE FROM sources WHERE name = '%s' """
        execCameraSql(dbManager, sqlTemplate, args.cameraID, isQuery=False)
        return

    if args.mode == 'enable':
        if camInfo['dormant'] == 0:
            logging.error('Camera already enabled: dormant=%d', camInfo['dormant'])
            exit(1)
        sqlTemplate = """UPDATE sources SET dormant=0 WHERE name = '%s' """
        execCameraSql(dbManager, sqlTemplate, args.cameraID, isQuery=False)
        return

    if args.mode == 'disable':
        if camInfo['dormant'] == 1:
            logging.error('Camera already disabled: dormant=%d', camInfo['dormant'])
            exit(1)
        sqlTemplate = """UPDATE sources SET dormant=1 WHERE name = '%s' """
        execCameraSql(dbManager, sqlTemplate, args.cameraID, isQuery=False)
        return

    if args.mode == 'stats':
        sqlTemplate = """SELECT max(timestamp) as maxtime FROM scores WHERE CameraName = '%s' """
        dbResult = execCameraSql(dbManager, sqlTemplate, args.cameraID, isQuery=True)
        logging.warning('Most recent image scanned: %s', getTime(dbResult))
        sqlTemplate = """SELECT max(timestamp) as maxtime FROM detections WHERE CameraName = '%s' """
        dbResult = execCameraSql(dbManager, sqlTemplate, args.cameraID, isQuery=True)
        logging.warning('Most recent smoke detection: %s', getTime(dbResult))
        sqlTemplate = """SELECT max(timestamp) as maxtime FROM alerts WHERE CameraName = '%s' """
        dbResult = execCameraSql(dbManager, sqlTemplate, args.cameraID, isQuery=True)
        logging.warning('Most recent smoke alert: %s', getTime(dbResult))
        return

    logging.error('Unexpected mode: %s', args.mode)
    exit(1)
Exemple #12
0
def main():
    optArgs = [
        ["b", "heartbeat", "filename used for heartbeating check"],
        ["c", "collectPositves", "collect positive segments for training data"],
        ["t", "time", "Time breakdown for processing images"],
        ["m", "minusMinutes", "(optional) subtract images from given number of minutes ago"],
        ["r", "restrictType", "Only process images from cameras of given type"],
        ["s", "startTime", "(optional) performs search with modifiedTime > startTime"],
        ["e", "endTime", "(optional) performs search with modifiedTime < endTime"],
    ]
    args = collect_args.collectArgs([], optionalArgs=optArgs, parentParsers=[goog_helper.getParentParser()])
    minusMinutes = int(args.minusMinutes) if args.minusMinutes else 0
    # TODO: Fix googleServices auth to resurrect email alerts
    # googleServices = goog_helper.getGoogleServices(settings, args)
    googleServices = None
    dbManager = db_manager.DbManager(sqliteFile=settings.db_file,
                                    psqlHost=settings.psqlHost, psqlDb=settings.psqlDb,
                                    psqlUser=settings.psqlUser, psqlPasswd=settings.psqlPasswd)
    cameras = dbManager.get_sources(activeOnly=True, restrictType=args.restrictType)
    startTimeDT = dateutil.parser.parse(args.startTime) if args.startTime else None
    endTimeDT = dateutil.parser.parse(args.endTime) if args.endTime else None
    timeRangeSeconds = None
    useArchivedImages = False
    camArchives = img_archive.getHpwrenCameraArchives(settings.hpwrenArchives)
    DetectionPolicyClass = policies.get_policies()[settings.detectionPolicy]
    detectionPolicy = DetectionPolicyClass(args, dbManager, minusMinutes, stateless=useArchivedImages)
    constants = { # dictionary of constants to reduce parameters in various functions
        'args': args,
        'googleServices': googleServices,
        'camArchives': camArchives,
        'dbManager': dbManager,
    }

    if startTimeDT or endTimeDT:
        assert startTimeDT and endTimeDT
        timeRangeSeconds = (endTimeDT-startTimeDT).total_seconds()
        assert timeRangeSeconds > 0
        assert args.collectPositves
        useArchivedImages = True
        random.seed(0) # fixed seed guarantees same randomized ordering.  Should make this optional argument in future

    processingTimeTracker = initializeTimeTracker()
    while True:
        classifyImgPath = None
        timeStart = time.time()
        if useArchivedImages:
            (cameraID, timestamp, imgPath, classifyImgPath) = \
                getArchivedImages(constants, cameras, startTimeDT, timeRangeSeconds, minusMinutes)
        # elif minusMinutes: to be resurrected using archive functionality
        else: # regular (non diff mode), grab image and process
            (cameraID, timestamp, imgPath, md5) = getNextImage(dbManager, cameras)
            classifyImgPath = imgPath
        if not cameraID:
            continue # skip to next camera
        timeFetch = time.time()

        image_spec = [{}]
        image_spec[-1]['path'] = classifyImgPath
        image_spec[-1]['timestamp'] = timestamp
        image_spec[-1]['cameraID'] = cameraID

        detectionResult = detectionPolicy.detect(image_spec)
        timeDetect = time.time()
        if detectionResult['fireSegment']:
            if not isDuplicateAlert(dbManager, cameraID, timestamp):
                alertFire(constants, cameraID, timestamp, imgPath, detectionResult['fireSegment'])
        deleteImageFiles(imgPath, imgPath)
        if (args.heartbeat):
            heartBeat(args.heartbeat)

        timePost = time.time()
        updateTimeTracker(processingTimeTracker, timePost - timeStart)
        if args.time:
            if not detectionResult['timeMid']:
                detectionResult['timeMid'] = timeDetect
            logging.warning('Timings: fetch=%.2f, detect0=%.2f, detect1=%.2f post=%.2f',
                timeFetch-timeStart, detectionResult['timeMid']-timeFetch, timeDetect-detectionResult['timeMid'], timePost-timeDetect)
        # free all memory for current iteration and trigger GC to prevent memory growth
        detectionResult = None
        gc.collect()