My sensor is not visible on the map

I have recently added a custom outdoor SPS30-based sensor to my Home Assistant instance. I also wanted to share the data with this project, so I added this to my configuration (+ an automation to trigger the command every minute):

rest_command:
  publish_sensor_community_pm:
    url: "http://api.sensor.community/v1/push-sensor-data/"
    method: post
    content_type: "application/json"
    timeout: 20
    headers:
      X-Pin: 1
      X-Sensor: raspi-5b0179d50c0c75e0
    payload: >-
      {
        "software_version": "HomeAssistant-custom",
        "sensordatavalues": [
          {"value_type": "P0", "value": "{{ states('sensor.outdoor_pm_0_3_1mm_mass_concentration') }}"},
          {"value_type": "P25", "value": "{{ states('sensor.outdoor_pm_0_3_2_5mm_mass_concentration') }}"},
          {"value_type": "P4", "value": "{{ states('sensor.outdoor_pm_0_3_4mm_mass_concentration') }}"},
          {"value_type": "P1", "value": "{{ states('sensor.outdoor_pm_0_3_10mm_mass_concentration') }}"},
          {"value_type": "N05", "value": "{{ states('sensor.outdoor_pm_0_3_0_5mm_count') }}"},
          {"value_type": "N1", "value": "{{ states('sensor.outdoor_pm_0_3_1mm_count') }}"},
          {"value_type": "N25", "value": "{{ states('sensor.outdoor_pm_0_3_2_5mm_count') }}"},
          {"value_type": "N4", "value": "{{ states('sensor.outdoor_pm_0_3_4mm_count') }}"},
          {"value_type": "N10", "value": "{{ states('sensor.outdoor_pm_0_3_10mm_count') }}"},
          {"value_type": "TS", "value": "{{ states('sensor.outdoor_pm_typical_particle_size') }}"}
        ]
      }

The POST requests succeeds and the data is logged, as can be seen e.g. here https://archive.sensor.community/2025-10-19/2025-10-19_sps30_sensor_96589.csv

I can also see the data updating every minute at https://devices.sensor.community:

However, I still cannot see my sensor as a hexagon on the map when switched to “PM2.5 (5 min. mean)”. I can see a dot at the sensor location when I switch to “Sensors at reference stations”, but no values are shown in that mode either.

What am I doing wrong?

1 Like

Please Check that it is the Same Sensor on the device Interface and on the map.

Can you send me the Board iD and the Sensor ID in DM?

It seems like the P2 (PM2.5) value is missing. Please rename P25 to P2.
We do some checks to filter out invalid sensors, one is the existence of both PM10 and PM2.5 values.
(We named those values more than 10 years ago, as most sensor gave only the PM10 and the PM2.5 values …)

1 Like

Thanks, that did the trick.

Does this mean the API documentation is wrong? It lists “P25” as a valid identifier for “2.5µm particles” alongside “P2”:

