Exemple #1
0
def test_fake(monkeypatch, setup_test):

    with freeze_time(parse("2000-01-01 12:00:00")) as fdt:
        global FDT
        FDT = fdt
        monkeypatch.setattr(time, 'sleep', sleepless)
        c = Camera(sw_cam=True)
        c.file_by_date = False
        c._interval = timedelta(minutes=10)

        run_until(c, fdt, today_at(13))
        assert len(c.recent_images) == 6 + 1  # fencepost
        images = sorted(glob(os.path.join(c.tmv_root, "2000-01-01T*")))
        assert len(images) == 6 + 1  # fencepost

        # run 13:00 - 14:00 with switch AUTO
        c.mode_button.value = AUTO
        run_until(c, fdt, today_at(14))
        assert c.active_timer.active()  # active
        images = sorted(glob(os.path.join(c.tmv_root, "2000-01-01T*")))
        assert len(images) == 6 + 1 + 6  # one hour more of 6 photos per hour
        # run 14:00 - 15:00 with switch ON
        c.active_timer = Timed(datetime.time(6, 0, 0), datetime.time(7, 0, 0))
        c.mode_button.value = ON
        run_until(c, fdt, today_at(15))
        assert not c.active_timer.active()  # not active - but overridden by switch
        images = sorted(glob(os.path.join(c.tmv_root, "2000-01-01T*")))
        # one hour more of 6 photos per hour
        assert len(images) == 6 + 1 + 6 + 6
        assert Path("./latest-image.jpg").is_file()
Exemple #2
0
def test_Sensor_lookups():
    c = Camera(sw_cam=True)

    c.active_timer = tmv.camera.ActiveTimes.factory(
        on='dim', off='dark', camera=c)
    c.light_sensor._current_level = LightLevel.LIGHT
    assert c.active_timer.camera_active()

    c = Camera(sw_cam=True)

    ss = tmv.camera.ActiveTimes.factory(on='dim', off='dark', camera=c)
    c.light_sensor._current_level = LightLevel.DARK
    # Active, as sensor will operate
    assert ss.active() is True
    # But could power off if camera not required (it's DARK)
    assert timedelta(minutes=59) <= (
        ss.waketime() - dt.now()) <= timedelta(minutes=61)
    c.light_sensor._current_level = LightLevel.DIM
    # Still active
    assert ss.active()
    # But can't power off for long (camera is active)
    assert ss.waketime() <= dt.now()
    c.light_sensor._current_level = LightLevel.LIGHT
    assert ss.waketime() <= dt.now()
    c.light_sensor._current_level = LightLevel.DIM
    assert ss.waketime() <= dt.now()
    c.light_sensor._current_level = LightLevel.DARK
    # active, but only the sensor
    assert ss.active()
    assert timedelta(minutes=59) <= (
        ss.waketime() - dt.now()) <= timedelta(minutes=61)
    #
    c.light_sensor._current_level = LightLevel.LIGHT
    # ON when DIM, OFF when DARK, should be ON when light
    assert ss.active()
Exemple #3
0
def test_Sensor(monkeypatch, setup_test):
    with freeze_time(parse("2000-01-01 00:00:00")) as fdt:
        global FDT
        FDT = fdt
        monkeypatch.setattr(time, 'sleep', sleepless)
        c = Camera(sw_cam=True)
        c.save_images = True
        c.light_sensor.freq = timedelta(minutes=20)
        c.light_sensor.max_age = timedelta(hours=1)
        c.configs("""
        [location]
        city = "Brisbane"
        [camera]
        interval = 300
        # test ON at first light, then off when dark (i.e. all day)
        on = 'light'
        off =  'dim'
        camera_inactive_action = 'WAIT'
    
       
    
        """)
        c.mode_button.value = AUTO
        reset_camera = deepcopy(c)  # a copy of the camera after it starts
        run_until(c, fdt, tomorrow_at(12), reset_camera)
        run_until(c, fdt, today_at(18, 00), reset_camera)
        run_until(c, fdt, today_at(23, 59), reset_camera)
        run_until(c, fdt, tomorrow_at(9, 00), reset_camera)
        reset_camera.run(1)
        assert reset_camera.active_timer.light_sensor.level == LightLevel.LIGHT
