Beispiel #1
0
def test_deepsleep(mocker, caplog):
    """
    Check deepsleep behavior.
    """

    # Acquire minimal settings.
    from test.settings import sleep as sleep_settings

    # Set deepsleep mode.
    sleep_settings.main['deepsleep'] = True

    # Invoke datalogger for a single duty cycle.
    datalogger = invoke_datalogger_pycom(caplog, settings=sleep_settings)

    # Patch machinery to mock the sleep method.
    import machine
    mocker.patch('machine.deepsleep', create=True)

    # Invoke sleep.
    datalogger.sleep()

    # Proof the "machine.deepsleep" function has been invoked.
    machine.deepsleep.assert_called_once()

    # Capture log output.
    captured = caplog.text

    # Proof it works by verifying log output.
    assert re.match('.*Entering deep sleep for .+ seconds.*',
                    captured,
                    flags=re.DOTALL), captured
Beispiel #2
0
def test_timesleep(mocker, caplog):
    """
    Check normal "time.sleep()" behavior without any machine.sleep methods.
    """

    # Acquire minimal settings.
    from test.settings import sleep as sleep_settings

    # Invoke datalogger for a single duty cycle.
    datalogger = invoke_datalogger_pycom(caplog, settings=sleep_settings)

    # Patch machinery to mock the sleep method.
    import time
    mocker.patch('time.sleep', create=True)

    # Invoke sleep.
    datalogger.sleep()

    # Proof the "time.sleep" function has been invoked.
    time.sleep.assert_called_once()

    # Capture log output.
    captured = caplog.text

    # Proof it works by verifying log output.
    assert re.match('.*Waiting for .+ seconds.*', captured,
                    flags=re.DOTALL), captured
def test_uplink_system_temperature(network_lora, caplog):
    """
    Pretend to invoke the datalogger on a LoPy4 with basic system sensors.
    Effectively, only the "system.temperature" sensor will be transmitted
    over LoRa telemetry.

    By intercepting the lora socket communication, proof that the
    submitted payload is correct by checking the raw payload value
    and decoding it through Cayenne.
    """

    # Define artificial LoRa conversation.
    network_lora.register_conversation()

    # Invoke datalogger with LoRaWAN telemetry settings for a single duty cycle.
    from test.settings import telemetry_lorawan
    invoke_datalogger_pycom(caplog, settings=telemetry_lorawan)

    # Capture log output.
    captured = caplog.text

    # Proof it works by verifying log output.
    assert "Starting Terkin datalogger" in captured, captured
    assert "platform: LoPy4" in captured, captured
    assert "[LoRa] Starting LoRa Manager" in captured, captured
    assert "Telemetry transport: CayenneLPP over LoRaWAN/TTN" in captured, captured
    assert "Telemetry status: SUCCESS (1/1)" in captured, captured

    # Check the raw LoRa payload.
    from mocket import Mocket
    assert Mocket.last_request() == bytearray(b'\x00g\x01\xbf\x00\x01\x00')

    # Check the value after decoding from CayenneLPP.
    from cayennelpp import LppFrame
    data = LppFrame.from_bytes(Mocket.last_request()).data

    # System temperature
    assert data[0].channel == 0
    assert data[0].type == 103
    assert data[0].value == (44.7, )

    # EOF?
    assert data[1].channel == 0
    assert data[1].type == 1
    assert data[1].value == (0, )

    assert "[LoRa] No downlink message processed" in captured, captured
def test_downlink_unpause(network_lora, caplog):
    """
    Simulate a downlink "unpause" command on LoRaWAN port 2.
    """

    # Define artificial LoRa conversation.
    network_lora.register_conversation(response_port=2,
                                       response_data=[b'\x00'])

    # Invoke datalogger with LoRaWAN telemetry settings for a single duty cycle.
    from test.settings import telemetry_lorawan
    invoke_datalogger_pycom(caplog, settings=telemetry_lorawan)

    # Capture log output.
    captured = caplog.text

    # Proof it works by verifying log output.
    assert '[LoRa] Received "pause payload submission" command: False' in captured, captured
def test_downlink_interval_reset(network_lora, caplog):
    """
    Simulate a downlink "reset interval" command on LoRaWAN port 1.
    """

    # Define artificial LoRa conversation.
    network_lora.register_conversation(response_port=1,
                                       response_data=[b'\x00'])

    # Invoke datalogger with LoRaWAN telemetry settings for a single duty cycle.
    from test.settings import telemetry_lorawan
    invoke_datalogger_pycom(caplog, settings=telemetry_lorawan)

    # Capture log output.
    captured = caplog.text

    # Proof it works by verifying log output.
    assert '[LoRa] Received "reset deep sleep interval" command, erasing from NVRAM.' in captured, captured
