Skip to content

Virtual sensor

The virtual sensor stands in for a physical ESP sensor. Instead of reading a BME280 and a BH1750, it serves either random test values or real weather data from OpenWeatherMap for a place you choose. The node finds and records it exactly like a physical sensor; no hardware is needed.

The virtual sensor runs as a service on the node and announces itself over mDNS as a _sensor._tcp device, so it appears on the node’s main page next to any physical sensors. Use it to:

  • log outdoor weather with your experiments, for example to relate behaviour to the day or the season, without installing a sensor outside;
  • have a sensor for tests or demonstrations when no hardware is available.

It reports the same four readings as the physical sensors (temperature, humidity, pressure and light). The node writes them to a CSV file in /ethoscope_data/sensors/ and attaches them to experiments by location, as for the ESP sensors.

  • Script: accessories/hardware/etho_sensor/virtual_sensor.py.
  • Service: ethoscope_sensor_virtual.service, run as the node user on port 8001.
  • Discovery: an mDNS service of type _sensor._tcp.local., which the node’s sensor scanner finds without any registration.
  • Endpoints: GET / (current readings as JSON), GET /id (the sensor’s stable ID) and POST /set (change name or location).
  • Data: with a weather location and an API key, live data from OpenWeatherMap, cached for ten minutes to stay within the free tier’s rate limit; otherwise plausible random values.
  • No alerts: the virtual sensor reports alerts: false, so the node’s temperature alerts ignore it.

The sensor’s ID is derived from the node’s hostname, so it stays the same across restarts.

The service comes with the node but is not started by default. Enable and start it with:

Terminal window
sudo systemctl enable --now ethoscope_sensor_virtual.service

The settings are read from the virtual_sensor section of ethoscope.conf, in the node’s configuration directory (by default /ethoscope_data/config; see where the configuration lives). Edit them in the Virtual sensor step of the node’s setup wizard, or by hand.

Key Meaning
enabled Whether the virtual sensor is active.
sensor_name The name shown on the node; any label.
location An incubator name, to attach the readings to experiments, or a descriptive label such as Outside.
weather_location Where to take real weather from. Leave it out for random values.
api_key Your OpenWeatherMap API key. Without it the sensor serves random values.

Random values only, the simplest case:

{
"virtual_sensor": {
"enabled": true,
"sensor_name": "test-sensor",
"location": "Incubator_1"
}
}

Real weather:

{
"virtual_sensor": {
"enabled": true,
"sensor_name": "Outside",
"location": "Outside",
"weather_location": "2643743",
"api_key": "YOUR_OPENWEATHER_API_KEY"
}
}
  1. Create a free account at openweathermap.org.
  2. Copy your API key from the dashboard. New keys can take a couple of hours to become active.
  3. Set api_key and weather_location as above, or pass them on the command line or in the OPENWEATHER_API_KEY environment variable.

weather_location accepts three formats:

Format Example
City ID (recommended, as it is unambiguous) 2643743 (London)
City name and country code London,GB, Paris,FR, Rome,IT
Latitude and longitude 51.5074,-0.1278

To find a city ID, search for the city on openweathermap.org: the number is in the address of its page. OpenWeatherMap does not report illuminance, so the light reading is estimated from cloud cover and the time of day.

To test the sensor, for example to check an API key before enabling the service, run the script directly:

Terminal window
python3 accessories/hardware/etho_sensor/virtual_sensor.py -z "2643743" -k YOUR_API_KEY -L Outside -n Outside
Option Purpose
-n, --name Sensor name
-L, --location Sensor location
-z, --zipcode Weather location (city ID, City,CC or lat,lon)
-k, --api-key OpenWeatherMap API key (or set OPENWEATHER_API_KEY)
-c Read the settings from a JSON file
-s, --save Save the given options into the file named with -c
-l, --listener List the _sensor._tcp devices on the network instead of acting as a sensor

A settings file for -c is flat, not nested under a virtual_sensor key:

{
"sensor_name": "Outside",
"location": "Outside",
"weather_location": "2643743",
"api_key": "YOUR_OPENWEATHER_API_KEY"
}
Terminal window
# use an existing settings file
python3 virtual_sensor.py -c config_sensor.json
# save the given options into config_sensor.json for later use
python3 virtual_sensor.py -z "2643743" -k YOUR_API_KEY -L Outside -n Outside -c config_sensor.json -s

Check that the sensor answers:

Terminal window
curl http://localhost:8001/ # current readings
curl http://localhost:8001/id # stable sensor ID