Exemple #4
0
def test_low_light_sense(monkeypatch, setup_test):
    with freeze_time(parse("2000-01-01 00:00:00")) as fdt:
        global FDT
        FDT = fdt
        monkeypatch.setattr(time, 'sleep', sleepless)
        c = Camera(sw_cam=True)

        c.file_by_date = False
        c._interval = timedelta(hours=1)
        c.light_sensor.light = 0.6
        c.light_sensor.dark = 0.1
        c.light_sensor.freq = timedelta(minutes=10)
        c.light_sensor.max_age = timedelta(minutes=60)
        assert c.light_sensor.level == LightLevel.LIGHT  # starts LIGHT by default
        run_until(c, fdt, today_at(3))
        assert c.light_sensor.level == LightLevel.DARK
        run_until(c, fdt, today_at(10))
        assert c.light_sensor.level == LightLevel.DIM
        run_until(c, fdt, today_at(12))
        assert c.light_sensor.level == LightLevel.LIGHT
        run_until(c, fdt, today_at(16, 30))
        assert c.light_sensor.level == LightLevel.DIM
        run_until(c, fdt, today_at(23))
        assert c.light_sensor.level == LightLevel.DARK
        images = glob(os.path.join(c.tmv_root, "2000-01-01T*"))
        assert len(images) == 24
Exemple #5
0
def test_latest_image(setup_test):
    cf = """
    [camera]
    tmv_root = "."
    """
    c = Camera(sw_cam=True)
    c.configs(cf)
    cwd = Path(os.getcwd())
    assert (cwd / "latest-image.jpg").absolute() == c.latest_image.absolute()
Exemple #6
0
def test_location():
    cf = """
    [camera]
    on = 'dawn'
    off = 'dusk'
    """
    # no location: fail
    c = Camera(sw_cam=True)

    with pytest.raises(tmv.camera.ConfigError):
        c.configs(cf)

    cf = """
    
    
    [camera]
    city = 'Brisbane'
    on = 'dawn'
    off = 'dusk'
    """
    #  location: ok
    c.configs(cf)

    cf = """
    
    [camera]
    city = 'auto'
    on = 'dawn'
    off = 'dusk'
    """
    # no location: fail

    with pytest.raises(NotImplementedError):
        c.configs(cf)
Exemple #7
0
def test_camera_inactive_action(monkeypatch, setup_test):
    with freeze_time(parse("2000-01-01 12:00:00")) as fdt:
        global FDT
        FDT = fdt
        monkeypatch.setattr(time, 'sleep', sleepless)
        c = Camera(sw_cam=True)
        c.mode_button.value = AUTO
        c.save_images = False
        c.configs("""
        [camera]
        interval = 900 # 15 minutes
        on = 09:00:00
        off = 13:00:00
        camera_inactive_action = 'EXCEPTION'       
        """)
        c._camera = FakePiCamera()
        c.mode_button.value = AUTO
        with pytest.raises(PowerOff):
            run_until(c, fdt, today_at(18))
        c.configs("""
        [camera]
        on = 09:00:00
        off = 13:00:00
        camera_inactive_action = 'WAIT'          
        """)
        run_until(c, fdt, tomorrow_at(18))  # no raise
Exemple #8
0
def test_speeds(setup_test):
    """ Test interval change with speed button"""
    c = Camera(sw_cam=True)
    assert c._interval == timedelta(seconds=60)
    cf = """
    [camera]
    interval = 100
    """

    c.configs(cf)
    assert c.interval == timedelta(seconds=100)
    c.speed_button.value = SLOW
    assert c.interval == timedelta(seconds=100 * SPEED_MULTIPLIER)
    c.speed_button.value = FAST
    assert c.interval == timedelta(seconds=100 / SPEED_MULTIPLIER)
Exemple #9
0
def test_config(monkeypatch, setup_test):
    with freeze_time(parse("2000-01-01 00:00:00")) as fdt:
        global FDT
        FDT = fdt
        c = Camera(sw_cam=True)

        c.tmv_root = "./test_config/"
        cf = """
        [location]
            city = "Brisbane"
        [camera]
            off = 07:00:00
            on = 18:00:00
        
        [camera.picam.LIGHT]
            id = "Custom day config at 800"
            iso = 800
            exposure_mode = "auto"
            resolution = "800x600"

        [camera.picam.DIM]
            id = "CUSTOM-DIM"
            framerate = 1
            iso = 0
            exposure_mode = "night"
            resolution = "800x600"

        [camera.picam.DARK]
            id = "CUSTOM-NIGHTY"
            framerate = 1
            iso = 1600
            shutter_speed = 1000000
            exposure_mode = "verylong"
            resolution = "800x600"
        """
        c.configs(cf)
        # default
        assert c.picam[LightLevel.LIGHT.name]['exposure_mode'] == 'auto'
        assert c.picam[LightLevel.LIGHT.name]['resolution'] == '800x600'
        # new one
        assert c.picam[LightLevel.LIGHT.name]['iso'] == 800
        c._camera = FakePiCamera()
        # fake sleeping
        monkeypatch.setattr(time, 'sleep', sleepless)
        c.run(3)
        # should have clicked over to DARK. Configured a special iso for DARK in toml.
        assert c.picam[c.light_sensor.level.name]['iso'] == 1600
        c.run(1)
