Store totalUse to disk & use si_prefixing for totalUse
This commit is contained in:
parent
b6cef14d64
commit
8e409451e4
2 changed files with 276 additions and 4 deletions
|
@ -6,7 +6,8 @@ import cv2
|
|||
import numpy as np
|
||||
import datetime
|
||||
import time
|
||||
|
||||
import os
|
||||
from si_prefix import si_format
|
||||
import Adafruit_CharLCD as LCD
|
||||
|
||||
# Set FPS (though RPi is probably to slow to meet it ;-)
|
||||
|
@ -51,6 +52,23 @@ lcd.message("Init scanner...")
|
|||
prevFaceCount = 0
|
||||
totalUse = 0 #in face-seconds
|
||||
|
||||
# make sure log file exists
|
||||
if not os.path.exists("scan_face.log")
|
||||
with open("scan_face.log","w") as f:
|
||||
f.write("{},{},{}".format(time.time(), 0,0))
|
||||
|
||||
# get last line of log file and update 'total use' using that.
|
||||
with open("scan_face.log", "rb") as f:
|
||||
first = f.readline() # Read the first line.
|
||||
f.seek(-2, os.SEEK_END) # Jump to the second last byte.
|
||||
while f.read(1) != b"\n": # Until EOL is found...
|
||||
f.seek(-2, os.SEEK_CUR) # ...jump back the read byte plus one more.
|
||||
last = f.readline() # Read last line.
|
||||
bits = last.split(",")
|
||||
totalUse = bits[2]
|
||||
|
||||
log = open("scan_face.log", "a")
|
||||
|
||||
lastFaceTime = datetime.datetime.utcnow()
|
||||
|
||||
while True:
|
||||
|
@ -65,7 +83,6 @@ while True:
|
|||
print(time.time(),"grayed")
|
||||
faces = classifier.detectMultiScale(gray, 1.2, 5, minSize=(30,20))
|
||||
|
||||
# TODO: time passed since last * prevFaceCount = usage
|
||||
|
||||
print(time.time(),"Found {} faces".format(len(faces)))
|
||||
|
||||
|
@ -76,7 +93,13 @@ while True:
|
|||
|
||||
lcd.clear()
|
||||
#~ lcd.message("viewers {:>8}\nview-min. {:>7.2f}".format(len(faces), totalUse/60))
|
||||
lcd.message("viewers {:>8}\nview-sec {:>7}".format(len(faces), int(totalUse)))
|
||||
lcd.message("{:>7} viewers \n{:>7}view-sec".format(len(faces), si_format(totalUse,precision=1)))
|
||||
|
||||
log.write("{},{},{}".format(time.time(), len(faces), int(totalUse)))
|
||||
log.flush()
|
||||
|
||||
os.fsync(log.fileno())
|
||||
|
||||
if len(faces) < 1 and end - lastFaceTime > dimTimeDelta:
|
||||
lcd.set_backlight(0)
|
||||
else:
|
||||
|
|
249
si_prefix.py
Normal file
249
si_prefix.py
Normal file
|
@ -0,0 +1,249 @@
|
|||
# coding: utf-8
|
||||
from __future__ import division
|
||||
import math
|
||||
import re
|
||||
|
||||
# Print a floating-point number in engineering notation.
|
||||
# Ported from [C version][1] written by
|
||||
# Jukka “Yucca” Korpela <jkorpela@cs.tut.fi>.
|
||||
#
|
||||
# [1]: http://www.cs.tut.fi/~jkorpela/c/eng.html
|
||||
|
||||
SI_PREFIX_UNITS = "yzafpnum kMGTPEZY"
|
||||
CRE_SI_NUMBER = re.compile(r'\s*(?P<sign>[\+\-])?'
|
||||
r'(?P<integer>\d+)'
|
||||
r'(?P<fraction>.\d+)?\s*'
|
||||
r'(?P<si_unit>[%s])?\s*' % SI_PREFIX_UNITS)
|
||||
|
||||
|
||||
def split(value, precision=1):
|
||||
'''
|
||||
Split `value` into value and "exponent-of-10", where "exponent-of-10" is a
|
||||
multiple of 3. This corresponds to SI prefixes.
|
||||
|
||||
Returns tuple, where the second value is the "exponent-of-10" and the first
|
||||
value is `value` divided by the "exponent-of-10".
|
||||
|
||||
Args
|
||||
----
|
||||
value : int, float
|
||||
Input value.
|
||||
precision : int
|
||||
Number of digits after decimal place to include.
|
||||
|
||||
Returns
|
||||
-------
|
||||
tuple
|
||||
The second value is the "exponent-of-10" and the first value is `value`
|
||||
divided by the "exponent-of-10".
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
si_prefix.split(0.04781) -> (47.8, -3)
|
||||
si_prefix.split(4781.123) -> (4.8, 3)
|
||||
|
||||
See `si_prefix.format` for more examples.
|
||||
'''
|
||||
negative = False
|
||||
digits = precision + 1
|
||||
|
||||
if value < 0.:
|
||||
value = -value
|
||||
negative = True
|
||||
elif value == 0.:
|
||||
return 0., 0
|
||||
|
||||
expof10 = int(math.log10(value))
|
||||
if expof10 > 0:
|
||||
expof10 = (expof10 // 3) * 3
|
||||
else:
|
||||
expof10 = (-expof10 + 3) // 3 * (-3)
|
||||
|
||||
value *= 10 ** (-expof10)
|
||||
|
||||
if value >= 1000.:
|
||||
value /= 1000.0
|
||||
expof10 += 3
|
||||
elif value >= 100.0:
|
||||
digits -= 2
|
||||
elif value >= 10.0:
|
||||
digits -= 1
|
||||
|
||||
if negative:
|
||||
value *= -1
|
||||
|
||||
return value, int(expof10)
|
||||
|
||||
|
||||
def prefix(expof10):
|
||||
'''
|
||||
Args:
|
||||
|
||||
expof10 : Exponent of a power of 10 associated with a SI unit
|
||||
character.
|
||||
|
||||
Returns:
|
||||
|
||||
str : One of the characters in "yzafpnum kMGTPEZY".
|
||||
'''
|
||||
prefix_levels = (len(SI_PREFIX_UNITS) - 1) // 2
|
||||
si_level = expof10 // 3
|
||||
|
||||
if abs(si_level) > prefix_levels:
|
||||
raise ValueError("Exponent out range of available prefixes.")
|
||||
return SI_PREFIX_UNITS[si_level + prefix_levels]
|
||||
|
||||
|
||||
def si_format(value, precision=1, format_str='{value} {prefix}',
|
||||
exp_format_str='{value}e{expof10}'):
|
||||
'''
|
||||
Format value to string with SI prefix, using the specified precision.
|
||||
|
||||
Args
|
||||
----
|
||||
|
||||
value : int, float
|
||||
Input value.
|
||||
precision : int
|
||||
Number of digits after decimal place to include.
|
||||
format_str : str
|
||||
Format string where `{prefix}` and `{value}` represent the SI prefix
|
||||
and the value (scaled according to the prefix), respectively. The
|
||||
default format matches the `SI prefix style`_ format.
|
||||
exp_str : str
|
||||
Format string where `{expof10}` and `{value}` represent the exponent of
|
||||
10 and the value (scaled according to the exponent of 10),
|
||||
respectively. This format is used if the absolute exponent of 10 value
|
||||
is greater than 24.
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
`value` formatted according to the `SI prefix style`_.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
For example, with `precision=2`:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
1e-27 --> 1.00e-27
|
||||
1.764e-24 --> 1.76 y
|
||||
7.4088e-23 --> 74.09 y
|
||||
3.1117e-21 --> 3.11 z
|
||||
1.30691e-19 --> 130.69 z
|
||||
5.48903e-18 --> 5.49 a
|
||||
2.30539e-16 --> 230.54 a
|
||||
9.68265e-15 --> 9.68 f
|
||||
4.06671e-13 --> 406.67 f
|
||||
1.70802e-11 --> 17.08 p
|
||||
7.17368e-10 --> 717.37 p
|
||||
3.01295e-08 --> 30.13 n
|
||||
1.26544e-06 --> 1.27 u
|
||||
5.31484e-05 --> 53.15 u
|
||||
0.00223223 --> 2.23 m
|
||||
0.0937537 --> 93.75 m
|
||||
3.93766 --> 3.94
|
||||
165.382 --> 165.38
|
||||
6946.03 --> 6.95 k
|
||||
291733 --> 291.73 k
|
||||
1.22528e+07 --> 12.25 M
|
||||
5.14617e+08 --> 514.62 M
|
||||
2.16139e+10 --> 21.61 G
|
||||
9.07785e+11 --> 907.78 G
|
||||
3.8127e+13 --> 38.13 T
|
||||
1.60133e+15 --> 1.60 P
|
||||
6.7256e+16 --> 67.26 P
|
||||
2.82475e+18 --> 2.82 E
|
||||
1.1864e+20 --> 118.64 E
|
||||
4.98286e+21 --> 4.98 Z
|
||||
2.0928e+23 --> 209.28 Z
|
||||
8.78977e+24 --> 8.79 Y
|
||||
3.6917e+26 --> 369.17 Y
|
||||
1.55051e+28 --> 15.51e+27
|
||||
6.51216e+29 --> 651.22e+27
|
||||
|
||||
|
||||
.. _SI prefix style:
|
||||
http://physics.nist.gov/cuu/Units/checklist.html
|
||||
'''
|
||||
svalue, expof10 = split(value, precision)
|
||||
value_format = '%%.%df' % precision
|
||||
value_str = value_format % svalue
|
||||
try:
|
||||
return format_str.format(value=value_str,
|
||||
prefix=prefix(expof10).strip())
|
||||
except ValueError:
|
||||
sign = ''
|
||||
if expof10 > 0:
|
||||
sign = "+"
|
||||
return exp_format_str.format(value=value_str,
|
||||
expof10=''.join([sign, str(expof10)]))
|
||||
|
||||
|
||||
def si_parse(value):
|
||||
'''
|
||||
Parse a value expressed using SI prefix units to a floating point number.
|
||||
|
||||
Args:
|
||||
|
||||
value (str) : Value expressed using SI prefix units (as returned by
|
||||
`si_format` function).
|
||||
'''
|
||||
CRE_10E_NUMBER = re.compile(r'^\s*(?P<integer>[\+\-]?\d+)?'
|
||||
r'(?P<fraction>.\d+)?\s*([eE]\s*'
|
||||
r'(?P<expof10>[\+\-]?\d+))?$')
|
||||
CRE_SI_NUMBER = re.compile(r'^\s*(?P<number>(?P<integer>[\+\-]?\d+)?'
|
||||
r'(?P<fraction>.\d+)?)\s*'
|
||||
r'(?P<si_unit>[%s])?\s*$' % SI_PREFIX_UNITS)
|
||||
match = CRE_10E_NUMBER.match(value)
|
||||
if match:
|
||||
# Can be parse using `float`.
|
||||
assert(match.group('integer') is not None or
|
||||
match.group('fraction') is not None)
|
||||
return float(value)
|
||||
match = CRE_SI_NUMBER.match(value)
|
||||
assert(match.group('integer') is not None or
|
||||
match.group('fraction') is not None)
|
||||
d = match.groupdict()
|
||||
si_unit = d['si_unit'] if d['si_unit'] else ' '
|
||||
prefix_levels = (len(SI_PREFIX_UNITS) - 1) // 2
|
||||
scale = 10 ** (3 * (SI_PREFIX_UNITS.index(si_unit) - prefix_levels))
|
||||
return float(d['number']) * scale
|
||||
|
||||
|
||||
def si_prefix_scale(si_unit):
|
||||
'''
|
||||
Parameters
|
||||
----------
|
||||
si_unit : str
|
||||
SI unit character, i.e., one of "yzafpnum kMGTPEZY".
|
||||
|
||||
Returns
|
||||
-------
|
||||
int
|
||||
Multiple associated with `si_unit`, e.g., 1000 for `si_unit=k`.
|
||||
'''
|
||||
return 10 ** si_prefix_expof10(si_unit)
|
||||
|
||||
|
||||
def si_prefix_expof10(si_unit):
|
||||
'''
|
||||
Parameters
|
||||
----------
|
||||
si_unit : str
|
||||
SI unit character, i.e., one of "yzafpnum kMGTPEZY".
|
||||
|
||||
Returns
|
||||
-------
|
||||
int
|
||||
Exponent of the power of ten associated with `si_unit`, e.g., 3 for
|
||||
`si_unit=k` and -6 for `si_unit=u`.
|
||||
'''
|
||||
prefix_levels = (len(SI_PREFIX_UNITS) - 1) // 2
|
||||
return (3 * (SI_PREFIX_UNITS.index(si_unit) - prefix_levels))
|
||||
|
Loading…
Reference in a new issue