This document outlines new features and enhancements for the SensorAPI to improve real-time sensor status tracking and data management.
Priority: High
Status: Not Started
Estimated Effort: Medium
Automatically update sensor metadata when new readings are received to maintain accurate real-time status information.
- Task: Update
sensor.latestReadingafter a new sensor reading occurs - Acceptance Criteria:
- When a new
SensorReadingis created, automatically update the correspondingSensor.latest_readingfield - The latest reading should always point to the most recent reading by timestamp
- Ensure atomic updates to prevent race conditions
- Add GraphQL field resolver for
Sensor.latestReadingto return the actual reading data
- When a new
- Task: Set
sensor.isOnlinebased on recent activity - Acceptance Criteria:
- Mark sensor as online (
isOnline = true) when a new reading is received - Mark sensor as offline (
isOnline = false) if no readings received within configurable threshold (default: 5 minutes) - Implement background job or trigger to check and update offline sensors periodically
- Mark sensor as online (
- Task: Set
sensor.lastSeenwhen sensor activity occurs - Acceptance Criteria:
- Update
lastSeentimestamp whenever a new reading is received - Use the reading's
timestampfield (when measurement was taken) orreceived_at(when API received it) - Ensure timestamp is in UTC
- Update
- Task: Manage
sensor.isActivestatus appropriately - Acceptance Criteria:
- New sensors should default to
isActive = true - Provide GraphQL mutation to manually activate/deactivate sensors
- Inactive sensors should still accept readings but may be filtered from default queries
- after receiving a sensor reading the status is set to active
- Consider auto-deactivation for sensors offline for extended periods (configurable, e.g., 24 hours)
- New sensors should default to
- Ensure
Sensor.latest_reading_idforeign key exists and is properly indexed - Add database triggers or use ORM event listeners for automatic updates
- Consider adding
last_reading_atfield for faster queries without joins
type Sensor {
# Existing fields...
latestReading: SensorReading # Implement this resolver
isOnline: Boolean!
lastSeen: DateTime
isActive: Boolean!
}
input UpdateSensorStatusInput {
isActive: Boolean
}
type Mutation {
updateSensorStatus(id: ID!, input: UpdateSensorStatusInput!): Sensor
}- Implement periodic job to check sensor online status
- Use APScheduler or similar for Python background tasks
- Consider Redis for job queuing in production
- Database migration to add any missing fields/indexes
- Background job scheduler setup
- Consider caching layer for frequently accessed sensor status
- Unit tests for status update logic
- Integration tests for GraphQL mutations
- Performance tests for bulk status updates
- Test edge cases (duplicate readings, out-of-order timestamps)
- Track sensor online/offline status changes
- Monitor background job execution
- Alert on sensors going offline unexpectedly
- Dashboard showing sensor health overview
- Calculate health score based on reading frequency, data quality, and uptime
- Predictive offline detection based on reading patterns
- Optimize database updates for high-volume scenarios
- Bulk operations for sensor status management
- Group sensors by location, type, or custom tags
- Bulk operations on sensor groups
- Configurable rules for sensor offline alerts
- Integration with notification systems (email, Slack, etc.)
- Ensure backward compatibility with existing API consumers
- Consider rate limiting for sensor reading ingestion
- Plan for horizontal scaling if sensor volume grows significantly
- Document new features in GraphQL schema descriptions