Exemple #10
0
def test_image_stats_2():
    """ Test max_age =0 boundary case"""
    #                           pixel_avg   looks
    # 2020-04-05T14-31-20.jpg   .29         light   0
    # 2020-04-05T15-24-20.jpg   .13         light   1
    # 2020-04-05T16-24-20.jpg   .08         dim     2
    # 2020-04-05T17-24-20.jpg   .04         dim     3
    # 2020-04-05T18-24-20.jpg   .01         dim     4
    # thresholds:   light > 0.10
    #               dark  < 0.01

    with freeze_time(dateutil.parser.parse("2020-04-05T20:00:00")):
        image_files = []
        rex = re.compile("^2020-04-05T.*")

        for r, ds, fs in os.walk(TEST_DATA / "camera_images"):
            print(ds)
            image_files = [os.path.join(r, f)
                           for f in fs if rex.match(f) is not None]
            break  # no deeper
        assert len(image_files) == 5

        cam = Camera(sw_cam=True)
        cam.light_sensor.max_age = timedelta(seconds=0)
        cam.light_sensor.dark = 0.0  # make sure they are DIM
        assert cam.light_sensor.level == tmv.camera.LightLevel.LIGHT
        for f in sorted(image_files):
            cam.light_sensor.add_reading(
                tmv.util.str2dt(f), calc_pixel_average(f))
            print("length:{}".format(len(cam.light_sensor._levels)))

        assert cam.light_sensor.level == tmv.camera.LightLevel.DIM
        assert len(cam.light_sensor._levels) == 0
Exemple #11
0
def test_Timed_capture(monkeypatch, setup_test):

    with freeze_time(parse("2000-01-01 06:00:00")) as fdt:
        global FDT
        FDT = fdt
        monkeypatch.setattr(time, 'sleep', sleepless)
        c = Camera(sw_cam=True)

        c.mode_button.value = AUTO
        c.mode_button.button_path = Path("./camera-switch")
        c.file_by_date = False
        #c._camera = FakePiCamera()
        c._interval = timedelta(minutes=60)
        c.active_timer = Timed(datetime.time(12), datetime.time(18))
        run_until(c, fdt, today_at(23))
        images = glob(os.path.join(c.tmv_root, "2000-01-01T*"))
        assert len(images) == 18 - 12 + 1  # +1 for a fencepost
Exemple #12
0
def check_test_fake2(monkeypatch, setup_test):
    s = 3
    c = Camera(sw_cam=True)
    c.tmv_root = "./test_fake2/"
    c.file_by_date = False
    c.interval = timedelta(seconds=1)
    c.active_timer = ActiveTimes.factory(dt.now().astimezone().time(
    ), (dt.now() + timedelta(seconds=s)).astimezone().time(), c)
    c.camera_inactive_action = CameraInactiveAction.EXCEPTION
    with pytest.raises(PowerOff):
        c.run()
    assert len(c.recent_images) == s + 1  # fencepost
    images = glob(os.path.join(c.tmv_root, "*.jpg"))
    assert len(images) == s + 1  # fencepost
Exemple #13
0
def test_overlays(monkeypatch, setup_test):
    cf = """
       [camera]
            overlays = [ "spinny", "image_name","simple_settings", "bottom_band"]

        """

    with freeze_time(parse("2000-01-01 12:00:00")) as fdt:
        global FDT
        FDT = fdt
        monkeypatch.setattr(time, 'sleep', sleepless)
        c = Camera(sw_cam=True)
        #c._camera.width = 1200
        #c._camera.height = 900
        c.configs(cf)
        c.file_by_date = False

        run_until(c, fdt, today_at(13))
Exemple #14
0
def test_camera_inactive_action_2(monkeypatch, setup_test):
    with freeze_time(parse("2000-01-01 12:00:00")) as fdt:
        global FDT
        FDT = fdt
        monkeypatch.setattr(time, 'sleep', sleepless)
        c = Camera(sw_cam=True)

        c.save_images = False
        c.configs("""
        [camera]
        interval = 900 # 15 minutes
        on = 'dim'
        off = 'dark'
        camera_inactive_action = 'EXCEPTION'       
        """)
        # with pytest.raises(PowerOff):
        run_until(c, fdt, today_at(14))
        assert c.light_sensor.level == LightLevel.LIGHT
        assert c.active_timer.active()
        assert c.active_timer.camera_active()
