Room occupancy and people count card
Shows room occupancy as a state - Free, Filling, Busy or Full - with the people count against a configured capacity.
Who it’s for
Facilities and workplace teams watching how full a space is right now - a meeting room, a co-working floor, a gym, a washroom, a car park - and anyone who has wired a people counter or an occupancy sensor to ThingsBoard and wants the dashboard to answer “is there room?” at a glance. The question on the wall is not “how many sensors reported” but “is this space free, filling, busy or full”, read across the room without doing arithmetic.
What it does
Shows room occupancy as a state, not a number. A meeting room with a capacity of 30 reporting 17
people reads Filling in large type, with 17 of 30 · room for 13 more below it and a fill figure
underneath. The state - Free, Filling, Busy or Full - comes from percentage-of-capacity
thresholds, so the same configuration fits a four-person huddle room and a two-hundred-person hall.
- Occupancy as a state, not just a number. The state word is the largest thing on the card, above the count. That inversion is what sets it apart from a plain value card.
- A fill figure that shows the thresholds, not only the value. The default zones figure draws the three thresholds as pale regions with a solid measure bar on top, so you see where the limits are as well as where you are. Switch to seats for a grid of one dot per person.
- An empty room is a good state. A count of 0 reads a calm Free - empty, never the greyed “no data” look a single-value card falls into at zero.
- An overcrowded room stays honest. A count above capacity keeps the true number -
34 / 30- clamps the bar and hatches its end, and the footer names both113% of capacityand+4 over capacity. - Optional in / out line. For door counters that report both, a cumulative
↑ in · ↓ outline - display only - it never changes the count, the fill or the state. - Renders the count it is given: it does not derive occupancy from raw sensor events, chart it over time, or decide who may enter.
The card is entity-neutral - no wording inside it names a “room”, so the same card serves a floor or a building rollup unchanged.
Requirements
A device that reports a current occupancy count as a numeric telemetry key - a people counter, a PIR-based tally, a turnstile total, or a calculated field that produces the number. The card renders the count - it does not derive it.
How to set up
Defaults work as soon as one key is bound. A fresh card previews a space at 17 of 30.
Data keys
Occupancy, capacity and direction keys resolve by name, never by bind order - an index-based rule would be behaviour the settings do not declare.
| Key | Role | Type | Description |
|---|---|---|---|
| user-configured - Occupancy count key | Main value | Timeseries or Attribute | The current people count. Leave the setting empty and the card takes the first bound key no other role claims |
| user-configured - Capacity key | Capacity bound | Timeseries or Attribute | Read only when Capacity source is From a data key. An attribute suits a limit that is fixed per space |
| user-configured - Entries (in) key | In total | Timeseries | Read only with Show in / out line on. Display only, it never changes the count, the fill or the state |
| user-configured - Exits (out) key | Out total | Timeseries | The other half of the in / out line. Both direction keys are required together |
Bind the count key on the Data tab. A count key bound but not yet reporting reads Waiting, a different card from No data (no key bound), so you look in the right place. When capacity is missing, zero or negative the card shows the count alone rather than a broken fraction, and with Show in / out line on but either direction key unbound the line shows an error rather than disappearing, so a misconfiguration stays visible.
Data
| Setting | Default | Effect |
|---|---|---|
| Capacity source | Fixed value | Where the maximum comes from - the Capacity setting, or a bound Capacity key |
| Capacity | 30 | The maximum the space holds, read when the source is the fixed value |
| Show in / out line | Off | Adds the cumulative in / out line and brings in both direction keys |
Occupancy states
Both thresholds are shares of capacity, so one configuration fits a four-person huddle room and a two-hundred-person hall alike.
| Setting | Default | Effect |
|---|---|---|
| Filling at (% of capacity) | 33 | At or above this share the state reads Filling, below it Free |
| Busy at (% of capacity) | 70 | At or above this share the state reads Busy, and at capacity it reads Full |
| States | Free, Filling, Busy, Full | The word and fill colour for each of the four states, in order |
How to customize
Each control below is a setting in the widget’s Data, Occupancy states and Appearance groups.
- To label the card - Card label - leave it empty to use the datasource entity name.
- To show an icon beside the label - Icon takes a Material icon name - groups, meeting_room, sensor_occupied. Clear the field to hide it.
- To rename or recolour the states - States holds the four in order: Free, Filling, Busy, Full. Each row carries the word the card shows and the colour it fills with, so Available and Occupied replace Free and Busy in one pass. Leave a label empty to keep the default word. The state word takes a readable ink derived from the colour, so even a light colour stays legible on both light and dark dashboards.
- To draw seats instead of zones - Fill figure → Seats - one dot per person. Seat cap (default 40) is the capacity above which seats become uncountable, so the card falls back to zones in three cases, all deliberate: capacity above the seat cap, a dot that would render below 12px at the current widget size, and the horizontal layout.
- To use a short wide tile - Layout → Horizontal puts the state word and figure side by side, with its figure always zones.
- To show a percentage footer - Show percentage footer. It is off by default and forced on whenever the count exceeds capacity - an overflow is not something a configuration may hide.
- To dim a stale card - Dim as stale after (minutes) - the card fades when the count stops updating for that long. 0 keeps it bright.
- To restyle the text - State word font, Sub-line font and Label font.
Tips
- Set the thresholds once as percentages and reuse the card across every space, whatever its capacity
- a 4-desk room and a 200-seat hall share one configuration.
- Bind capacity as an attribute key when each room has a different limit: the card reads it per entity through the normal subscription, so one dashboard widget serves a whole building.
- Use Seats for rooms up to a few dozen places, where one dot per person reads instantly, and let it fall back to zones for the big spaces - the same card handles both.
- Keep Dim as stale a few minutes above your reporting interval to catch a counter that has gone quiet, without flagging a healthy quiet room.
Share Your Widget with the Community
Built a custom widget? Export it as a JSON from ThingsBoard and publish it to the IoT Hub through a simple 4-step wizard (Upload, Listing, Readme, Review & Submit). Share it with thousands of ThingsBoard developers worldwide and get featured in the catalog.