IoT Sensors
IoT Sensors
Read climate data from Rhombus IoT sensors via the API to monitor temperature, humidity, air quality, and environmental conditions across your facilities.
On this page
Overview
Rhombus IoT sensors (E-series) continuously monitor environmental conditions across your facilities. These sensors capture temperature, humidity, indoor air quality (IAQ), CO2 levels, TVOC, and PM2.5, reporting data through environmental gateways back to the Rhombus platform.
Through the API, you can:
- List sensors and retrieve their current readings
- Query historical data for trend analysis and reporting
- Configure sensors by updating descriptions, locations, and camera associations
- Set up climate alert policies that trigger when readings cross defined thresholds
- Monitor gateways that relay data from sensors to the cloud
- Export data as CSV for external analysis tools
Prerequisites
Before you begin, make sure you have:
- A Rhombus API key with sensor permissions (generated in the Rhombus Console under Settings → Integrations & Developer Resources → API Tokens)
- At least one E-series environmental sensor deployed and connected to an environmental gateway
- A configured location where your sensors are installed
List all sensors
Retrieve the current state of every climate sensor in your organization. This returns each sensor's UUID, name, current readings, battery level, and health status.
import requests
headers = {
"x-auth-scheme": "api-token",
"x-auth-apikey": "YOUR_API_KEY",
"Content-Type": "application/json"
}
response = requests.post(
"https://api2.rhombussystems.com/api/climate/getMinimalClimateStateList",
headers=headers,
json={}
)
data = response.json()
for sensor in data.get("climateStates", []):
name = sensor.get("name", "Unnamed")
temp_c = sensor.get("temperatureCelcius")
humidity = sensor.get("humidity")
iaq = sensor.get("iaq")
battery = sensor.get("batteryPercent")
temp_f = round(temp_c * 9 / 5 + 32, 1) if temp_c else None
print(f"{name}: {temp_f}°F, {humidity}% RH, IAQ {iaq}, Battery {battery}%")const response = await fetch('https://api2.rhombussystems.com/api/climate/getMinimalClimateStateList', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-auth-scheme': 'api-token',
'x-auth-apikey': 'YOUR_API_KEY'
},
body: JSON.stringify({})
});
const data = await response.json();
for (const sensor of data.climateStates || []) {
const tempF = sensor.temperatureCelcius
? (sensor.temperatureCelcius * 9 / 5 + 32).toFixed(1)
: null;
console.log(`${sensor.name}: ${tempF}°F, ${sensor.humidity}% RH, IAQ ${sensor.iaq}, Battery ${sensor.batteryPercent}%`);
}curl -X POST https://api2.rhombussystems.com/api/climate/getMinimalClimateStateList \
-H "Content-Type: application/json" \
-H "x-auth-scheme: api-token" \
-H "x-auth-apikey: YOUR_API_KEY" \
-d '{}'The response includes a climateStates array. Key fields for each sensor:
| Field | Type | Description |
|---|---|---|
sensorUuid | string | Unique identifier for the sensor |
name | string | Display name (e.g., "Server Room Sensor") |
temperatureCelcius | float | Current temperature in Celsius |
humidity | float | Relative humidity percentage |
iaq | float | Indoor Air Quality index |
co2 | float | CO2 level in ppm |
tvoc | float | Total Volatile Organic Compounds |
pm25 | float | PM2.5 particulate matter |
batteryPercent | integer | Battery level (0-100) |
health | string | Sensor health status (GREEN or RED) |
locationUuid | string | Location where the sensor is assigned |
Temperature is returned in Celsius. To convert to Fahrenheit: °F = °C × 9/5 + 32.
Read sensor data
Query historical climate events for a specific sensor over a time range. Each event represents a data point with temperature, humidity, air quality, and other environmental readings.
import requests
import time
headers = {
"x-auth-scheme": "api-token",
"x-auth-apikey": "YOUR_API_KEY",
"Content-Type": "application/json"
}
# Query the last 24 hours of data
now_ms = int(time.time() * 1000)
one_day_ago_ms = now_ms - (24 * 60 * 60 * 1000)
response = requests.post(
"https://api2.rhombussystems.com/api/climate/getClimateEventsForSensor",
headers=headers,
json={
"sensorUuid": "YOUR_SENSOR_UUID",
"createdAfterMs": one_day_ago_ms,
"createdBeforeMs": now_ms,
"limit": 100
}
)
data = response.json()
for event in data.get("climateEvents", []):
temp_c = event.get("temp")
humidity = event.get("humidity")
timestamp = event.get("timestampMs")
temp_f = round(temp_c * 9 / 5 + 32, 1) if temp_c else None
print(f"[{timestamp}] {temp_f}°F, {humidity}% RH")const now = Date.now();
const oneDayAgo = now - (24 * 60 * 60 * 1000);
const response = await fetch('https://api2.rhombussystems.com/api/climate/getClimateEventsForSensor', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-auth-scheme': 'api-token',
'x-auth-apikey': 'YOUR_API_KEY'
},
body: JSON.stringify({
sensorUuid: 'YOUR_SENSOR_UUID',
createdAfterMs: oneDayAgo,
createdBeforeMs: now,
limit: 100
})
});
const data = await response.json();
for (const event of data.climateEvents || []) {
const tempF = event.temp ? (event.temp * 9 / 5 + 32).toFixed(1) : null;
console.log(`[${new Date(event.timestampMs).toISOString()}] ${tempF}°F, ${event.humidity}% RH`);
}curl -X POST https://api2.rhombussystems.com/api/climate/getClimateEventsForSensor \
-H "Content-Type: application/json" \
-H "x-auth-scheme: api-token" \
-H "x-auth-apikey: YOUR_API_KEY" \
-d '{
"sensorUuid": "YOUR_SENSOR_UUID",
"createdAfterMs": 1712620800000,
"createdBeforeMs": 1712707200000,
"limit": 100
}'Each climate event includes these fields:
| Field | Type | Description |
|---|---|---|
timestampMs | integer | Event timestamp in epoch milliseconds |
temp | float | Temperature in Celsius at this reading |
humidity | float | Relative humidity percentage |
iaq | float | Indoor Air Quality index |
co2 | float | CO2 concentration |
tvoc | float | Total Volatile Organic Compounds |
pm25 | float | PM2.5 particulate matter |
heatIndexDegF | float | Calculated heat index in Fahrenheit |
The limit parameter caps the number of events returned. If you need more data points than the limit allows, paginate by adjusting the createdAfterMs and createdBeforeMs window.
Configure sensors
Get sensor configuration
Retrieve the full configuration for a specific sensor, including its threshold settings and associated devices.
import requests
headers = {
"x-auth-scheme": "api-token",
"x-auth-apikey": "YOUR_API_KEY",
"Content-Type": "application/json"
}
response = requests.post(
"https://api2.rhombussystems.com/api/climate/getConfig",
headers=headers,
json={
"uuid": "YOUR_SENSOR_UUID"
}
)
config = response.json().get("config", {})
print(config)const response = await fetch('https://api2.rhombussystems.com/api/climate/getConfig', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-auth-scheme': 'api-token',
'x-auth-apikey': 'YOUR_API_KEY'
},
body: JSON.stringify({
uuid: 'YOUR_SENSOR_UUID'
})
});
const data = await response.json();
console.log(data.config);curl -X POST https://api2.rhombussystems.com/api/climate/getConfig \
-H "Content-Type: application/json" \
-H "x-auth-scheme: api-token" \
-H "x-auth-apikey: YOUR_API_KEY" \
-d '{
"uuid": "YOUR_SENSOR_UUID"
}'Update sensor details
Update a sensor's description, location assignment, or camera associations. Fields you include with their corresponding *Updated flag set to true will be modified; all others remain unchanged.
import requests
headers = {
"x-auth-scheme": "api-token",
"x-auth-apikey": "YOUR_API_KEY",
"Content-Type": "application/json"
}
response = requests.post(
"https://api2.rhombussystems.com/api/climate/updateDetails",
headers=headers,
json={
"uuid": "YOUR_SENSOR_UUID",
"description": "Server Room B - Rack 4 temperature and humidity monitor",
"descriptionUpdated": True,
"locationUuid": "YOUR_LOCATION_UUID",
"locationUuidUpdated": True
}
)
print(response.json())const response = await fetch('https://api2.rhombussystems.com/api/climate/updateDetails', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-auth-scheme': 'api-token',
'x-auth-apikey': 'YOUR_API_KEY'
},
body: JSON.stringify({
uuid: 'YOUR_SENSOR_UUID',
description: 'Server Room B - Rack 4 temperature and humidity monitor',
descriptionUpdated: true,
locationUuid: 'YOUR_LOCATION_UUID',
locationUuidUpdated: true
})
});
const data = await response.json();
console.log(data);curl -X POST https://api2.rhombussystems.com/api/climate/updateDetails \
-H "Content-Type: application/json" \
-H "x-auth-scheme: api-token" \
-H "x-auth-apikey: YOUR_API_KEY" \
-d '{
"uuid": "YOUR_SENSOR_UUID",
"description": "Server Room B - Rack 4 temperature and humidity monitor",
"descriptionUpdated": true,
"locationUuid": "YOUR_LOCATION_UUID",
"locationUuidUpdated": true
}'You must set the corresponding *Updated flag to true for each field you want to change. For example, setting description without descriptionUpdated: true will have no effect.
Set up climate alerts
Climate policies define threshold rules that trigger alerts when environmental readings go above or below specified values. Create a policy and associate it with sensors to receive notifications.
Create a climate policy
This example creates a policy that alerts when temperature exceeds 80°F (26.7°C) or drops below 40°F (4.4°C).
import requests
headers = {
"x-auth-scheme": "api-token",
"x-auth-apikey": "YOUR_API_KEY",
"Content-Type": "application/json"
}
response = requests.post(
"https://api2.rhombussystems.com/api/policy/createClimatePolicy",
headers=headers,
json={
"policy": {
"name": "Server Room Temperature Alert",
"description": "Alert when server room temperature is outside safe operating range",
"scheduledTriggers": [
{
"triggerSet": [
{
"activity": "TEMPERATURE_EXCEEDED_HIGH",
"threshold": 26.7
},
{
"activity": "TEMPERATURE_EXCEEDED_LOW",
"threshold": 4.4
},
{
"activity": "HUMIDITY_EXCEEDED_HIGH",
"threshold": 60.0
}
]
}
]
}
}
)
data = response.json()
print(f"Created policy: {data.get('policyUuid')}")const response = await fetch('https://api2.rhombussystems.com/api/policy/createClimatePolicy', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-auth-scheme': 'api-token',
'x-auth-apikey': 'YOUR_API_KEY'
},
body: JSON.stringify({
policy: {
name: 'Server Room Temperature Alert',
description: 'Alert when server room temperature is outside safe operating range',
scheduledTriggers: [
{
triggerSet: [
{
activity: 'TEMPERATURE_EXCEEDED_HIGH',
threshold: 26.7
},
{
activity: 'TEMPERATURE_EXCEEDED_LOW',
threshold: 4.4
},
{
activity: 'HUMIDITY_EXCEEDED_HIGH',
threshold: 60.0
}
]
}
]
}
})
});
const data = await response.json();
console.log(`Created policy: ${data.policyUuid}`);curl -X POST https://api2.rhombussystems.com/api/policy/createClimatePolicy \
-H "Content-Type: application/json" \
-H "x-auth-scheme: api-token" \
-H "x-auth-apikey: YOUR_API_KEY" \
-d '{
"policy": {
"name": "Server Room Temperature Alert",
"description": "Alert when server room temperature is outside safe operating range",
"scheduledTriggers": [
{
"triggerSet": [
{
"activity": "TEMPERATURE_EXCEEDED_HIGH",
"threshold": 26.7
},
{
"activity": "TEMPERATURE_EXCEEDED_LOW",
"threshold": 4.4
},
{
"activity": "HUMIDITY_EXCEEDED_HIGH",
"threshold": 60.0
}
]
}
]
}
}'Threshold values for temperature triggers use Celsius. Convert your target Fahrenheit values before creating the policy: °C = (°F - 32) × 5/9.
List climate policies
Retrieve all climate policies configured for your organization.
import requests
headers = {
"x-auth-scheme": "api-token",
"x-auth-apikey": "YOUR_API_KEY",
"Content-Type": "application/json"
}
response = requests.post(
"https://api2.rhombussystems.com/api/policy/getClimatePolicies",
headers=headers,
json={}
)
data = response.json()
for policy in data.get("policies", []):
print(f"{policy.get('name')}: {policy.get('uuid')}")const response = await fetch('https://api2.rhombussystems.com/api/policy/getClimatePolicies', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-auth-scheme': 'api-token',
'x-auth-apikey': 'YOUR_API_KEY'
},
body: JSON.stringify({})
});
const data = await response.json();
for (const policy of data.policies || []) {
console.log(`${policy.name}: ${policy.uuid}`);
}curl -X POST https://api2.rhombussystems.com/api/policy/getClimatePolicies \
-H "Content-Type: application/json" \
-H "x-auth-scheme: api-token" \
-H "x-auth-apikey: YOUR_API_KEY" \
-d '{}'Environmental gateways
Environmental gateways are the hardware hubs that receive data from nearby E-series sensors via Bluetooth and relay it to the Rhombus cloud. Each gateway supports multiple sensors and connects over your network.
Use the gateway status endpoint to check connectivity, firmware versions, and which sensors each gateway is serving.
import requests
headers = {
"x-auth-scheme": "api-token",
"x-auth-apikey": "YOUR_API_KEY",
"Content-Type": "application/json"
}
response = requests.post(
"https://api2.rhombussystems.com/api/climate/getMinimalEnvironmentalGatewayStates",
headers=headers,
json={}
)
data = response.json()
for gw in data.get("minimalEnvironmentalGatewayStates", []):
print(f"Gateway: {gw.get('name')} ({gw.get('deviceUuid')})")
print(f" Health: {gw.get('healthStatus')}, Firmware: {gw.get('firmwareVersion')}")const response = await fetch('https://api2.rhombussystems.com/api/climate/getMinimalEnvironmentalGatewayStates', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-auth-scheme': 'api-token',
'x-auth-apikey': 'YOUR_API_KEY'
},
body: JSON.stringify({})
});
const data = await response.json();
for (const gw of data.minimalEnvironmentalGatewayStates || []) {
console.log(`Gateway: ${gw.name} (${gw.deviceUuid})`);
console.log(` Health: ${gw.healthStatus}, Firmware: ${gw.firmwareVersion}`);
}curl -X POST https://api2.rhombussystems.com/api/climate/getMinimalEnvironmentalGatewayStates \
-H "Content-Type: application/json" \
-H "x-auth-scheme: api-token" \
-H "x-auth-apikey: YOUR_API_KEY" \
-d '{}'Get gateway events
Query historical events for a specific gateway, such as connectivity changes and sensor registration.
import requests
import time
headers = {
"x-auth-scheme": "api-token",
"x-auth-apikey": "YOUR_API_KEY",
"Content-Type": "application/json"
}
now_ms = int(time.time() * 1000)
one_week_ago_ms = now_ms - (7 * 24 * 60 * 60 * 1000)
response = requests.post(
"https://api2.rhombussystems.com/api/climate/getEventsForEnvironmentalGateway",
headers=headers,
json={
"deviceUuid": "YOUR_GATEWAY_UUID",
"createdAfterMs": one_week_ago_ms,
"createdBeforeMs": now_ms
}
)
print(response.json())const now = Date.now();
const oneWeekAgo = now - (7 * 24 * 60 * 60 * 1000);
const response = await fetch('https://api2.rhombussystems.com/api/climate/getEventsForEnvironmentalGateway', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-auth-scheme': 'api-token',
'x-auth-apikey': 'YOUR_API_KEY'
},
body: JSON.stringify({
deviceUuid: 'YOUR_GATEWAY_UUID',
createdAfterMs: oneWeekAgo,
createdBeforeMs: now
})
});
const data = await response.json();
console.log(data);curl -X POST https://api2.rhombussystems.com/api/climate/getEventsForEnvironmentalGateway \
-H "Content-Type: application/json" \
-H "x-auth-scheme: api-token" \
-H "x-auth-apikey: YOUR_API_KEY" \
-d '{
"deviceUuid": "YOUR_GATEWAY_UUID",
"createdAfterMs": 1712016000000,
"createdBeforeMs": 1712620800000
}'Export sensor data
Export climate sensor data as a CSV file for use in spreadsheets, data analysis tools, or compliance reporting. Specify a sensor and time range to download all recorded readings.
import requests
import time
headers = {
"x-auth-scheme": "api-token",
"x-auth-apikey": "YOUR_API_KEY",
"Content-Type": "application/json"
}
# Export the last 30 days of data
now_ms = int(time.time() * 1000)
thirty_days_ago_ms = now_ms - (30 * 24 * 60 * 60 * 1000)
response = requests.post(
"https://api2.rhombussystems.com/api/export/climateEvents",
headers=headers,
json={
"sensorUuid": "YOUR_SENSOR_UUID",
"createdAfterMs": thirty_days_ago_ms,
"createdBeforeMs": now_ms
}
)
# Response is CSV data
with open("climate_export.csv", "w") as f:
f.write(response.text)
print("Exported climate data to climate_export.csv")const now = Date.now();
const thirtyDaysAgo = now - (30 * 24 * 60 * 60 * 1000);
const response = await fetch('https://api2.rhombussystems.com/api/export/climateEvents', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-auth-scheme': 'api-token',
'x-auth-apikey': 'YOUR_API_KEY'
},
body: JSON.stringify({
sensorUuid: 'YOUR_SENSOR_UUID',
createdAfterMs: thirtyDaysAgo,
createdBeforeMs: now
})
});
// Response is CSV text
const csvData = await response.text();
console.log(csvData);curl -X POST https://api2.rhombussystems.com/api/export/climateEvents \
-H "Content-Type: application/json" \
-H "x-auth-scheme: api-token" \
-H "x-auth-apikey: YOUR_API_KEY" \
-d '{
"sensorUuid": "YOUR_SENSOR_UUID",
"createdAfterMs": 1710028800000,
"createdBeforeMs": 1712620800000
}' \
-o climate_export.csvThe export endpoint returns CSV data directly in the response body, not JSON. Use the -o flag in cURL or write the response text to a file in your application.
You can also export environmental gateway events with the same pattern using /api/export/environmentalGatewayEvents.
Next steps
Set up automated alert responses when sensor thresholds trigger alarms
Receive real-time push notifications when sensor readings cross thresholds