Exemple #15
0
def test_video(monkeypatch, setup_test):
    c = Camera(sw_cam=True)
    c.file_by_date = False
    with freeze_time(parse("2000-01-01 12:00:00")) as fdt:
        global FDT
        FDT = fdt
        real_sleep = time.sleep
        monkeypatch.setattr(time, 'sleep', sleepless)
        # start normally
        c.mode_button.value = ON
        c._interval = timedelta(seconds=60)

        while dt.now() < today_at(13):
            c.run(1)
            fdt.tick(timedelta(seconds=1))

        # switch to video mode
        c.mode_button.value = VIDEO
        vtd = threading.Thread(target=video_server, args=(c, fdt), daemon=True)
        vtd.start()
        real_sleep(3)
        c.mode_button.value = OFF
        vtd.join()
        real_sleep(1)

        # switch to video mode agina : ok
        c.mode_button.value = VIDEO
        vtd = threading.Thread(target=video_server, args=(c, fdt), daemon=True)
        vtd.start()
        real_sleep(3)
        c.mode_button.value = OFF
        vtd.join()
Exemple #16
0
def test_SunCalc(monkeypatch, setup_test):
    # dawn:   datetime.time(4, 28, 38, 892410)
    # sunrise:datetime.time(4, 55, 38, 480930)
    # noon:   datetime.time(11, 50, 59)
    # sunset  datetime.time(18, 46, 18, 926896)
    # dusk    datetime.time(19, 13, 17, 159158)

    with freeze_time(parse("2000-01-01 00:00:00")) as fdt:
        global FDT
        FDT = fdt
        monkeypatch.setattr(time, 'sleep', sleepless)
        c = Camera(sw_cam=True)

        c.save_images = False
        c.configs("""
        [camera]
        city = 'Brisbane'
        interval = 600
        on = 'dawn'
        off =  'sunset' # (2000, 1, 1, 18, 46, 18, 926896, tzinfo=tzlocal())
        camera_inactive_action = 'WAIT'
        """)
        c._camera = FakePiCamera()
        assert c.active_timer.active() is False
        run_until(c, fdt, today_at(4, 30))
        assert c.active_timer.active() is True
        run_until(c, fdt, today_at(12, 30))
        assert c.active_timer.active() is True
        run_until(c, fdt, today_at(18, 30))
        assert c.active_timer.active() is True
        run_until(c, fdt, today_at(18, 40))
        run_until(c, fdt, today_at(18, 50))
        assert c.active_timer.active() is False
        run_until(c, fdt, tomorrow_at(8))
        assert c.active_timer.active() is True
Exemple #17
0
def test_image_verify(setup_test, caplog):
    c = Camera(sw_cam=True)

    stream = BytesIO()
    # "Rewind" the stream to the beginning so we can read its content
    stream.seek(0)
    f = FakePiCamera()
    f.capture(stream)
    stream.seek(0)
    image = Image.open(stream)
    image.save("should-not-be-required.jpg")
    fn = Path("test_image_verify.jpg")
    c.save_image(image, fn)
    assert Path(fn).is_file()

    c = Camera(sw_cam=True)

    image = Image.Image()
    fn = Path("test_image_dud.jpg")
    caplog.clear()
    c.save_image(image, fn)
    assert not Path(fn).is_file()
    assert "Image has zero width or height" in caplog.text
Exemple #18
0
def test_image_stats():
    #                           pixel_avg   looks
    # 2020-04-05T14-31-20.jpg   .29         light   0
    # 2020-04-05T15-24-20.jpg   .13         light   1
    # 2020-04-05T16-24-20.jpg   .08         dim     2
    # 2020-04-05T17-24-20.jpg   .04         dim     3
    # 2020-04-05T18-24-20.jpg   .01         dim     4
    # thresholds:   light > 0.10
    #               dark  < 0.01

    with freeze_time(dateutil.parser.parse("2020-04-05T20:00:00")) as fdt:
        image_files = []
        rex = re.compile("^2020-04-05T.*")

        for r, ds, fs in os.walk(TEST_DATA/"camera_images"):
            print(ds)
            image_files = [os.path.join(r, f)
                           for f in fs if rex.match(f) is not None]
            break  # no deeper
        assert len(image_files) == 5
        cam = Camera(sw_cam=True)

        # usually max_age is 1 hour: use long to make testing easier
        cam.light_sensor.max_age = timedelta(days=1)
        for f in sorted(image_files):
            cam.light_sensor.add_reading(
                tmv.util.str2dt(f), calc_pixel_average(f))
        # pylint: disable=protected-access,pointless-statement
        assert cam.light_sensor.level == tmv.camera.LightLevel.LIGHT
        assert len(cam.light_sensor._levels) == 5
        cam.light_sensor.max_age = timedelta(hours=4)
        cam.light_sensor.level
        assert len(cam.light_sensor._levels) == 3
        fdt.move_to(dateutil.parser.parse("2020-04-07T20:00:00"))
        cam.light_sensor.level
        assert len(cam.light_sensor._levels) == 0
Exemple #19
0
def video_server(c: Camera, fdt):
    while c.mode_button.value != VIDEO:
        c.run(1)