Beispiel #6
0
def test_maintenance(mocker, caplog):
    """
    Check maintenance mode.

    When the device is in maintenance mode, a different duty cycle
    will apply and the sleep method will resort to "time.sleep" in
    order to keep the appliance "online", even when deepsleep mode
    is enabled through the configuration.
    """

    # Acquire minimal settings.
    from test.settings import sleep as sleep_settings

    # Set deepsleep mode.
    sleep_settings.main['deepsleep'] = True

    # Invoke datalogger for a single duty cycle.
    datalogger = invoke_datalogger_pycom(caplog, settings=sleep_settings)

    # Enable maintenance mode.
    datalogger.device.status.maintenance = True

    # Patch machinery to mock the sleep method.
    import time
    mocker.patch('time.sleep', create=True)

    # Invoke sleep.
    datalogger.sleep()

    # Proof the "time.sleep" function has been invoked.
    time.sleep.assert_called_once()

    # Capture log output.
    captured = caplog.text

    # Proof it works by verifying log output.
    assert re.match(
        '.*Device is in maintenance mode. Skipping deep sleep and adjusting sleep time to .+ seconds..*',
        captured,
        flags=re.DOTALL), captured
    assert re.match('.*Waiting for .+ seconds.*', captured,
                    flags=re.DOTALL), captured
Beispiel #7
0
def test_sensors(mocker, caplog):
    """
    Check the whole sensor machinery.
    """

    # Acquire minimal settings.
    from test.settings import sensors_micropython as sensor_settings

    # Pretend the HX711 to be ready.
    mocker.patch('terkin.lib.hx711_heisenberg.HX711Heisenberg.is_ready',
                 mock.Mock(return_value=True))

    # Invoke datalogger for a single duty cycle.
    datalogger = invoke_datalogger_pycom(caplog, settings=sensor_settings)

    # Capture log output.
    captured = caplog.text

    # Proof it works by verifying log output.
    assert "Found 2 I2C devices: [118, 119]" in captured, captured
    assert "Found 2 1-Wire (DS18x20) devices: ['28ff641d8fdf18c1', '28ff641d8fc3944f']" in captured, captured

    # Get hold of the last reading.
    last_reading = datalogger.storage.last_reading

    # Proof it works by verifying last sensor readings.

    # ADC
    assert last_reading['system.voltage.battery'] == 4.2

    # BME280
    assert last_reading['temperature.0x77.i2c:0'] == 15.129645347595215
    assert last_reading['humidity.0x77.i2c:0'] == 77.88673400878906
    assert last_reading['pressure.0x77.i2c:0'] == 1055.163671875

    # DS18B20
    assert last_reading['temperature.28ff641d8fc3944f.onewire:0'] == 48.1875
    assert last_reading['temperature.28ff641d8fdf18c1.onewire:0'] == 48.1875

    # HX711
    assert last_reading['weight.0'] == 3.845
def test_uplink_environmental_sensors(mocker, network_lora, caplog):
    """
    Pretend to invoke the datalogger on a LoPy4 with environmental sensors.

    By intercepting the lora socket communication, proof that the
    submitted payload is correct by checking the raw payload value
    and decoding it through Cayenne.
    """

    # Define artificial LoRa conversation.
    network_lora.register_conversation()

    # Mix together different settings.
    from test.settings import telemetry_lorawan
    from test.settings import sensors as sensor_settings
    mocker.patch('test.settings.telemetry_lorawan.sensors',
                 sensor_settings.sensors)

    # Invoke datalogger with LoRaWAN telemetry settings for a single duty cycle.
    invoke_datalogger_pycom(caplog, settings=telemetry_lorawan)

    # Capture log output.
    captured = caplog.text

    # Proof it works by verifying log output.
    assert "Starting Terkin datalogger" in captured, captured
    assert "platform: LoPy4" in captured, captured
    assert "[LoRa] Starting LoRa Manager" in captured, captured
    assert "Telemetry transport: CayenneLPP over LoRaWAN/TTN" in captured, captured
    assert "Telemetry status: SUCCESS (1/1)" in captured, captured

    # Check the raw LoRa payload.
    from mocket import Mocket
    assert Mocket.last_request() == bytearray(
        b'\x00g\x01\xbf\x00\x03\x01\xa4\x00\x02\x01\x80\x01g\x01\xe1\x02g\x01\xe1'
        b'\x03g\x00\x97\x00s)7\x00h\x9b\x00\x01\x00')

    # Check the value after decoding from CayenneLPP.
    from cayennelpp import LppFrame
    data = LppFrame.from_bytes(Mocket.last_request()).data

    # System temperature
    assert data[0].channel == 0
    assert data[0].type == 103
    assert data[0].value == (44.7, )

    # Voltage
    assert data[1].channel == 0
    assert data[1].type == 3
    assert data[1].value == (4.2, )

    # Weight (kg)
    assert data[2].channel == 0
    assert data[2].type == 2
    assert data[2].value == (3.84, )

    # DS18B20 temperature
    assert data[3].channel == 1
    assert data[3].type == 103
    assert data[3].value == (48.1, )
    assert data[4].channel == 2
    assert data[4].type == 103
    assert data[4].value == (48.1, )

    # BME280 temperature
    assert data[5].channel == 3
    assert data[5].type == 103
    assert data[5].value == (15.1, )

    # BME280 pressure
    assert data[6].channel == 0
    assert data[6].type == 115
    assert data[6].value == (1055.1, )

    # BME280 humidity
    assert data[7].channel == 0
    assert data[7].type == 104
    assert data[7].value == (77.5, )

    # EOF?
    assert data[8].channel == 0
    assert data[8].type == 1
    assert data[8].value == (0, )

    assert "[LoRa] No downlink message processed" in captured, captured