{"id":26163475,"url":"https://github.com/franciscoraguilera/sensorhub","last_synced_at":"2026-04-12T11:46:27.967Z","repository":{"id":281743200,"uuid":"946280244","full_name":"franciscoraguilera/sensorhub","owner":"franciscoraguilera","description":"Real-time sensor data acquisition using multithread and network monitoring","archived":false,"fork":false,"pushed_at":"2025-11-21T19:45:07.000Z","size":39,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-21T21:19:40.216Z","etag":null,"topics":["c","embbeded-system","linux-kernel","raspberry-pi-3"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/franciscoraguilera.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-03-10T22:32:33.000Z","updated_at":"2025-03-10T22:38:15.000Z","dependencies_parsed_at":"2025-03-10T23:39:15.072Z","dependency_job_id":null,"html_url":"https://github.com/franciscoraguilera/sensorhub","commit_stats":null,"previous_names":["franciscoraguilera/sensorhub"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/franciscoraguilera/sensorhub","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/franciscoraguilera%2Fsensorhub","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/franciscoraguilera%2Fsensorhub/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/franciscoraguilera%2Fsensorhub/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/franciscoraguilera%2Fsensorhub/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/franciscoraguilera","download_url":"https://codeload.github.com/franciscoraguilera/sensorhub/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/franciscoraguilera%2Fsensorhub/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31713876,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-12T06:22:27.080Z","status":"ssl_error","status_checked_at":"2026-04-12T06:21:52.710Z","response_time":58,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","embbeded-system","linux-kernel","raspberry-pi-3"],"created_at":"2025-03-11T14:27:13.272Z","updated_at":"2026-04-12T11:46:27.961Z","avatar_url":"https://github.com/franciscoraguilera.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Advanced Multithreaded Sensor Hub with Network Monitoring\n\nA production-grade embedded application demonstrating real-time sensor data acquisition, multithreaded processing, and remote monitoring capabilities for POSIX-compliant systems.\n\n## Features\n\n- **Hardware Sensor Integration**: Reads temperature data from dual TMP102 sensors via I²C interface\n- **Concurrent Processing**: Leverages POSIX threads with C11 atomics for proper thread safety\n- **Configurable System**: INI-based configuration file for all runtime parameters\n- **Error Recovery**: Automatic handling of single sensor failures with timeout-based fallback\n- **Queue Management**: Bounded queue with configurable size limits to prevent OOM conditions\n- **Data Management**: Processes, logs, and exposes sensor readings through multiple interfaces\n- **Remote Monitoring**: Enhanced HTTP server with proper routing, JSON API, and error handling\n- **Robust Architecture**: Thread-safe communication and graceful shutdown handling\n- **Unit Tests**: Comprehensive test suite for core functionality\n\n## Requirements\n\n- POSIX-compliant system (Linux, Raspberry Pi OS)\n- Two TMP102 temperature sensors connected via I²C\n- C compiler with C11 support (for atomics)\n- CMake 3.10+\n- pthread library\n\n## Hardware Setup\n\n| Component | Configuration |\n|-----------|---------------|\n| TMP102 Sensor 1 | I²C address: 0x48 on `/dev/i2c-1` (configurable) |\n| TMP102 Sensor 2 | I²C address: 0x49 on `/dev/i2c-1` (configurable) |\n| I²C Bus | Connected to SDA/SCL on `/dev/i2c-1` |\n\nConnect both sensors to the system's I²C bus (SDA/SCL pins).\n\n## Configuration\n\nThe application uses a `config.ini` file for all runtime parameters. Create one in the same directory as the executable:\n\n```ini\n# SensorHub Configuration File\n\n[sensors]\n# I2C device path\ni2c_device = /dev/i2c-1\n\n# Sensor 1 configuration\nsensor1_address = 0x48\nsensor1_interval = 1\n\n# Sensor 2 configuration\nsensor2_address = 0x49\nsensor2_interval = 2\n\n# Timeout for single sensor failure (seconds)\n# If one sensor fails for this long, process readings from working sensor only\nsensor_timeout = 10\n\n[network]\n# HTTP server port\nport = 8080\n# Listen backlog\nbacklog = 5\n\n[queue]\n# Maximum queue size (0 = unbounded)\nmax_size = 100\n\n[logging]\n# CSV log file path\nlog_file = sensor_log.csv\n```\n\n### Configuration Options\n\n#### Sensors Section\n- **i2c_device**: Path to I²C device (default: `/dev/i2c-1`)\n- **sensor1_address**: I²C address for sensor 1 in hex (default: `0x48`)\n- **sensor1_interval**: Reading interval for sensor 1 in seconds (default: `1`)\n- **sensor2_address**: I²C address for sensor 2 in hex (default: `0x49`)\n- **sensor2_interval**: Reading interval for sensor 2 in seconds (default: `2`)\n- **sensor_timeout**: Seconds to wait before processing single sensor (default: `10`)\n\n#### Network Section\n- **port**: HTTP server port (default: `8080`)\n- **backlog**: TCP listen backlog (default: `5`)\n\n#### Queue Section\n- **max_size**: Maximum queue size, 0 for unbounded (default: `100`)\n\n#### Logging Section\n- **log_file**: Path to CSV log file (default: `sensor_log.csv`)\n\n## Building and Running\n\n```bash\n# Clone repository\ngit clone https://github.com/franciscoraguilera/sensorhub.git\ncd sensorhub\n\n# Build\nmkdir build \u0026\u0026 cd build\ncmake ..\nmake\n\n# Run tests\nmake check\n# OR\nctest --output-on-failure\n\n# Run application (may require elevated privileges for I²C access)\nsudo ./sensorhub\n\n# Run with custom config\nsudo ./sensorhub /path/to/config.ini\n```\n\nExit the application with `Ctrl+C` for graceful shutdown.\n\n## Monitoring Interface\n\nThe application provides multiple HTTP endpoints:\n\n### HTML Status Page\nAccess at `http://\u003cdevice_ip\u003e:8080/` or `http://\u003cdevice_ip\u003e:8080/index.html`\n\nDisplays:\n- Timestamp of the most recent sensor reading\n- Current temperature from each sensor (or N/A if unavailable)\n- Calculated average temperature\n- Link to JSON API\n\n### JSON API\nAccess at `http://\u003cdevice_ip\u003e:8080/json` or `http://\u003cdevice_ip\u003e:8080/api/status`\n\nReturns JSON format:\n```json\n{\n  \"timestamp\": \"2025-11-21 14:32:45\",\n  \"sensor1\": 23.50,\n  \"sensor2\": 24.62,\n  \"average\": 24.06,\n  \"status\": \"ok\"\n}\n```\n\nIf a sensor is unavailable, its value will be `null`.\n\n### Error Handling\n- **404 Not Found**: Invalid paths return proper 404 page\n- **405 Method Not Allowed**: Non-GET requests return 405 error\n\n### Command-Line Access\n```bash\n# HTML page\ncurl http://\u003cdevice_ip\u003e:8080/\n\n# JSON API\ncurl http://\u003cdevice_ip\u003e:8080/json\n```\n\n## Project Structure\n\n| Component | Description |\n|-----------|-------------|\n| `src/main.c` | Application entry point, thread initialization, signal handling |\n| `src/sensor.c/h` | TMP102 sensor interface via Linux I²C-dev |\n| `src/data_processor.c/h` | Data collection, averaging, timeout handling, CSV logging |\n| `src/queue.c/h` | Thread-safe bounded queue with size limits |\n| `src/network.c/h` | HTTP server with routing, JSON API, proper error codes |\n| `src/utils.c/h` | Shared data structures with C11 atomic operations |\n| `src/config.c/h` | INI configuration file parser |\n| `tests/` | Unit tests for queue, config, and utilities |\n\n## Architecture Improvements\n\n### Thread Safety\n- **C11 Atomics**: Exit flag now uses `atomic_int` for proper thread safety\n- **Mutex Protection**: All shared state properly protected with pthread mutexes\n- **Condition Variables**: Efficient thread wakeup on shutdown\n\n### Error Recovery\n- **Single Sensor Timeout**: If one sensor fails for `sensor_timeout` seconds, system continues with the working sensor\n- **Graceful Degradation**: CSV logs show \"N/A\" for failed sensors\n- **Recovery Detection**: System automatically detects when failed sensor recovers\n\n### Queue Management\n- **Bounded Queue**: Configurable max size prevents out-of-memory conditions\n- **Backpressure**: When queue is full, new readings are dropped with warning\n- **Size Tracking**: Thread-safe queue size tracking\n\n### HTTP Server\n- **Request Parsing**: Proper HTTP method and path parsing\n- **Routing**: Multiple endpoints with different content types\n- **Status Codes**: Proper 200 OK, 404 Not Found, 405 Method Not Allowed\n- **JSON Support**: RESTful JSON API for programmatic access\n- **Styled HTML**: Clean, readable HTML with CSS styling\n\n## Testing\n\nRun the test suite:\n\n```bash\ncd build\nmake check\n```\n\nOr run individual tests:\n```bash\n./test_utils\n./test_config\n./test_queue\n```\n\nTests cover:\n- Queue operations (push, pop, bounds, thread safety)\n- Configuration loading and defaults\n- Atomic exit flag operations\n- Shared state management\n\n## Implementation Notes\n\n- **CSV Logging**: Logs to configured file path (default: `sensor_log.csv`) in current directory\n- **Sensor Timeout**: After configured timeout, system processes single sensor readings\n- **Thread-Safe**: All shared state protected with appropriate synchronization primitives\n- **Configuration**: All hardcoded values moved to `config.ini` for easy customization\n- **Standards Compliance**: Uses C11 standard for modern features (atomics, inline)\n\n## Performance Characteristics\n\n- **Memory**: Minimal footprint, bounded queue prevents unbounded growth\n- **CPU**: Low overhead, sensors poll at configurable intervals (1-2s default)\n- **Network**: Lightweight HTTP server, no external dependencies\n- **Reliability**: Handles sensor failures gracefully, continues operation with degraded capability\n\n## Development\n\n### Adding New Sensors\n1. Update `config.ini` with new sensor configuration\n2. Create new thread function in `sensor.c`\n3. Update `main.c` to spawn new thread\n4. Modify `data_processor.c` to handle additional sensor IDs\n\n### Customizing Intervals\nEdit `config.ini`:\n```ini\nsensor1_interval = 5  # Read every 5 seconds\nsensor2_interval = 10 # Read every 10 seconds\n```\n\n### Changing Network Port\nEdit `config.ini`:\n```ini\n[network]\nport = 9000  # Use port 9000 instead\n```\n\n## Troubleshooting\n\n### I²C Permission Denied\n```bash\nsudo usermod -a -G i2c $USER\n# Log out and back in\n```\n\n### Config File Not Found\nApplication will use built-in defaults and display warning. Create `config.ini` in the same directory as the executable.\n\n### Queue Full Messages\nIncrease queue size in `config.ini`:\n```ini\n[queue]\nmax_size = 200  # Or 0 for unbounded\n```\n\n### Sensor Timeout\nCheck sensor connections and I²C bus. Adjust timeout in `config.ini`:\n```ini\nsensor_timeout = 30  # Wait 30 seconds before fallback\n```\n\n## License\n\nThis project is licensed under the MIT License.\n\n## Author\n\nFran (franciscoaguilera@ieee.org)\n\n## Changelog\n\n### v2.0 - Major Improvements\n- Added INI-based configuration system\n- Implemented C11 atomics for proper thread safety\n- Added bounded queue with configurable size limits\n- Implemented single sensor failure recovery with timeouts\n- Enhanced HTTP server with routing, JSON API, and proper error codes\n- Added comprehensive unit test suite\n- Improved error handling throughout\n- Better logging and diagnostics\n\n### v1.0 - Initial Release\n- Basic multithreaded sensor reading\n- CSV logging\n- Simple HTTP status page\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffranciscoraguilera%2Fsensorhub","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffranciscoraguilera%2Fsensorhub","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffranciscoraguilera%2Fsensorhub/lists"}