$ curl -X OPTIONS http://api.sensor.community/v1/push-sensor-data/ | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  4890    0  4890    0     0  24929      0 --:--:-- --:--:-- --:--:-- 25076
{
  "name": "Post Sensor Data List",
  "description": "This endpoint is to POST data from the sensor to the api.",
  "renders": [
    "application/json",
    "text/html"
  ],
  "parses": [
    "application/json",
    "application/x-www-form-urlencoded",
    "multipart/form-data"
  ],
  "actions": {
    "POST": {
      "sensor": {
        "type": "integer",
        "required": false,
        "read_only": false,
        "label": "Sensor"
      },
      "sampling_rate": {
        "type": "integer",
        "required": false,
        "read_only": false,
        "label": "Sampling rate",
        "help_text": "in milliseconds",
        "min_value": -2147483648,
        "max_value": 2147483647
      },
      "timestamp": {
        "type": "datetime",
        "required": false,
        "read_only": false,
        "label": "Timestamp"
      },
      "sensordatavalues": {
        "type": "field",
        "required": true,
        "read_only": false,
        "label": "Sensordatavalues",
        "child": {
          "type": "nested object",
          "required": true,
          "read_only": false,
          "children": {
            "value": {
              "type": "string",
              "required": true,
              "read_only": false,
              "label": "Value"
            },
            "value_type": {
              "type": "choice",
              "required": true,
              "read_only": false,
              "label": "Value type",
              "choices": [
                {
                  "value": "P01",
                  "display_name": "0.1µm particles"
                },
                {
                  "value": "P03",
                  "display_name": "0.3µm particles"
                },
                {
                  "value": "P05",
                  "display_name": "0.5µm particles"
                },
                {
                  "value": "P0",
                  "display_name": "1µm particles"
                },
                {
                  "value": "P2",
                  "display_name": "2.5µm particles"
                },
                {
                  "value": "P3",
                  "display_name": "3µm particles"
                },
                {
                  "value": "P4",
                  "display_name": "4µm particles"
                },
                {
                  "value": "P5",
                  "display_name": "5µm particles"
                },
                {
                  "value": "P1",
                  "display_name": "10µm particles"
                },
                {
                  "value": "durP1",
                  "display_name": "duration 1µm"
                },
                {
                  "value": "durP2",
                  "display_name": "duration 2.5µm"
                },
                {
                  "value": "ratioP1",
                  "display_name": "ratio 1µm in percent"
                },
                {
                  "value": "ratioP2",
                  "display_name": "ratio 2.5µm in percent"
                },
                {
                  "value": "samples",
                  "display_name": "samples"
                },
                {
                  "value": "interval",
                  "display_name": "measurement interval"
                },
                {
                  "value": "min_micro",
                  "display_name": "min_micro"
                },
                {
                  "value": "max_micro",
                  "display_name": "max_micro"
                },
                {
                  "value": "N01",
                  "display_name": "count 0.1µm particles"
                },
                {
                  "value": "N03",
                  "display_name": "count 0.3µm particles"
                },
                {
                  "value": "N05",
                  "display_name": "count 0.5µm particles"
                },
                {
                  "value": "N1",
                  "display_name": "count 1µm particles"
                },
                {
                  "value": "N25",
                  "display_name": "count 2.5µm particles"
                },
                {
                  "value": "N4",
                  "display_name": "count 4µm particles"
                },
                {
                  "value": "N5",
                  "display_name": "count 5µm particles"
                },
                {
                  "value": "N10",
                  "display_name": "count 1µm particles"
                },
                {
                  "value": "TS",
                  "display_name": "typical particle size"
                },
                {
                  "value": "temperature",
                  "display_name": "Temperature"
                },
                {
                  "value": "humidity",
                  "display_name": "Humidity"
                },
                {
                  "value": "pressure",
                  "display_name": "Pa"
                },
                {
                  "value": "altitude",
                  "display_name": "meter"
                },
                {
                  "value": "pressure_sealevel",
                  "display_name": "Pa (sealevel)"
                },
                {
                  "value": "brightness",
                  "display_name": "Brightness"
                },
                {
                  "value": "dust_density",
                  "display_name": "Dust density in mg/m3"
                },
                {
                  "value": "vo_raw",
                  "display_name": "Dust voltage raw"
                },
                {
                  "value": "voltage",
                  "display_name": "Dust voltage calculated"
                },
                {
                  "value": "P10",
                  "display_name": "1µm particles"
                },
                {
                  "value": "P25",
                  "display_name": "2.5µm particles"
                },
                {
                  "value": "durP10",
                  "display_name": "duration 1µm"
                },
                {
                  "value": "durP25",
                  "display_name": "duration 2.5µm"
                },
                {
                  "value": "ratioP10",
                  "display_name": "ratio 1µm in percent"
                },
                {
                  "value": "ratioP25",
                  "display_name": "ratio 2.5µm in percent"
                },
                {
                  "value": "door_state",
                  "display_name": "door state (open/closed)"
                },
                {
                  "value": "lat",
                  "display_name": "latitude"
                },
                {
                  "value": "lon",
                  "display_name": "longitude"
                },
                {
                  "value": "height",
                  "display_name": "height"
                },
                {
                  "value": "hdop",
                  "display_name": "horizontal dilusion of precision"
                },
                {
                  "value": "timestamp",
                  "display_name": "measured timestamp"
                },
                {
                  "value": "age",
                  "display_name": "measured age"
                },
                {
                  "value": "satelites",
                  "display_name": "number of satelites"
                },
                {
                  "value": "speed",
                  "display_name": "current speed over ground"
                },
                {
                  "value": "azimuth",
                  "display_name": "track angle"
                },
                {
                  "value": "noise_LA_min",
                  "display_name": "Sound level min"
                },
                {
                  "value": "noise_LA_max",
                  "display_name": "Sound level max"
                },
                {
                  "value": "noise_LA01",
                  "display_name": "Sound level L01"
                },
                {
                  "value": "noise_LA95",
                  "display_name": "Sound level L95"
                },
                {
                  "value": "noise_LAeq",
                  "display_name": "Sound level Leq"
                },
                {
                  "value": "counts_per_second",
                  "display_name": "Counts per second"
                },
                {
                  "value": "counts_per_minute",
                  "display_name": "Counts per minute"
                },
                {
                  "value": "radiation_msi",
                  "display_name": "MilliSievert"
                },
                {
                  "value": "hv_pulses",
                  "display_name": "Count of high voltage pulses"
                },
                {
                  "value": "counts",
                  "display_name": "Counts"
                },
                {
                  "value": "sample_time_ms",
                  "display_name": "Time per sample"
                },
                {
                  "value": "co_kohm",
                  "display_name": "CO in kOhm"
                },
                {
                  "value": "co_ppb",
                  "display_name": "CO in ppb"
                },
                {
                  "value": "eco2",
                  "display_name": "eCO2 in ppm"
                },
                {
                  "value": "co2_ppm",
                  "display_name": "CO2 in ppm"
                },
                {
                  "value": "no2_kohm",
                  "display_name": "NO2 in kOhm"
                },
                {
                  "value": "no2_ppb",
                  "display_name": "NO2 in ppb"
                },
                {
                  "value": "ozone_ppb",
                  "display_name": "O3 in ppb"
                },
                {
                  "value": "so2_ppb",
                  "display_name": "SO2 in ppb"
                }
              ]
            },
            "sensordata": {
              "type": "integer",
              "required": false,
              "read_only": true,
              "label": "Sensordata"
            }
          }
        }
      },
      "software_version": {
        "type": "string",
        "required": false,
        "read_only": false,
        "label": "Software version",
        "help_text": "sensor software version",
        "max_length": 100
      }
    }
  }
}

Also, I noticed both “N1” and “N10” are documented as “count 1µm particles”, but the firmware sends 10um count to N10, so I did the same.

It’s our map that is not showing the values “tagged” as “P25”. And most users will expect the PM2.5 values tagged as “P2”. So it’s not really wrong, but it’s better to use “P2”.