Smart Building Occupancy Sensing With AI
10 min read · updated August 11, 2026
A motion sensor knows whether a room is empty. It does not know whether there are two people in it or twenty, and for ventilation control, space planning and energy that difference is the whole question. CO2 answers it, slowly and indirectly, through a mass balance you can write down.
What each sensor can and cannot tell you
- Passive infrared motion. Detects moving warm bodies in line of sight. Fast, cheap, no privacy concerns, and it saturates immediately: one person and thirty produce the same output. Its characteristic failure is the still occupant — someone reading quietly falls below the detection threshold and the room is declared empty, which is why lights go off in meetings.
- CO2. Rises in proportion to how many people are breathing and falls with ventilation. It is genuinely quantitative but has a long time constant, so it lags occupancy changes by many minutes and cannot see a short meeting at all.
- Wi-Fi or Bluetooth association counts. Cheap where the infrastructure already exists, and biased by a factor that changes per person and per site — some people carry three devices, some carry none that associate.
- Thermal arrays and depth sensors. Low-resolution infrared arrays count people directly without producing identifiable images, which is a meaningful privacy distinction from cameras. They need line of sight and careful mounting, and they are the most expensive option per room.
None is sufficient alone, and the pairing that recovers the most information for the least money is CO2 with motion, because their failure modes are complementary: motion is fast and non-quantitative, CO2 is quantitative and slow.
The CO2 mass balance
The reason CO2 is quantitative is that it obeys a simple conservation equation. For a well-mixed room of volume V with ventilation rate Q of outdoor air, outdoor concentration C_out, and n occupants each generating CO2 at rate G:
V * dC/dt = n * G - Q * (C - C_out) At steady state (dC/dt = 0): C_ss = C_out + n * G / Q n = (C_ss - C_out) * Q / G Time constant of the approach to steady state: tau = V / Q
Everything about the practical behaviour of CO2 sensing falls out of those three lines. The steady-state rise above outdoor concentration is directly proportional to occupancy and inversely proportional to ventilation, so an occupancy estimate is impossible without knowing the ventilation rate. And tau is the room volume divided by the airflow, which for a typical office room is on the order of ten to twenty minutes — that is the lag, and no signal processing removes it, because the physics has not happened yet.
The generation rate G depends on body size and activity level. ASHRAE Standard 62.1 and its supporting literature give generation rates for adults at various metabolic rates; a commonly used figure for sedentary adult office work is on the order of 0.005 L/s per person, and the ASHRAE standards documentation is the reference to check for the value appropriate to your occupancy category. Children generate substantially less, which is why a classroom calibrated with adult figures under-counts badly.
A worked estimate
A meeting room, with every input stated as an assumption:
ASSUMPTIONS
room volume V = 60 m3 (5 x 4 x 3 m)
ventilation Q = 60 m3/h = 0.0167 m3/s
outdoor CO2 C_out = 420 ppm
generation rate G = 0.005 L/s = 5e-6 m3/s per person
measured steady C_ss = 980 ppm
OCCUPANCY
rise = (980 - 420) ppm = 560 ppm = 560e-6 (volume fraction)
n = rise * Q / G
= 560e-6 * 0.0167 / 5e-6
= 9.35e-6 / 5e-6
= 1.87 -> about 2 people
TIME CONSTANT
tau = V / Q = 60 / 60 = 1 hour
REACHING STEADY STATE
after 1 tau : 63% of the way
after 2 tau : 86%
after 3 tau : 95%
So a one-hour meeting in this room never reaches steady state, and
reading occupancy off the raw concentration under-counts throughout.The time constant is the result that changes how you build the system. At one hour, most meetings end before the signal settles, so a steady-state formula is systematically biased low. The fix is to use the differential form instead: estimate n from the rate of change plus the current concentration, since n = (V * dC/dt + Q * (C - C_out)) / G holds at every instant, not just at equilibrium. That responds within minutes rather than hours, at the cost of differentiating a noisy signal, which is exactly the situation a Kalman filter with occupancy in the state is designed for.
Fusing CO2 with motion
The fusion is not a weighted average of two occupancy estimates, because motion does not produce one. It is better framed as motion constraining the state that the CO2 estimator is tracking.
- Motion gates the zero. No motion for a sustained period plus falling CO2 is strong evidence of an empty room, and lets the estimator clamp to zero rather than decaying slowly through the ventilation time constant. This alone removes the most visible error.
- Motion sets the timing, CO2 sets the magnitude. A motion event marks the arrival edge precisely; the concentration response that follows, interpreted through the balance, gives the number. Anchoring the differential estimator’s change points to motion events makes it far more stable than differentiating alone.
- Disagreement is information. Rising CO2 with no motion for an hour usually means the motion sensor cannot see part of the room, not that the room is empty. Persistent motion with flat CO2 usually means the door is open and the room is not the well-mixed volume the model assumes.
Implemented as a state estimator, occupancy is a slowly varying state driven by the mass balance, and the motion channel enters as a separate observation with its own likelihood — the general machinery is in sensor fusion algorithms, and the resulting model of the room, continuously corrected by telemetry, is a small digital twin.
What breaks in a real building
- Ventilation is not constant and is often unknown. Demand-controlled ventilation changes
Qin response to the very CO2 reading you are using, which closes a feedback loop and makes the naive inversion badly wrong. Read the airflow or damper position from the building management system and use it, or expect the estimate to fail exactly when the room is busy. - Rooms are not well mixed. The balance assumes one uniform concentration. A sensor next to a supply diffuser reads close to outdoor air regardless of occupancy. Sensor placement changes the answer more than the algorithm does — away from diffusers, doors and the occupants’ immediate breathing zone, at seated head height.
- NDIR sensors drift and most self-calibrate by assumption. Many low-cost non-dispersive infrared sensors use automatic baseline correction, which assumes the lowest reading over the past week is outdoor air. In a space occupied continuously, that assumption is false and the sensor calibrates itself to a wrong baseline. Check whether the feature can be disabled, and monitor for calibration drift against a reference.
- Open doors and adjoining spaces. The single-zone balance stops applying the moment air exchanges freely with a corridor. A door sensor is a cheap way to know when to distrust the estimate.
- Occupancy data about people has governance obligations. Even without cameras, room-level occupancy in a small office can identify individuals, and in many jurisdictions workplace monitoring carries specific consultation and notice requirements. That is a legal question to settle with the people responsible for it before deployment, not a modelling parameter.