Skip to content

Commit d8bcef1

Browse files
Copilotmatthias-bs
andauthored
Add copilot-instructions.md for codebase context (#285)
* Initial plan * Add comprehensive copilot-instructions.md Co-authored-by: matthias-bs <83612361+matthias-bs@users.noreply.github.com> * Address PR feedback: correct board name, remove broadcast ID, add package.json to version management Co-authored-by: matthias-bs <83612361+matthias-bs@users.noreply.github.com> * Update board configurations: clarify LORAWAN_NODE and add DFROBOT_COVER_LORA Co-authored-by: matthias-bs <83612361+matthias-bs@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: matthias-bs <83612361+matthias-bs@users.noreply.github.com>
1 parent c11ad8a commit d8bcef1

File tree

1 file changed

+353
-0
lines changed

1 file changed

+353
-0
lines changed

copilot-instructions.md

Lines changed: 353 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,353 @@
1+
# GitHub Copilot Instructions for BresserWeatherSensorReceiver
2+
3+
## Project Overview
4+
5+
**BresserWeatherSensorReceiver** is an Arduino library for receiving and decoding 868 MHz wireless data from Bresser weather sensors using ESP32, ESP8266, or RP2040 microcontrollers with RF transceivers (CC1101, SX1276/RFM95W, SX1262, or LR1121).
6+
7+
### Key Responsibilities
8+
- Receive and decode RF messages from multiple Bresser sensor types (5-in-1, 6-in-1, 7-in-1, 8-in-1 weather stations, lightning sensors, water leakage sensors, etc.)
9+
- Support multiple simultaneous sensors with ID filtering and slot management
10+
- Provide post-processing for rain gauge statistics and lightning detection
11+
- Integrate with MQTT, WiFi, OLED displays, SD cards, and Home Assistant
12+
13+
## Architecture
14+
15+
### Core Classes
16+
17+
| Class | File | Purpose |
18+
|-------|------|---------|
19+
| `WeatherSensor` | `WeatherSensor.h/.cpp` | Main receiver class - RF reception, message decoding, multi-sensor management |
20+
| `RainGauge` | `RainGauge.h/.cpp` | Rain statistics - hourly/daily/weekly/monthly accumulation, overflow handling |
21+
| `Lightning` | `Lightning.h/.cpp` | Lightning strike counting, hourly history, post-processing |
22+
| `InitBoard` | `InitBoard.h/.cpp` | Board-specific initialization for 15+ ESP32/ESP8266 variants |
23+
24+
### Key Design Patterns
25+
26+
1. **Union-Based Memory Efficiency**: Sensor data stored in unions to minimize memory footprint
27+
2. **Conditional Compilation**: Features selectable via `WeatherSensorCfg.h` macros
28+
3. **Circular History Buffers**: 60-minute history for rain/lightning with wraparound
29+
4. **Preferences Storage**: Flash-based persistence for sensor configs, rain/lightning history
30+
5. **Slot-Based Multi-Sensor**: Dynamic `std::vector<Sensor>` for managing multiple sensors
31+
6. **Decoder Chain**: Try decoders in order (7-in-1 → 6-in-1 → 5-in-1 → Lightning → Leakage) until success
32+
33+
## Coding Conventions
34+
35+
### Naming Conventions
36+
- **Classes**: `CamelCase` (e.g., `WeatherSensor`, `RainGauge`)
37+
- **Functions/Methods**: `camelCase` (e.g., `getMessage()`, `getData()`)
38+
- **Variables**: `snake_case` (e.g., `sensor_id`, `wind_speed_ms`)
39+
- **Constants/Macros**: `UPPER_SNAKE_CASE` (e.g., `NUM_SENSORS`, `BRESSER_5_IN_1`)
40+
- **Private Members**: No specific prefix convention
41+
42+
### File Organization
43+
```
44+
src/
45+
├── WeatherSensor.h/.cpp # Core receiver & decoder orchestration
46+
├── WeatherSensorCfg.h # User configuration (pins, sensors, decoders)
47+
├── WeatherSensorConfig.cpp # Runtime configuration via JSON
48+
├── WeatherSensorDecoders.cpp # Protocol decoders (5/6/7-in-1, Lightning, Leakage)
49+
├── WeatherUtils.h/.cpp # Utility functions (dew point, wind chill, etc.)
50+
├── RainGauge.h/.cpp # Rain statistics module
51+
├── Lightning.h/.cpp # Lightning post-processing module
52+
└── InitBoard.h/.cpp # Board initialization
53+
54+
examples/
55+
├── BresserWeatherSensorBasic/ # Simple receive & print
56+
├── BresserWeatherSensorMQTT/ # MQTT integration
57+
├── BresserWeatherSensorMQTTCustom/ # Advanced MQTT with local copy of library
58+
└── [12 other examples]
59+
60+
test/
61+
└── src/ # CppUTest unit tests
62+
```
63+
64+
### Header File Structure
65+
Every source file must include:
66+
1. **File header comment block** with:
67+
- File name and purpose
68+
- Project URL: `https://github.com/matthias-bs/BresserWeatherSensorReceiver`
69+
- Credits/references to original work
70+
- MIT License text
71+
- Detailed history log with dates and changes
72+
- Author: Matthias Prinke
73+
2. **Include guards** (not `#pragma once`)
74+
3. **Arduino.h include** for Arduino types
75+
4. **Doxygen-style comments** for public API
76+
77+
### Documentation Standards
78+
- Use `///` for Doxygen comments on functions/classes
79+
- Use `//` for inline explanations
80+
- Add `@brief`, `@param`, `@return` tags for public methods
81+
- Reference rtl_433 project sources when applicable
82+
- Document protocol details and sensor quirks extensively
83+
84+
### Code Style
85+
- **Indentation**: 4 spaces (no tabs)
86+
- **Braces**: Opening brace on same line for functions/classes
87+
- **Line Length**: No strict limit, but keep readable (~100-120 chars preferred)
88+
- **Comments**: Extensive inline documentation explaining RF protocols, sensor behavior, edge cases
89+
- **Debug Output**: Use `log_d()`, `log_i()`, `log_w()`, `log_e()` macros (ESP32/ESP8266)
90+
- **Conditional Features**: Wrap optional features in `#ifdef FEATURE_NAME`
91+
92+
### Error Handling
93+
- Return `DecodeStatus` enum from decoders (e.g., `DECODE_OK`, `DECODE_DIG_ERR`, `DECODE_CHK_ERR`)
94+
- Use validation flags in structs (e.g., `temp_ok`, `humidity_ok`, `wind_ok`)
95+
- Check sensor startup flag to prevent false rain/lightning counts after battery replacement
96+
- Validate CRC/checksums using `lfsr_digest16()` or `crc16()`
97+
98+
## Common Patterns & Idioms
99+
100+
### Conditional Compilation
101+
Use macros in `WeatherSensorCfg.h` to enable/disable features:
102+
```cpp
103+
#define BRESSER_5_IN_1 // Enable 5-in-1 decoder
104+
#define BRESSER_6_IN_1 // Enable 6-in-1 decoder
105+
#define BRESSER_7_IN_1 // Enable 7-in-1 decoder
106+
#define BRESSER_LIGHTNING // Enable lightning decoder
107+
#define LIGHTNING_USE_PREFS // Store lightning history in flash
108+
```
109+
110+
### Preferences API (Flash Storage)
111+
```cpp
112+
#include <Preferences.h>
113+
Preferences preferences;
114+
preferences.begin("namespace", false); // false = read/write
115+
uint32_t value = preferences.getUInt("key", default_value);
116+
preferences.putUInt("key", value);
117+
preferences.end();
118+
```
119+
120+
### Rain Gauge Usage Pattern
121+
```cpp
122+
RainGauge rainGauge;
123+
rainGauge.reset(); // Reset all statistics
124+
rainGauge.update(timestamp, rain_mm, startup_flag);
125+
float hourly = rainGauge.pastHour();
126+
float daily = rainGauge.currentDay();
127+
```
128+
129+
### Lightning Detection Pattern
130+
```cpp
131+
Lightning lightning;
132+
lightning.reset();
133+
lightning.update(timestamp, strike_count, distance_km, startup_flag);
134+
uint8_t strikes_past_hour = lightning.pastHour();
135+
```
136+
137+
### Multi-Sensor Slot Management
138+
```cpp
139+
// Add sensor configuration
140+
std::vector<uint32_t> sensor_ids = {0x39582376};
141+
weatherSensor.setSensorsCfg(sensor_ids);
142+
143+
// Get data with timeout
144+
int decode_status = weatherSensor.getData(RX_TIMEOUT, DATA_COMPLETE);
145+
if (decode_status == DECODE_OK) {
146+
for (size_t i = 0; i < weatherSensor.sensor.size(); i++) {
147+
if (weatherSensor.sensor[i].valid) {
148+
uint32_t id = weatherSensor.sensor[i].sensor_id;
149+
// Process sensor data...
150+
}
151+
}
152+
}
153+
```
154+
155+
### Decoder Implementation
156+
Decoders should:
157+
1. Check message length: `if (msg_size != EXPECTED_SIZE) return DECODE_INVALID;`
158+
2. Validate CRC/checksum: `if (calculated_crc != expected_crc) return DECODE_CHK_ERR;`
159+
3. Extract sensor ID and type
160+
4. Decode fields with proper scaling/units
161+
5. Set validity flags for each field
162+
6. Return `DecodeStatus`
163+
164+
## Platform-Specific Notes
165+
166+
### Supported Platforms
167+
- **ESP32** (primary target) - full feature support
168+
- **ESP8266** - limited RAM, use carefully with multiple sensors
169+
- **RP2040** - limited testing, basic features supported
170+
171+
### Board Configurations
172+
Predefined board configs in `WeatherSensorCfg.h`:
173+
- `LORAWAN_NODE` - Custom board based on DFRobot FireBeetle ESP32
174+
- `DFROBOT_COVER_LORA` - DFRobot FireBeetle ESP32 with FireBeetle Cover LoRa Radio
175+
- `TTGO_LORA32` - TTGO ESP32 with integrated SX1276
176+
- `ADAFRUIT_FEATHER_ESP32S2` - Adafruit Feather with RFM95W
177+
- `ARDUINO_DFROBOT_FIREBEETLE_ESP32` - DFRobot FireBeetle ESP32
178+
- `ESP32_LORA_V2` - Heltec ESP32 LoRa V2
179+
- `M5CORE2_MODULE_LORA868` - M5Stack Core2 with LoRa module
180+
181+
### Pin Configuration
182+
Define pins in `WeatherSensorCfg.h`:
183+
```cpp
184+
#define PIN_RECEIVER_CS 27 // SPI chip select
185+
#define PIN_RECEIVER_IRQ 21 // CC1101: GDO0 / SX127x: DIO0
186+
#define PIN_RECEIVER_GPIO 33 // CC1101: GDO2 / SX127x: DIO1
187+
#define PIN_RECEIVER_RST 32 // Reset pin (SX127x) or RADIOLIB_NC (CC1101)
188+
```
189+
190+
## Testing
191+
192+
### Framework
193+
- **CppUTest** for unit tests (desktop)
194+
- **arduino-ci** for Arduino library validation
195+
196+
### Test Structure
197+
```cpp
198+
#include "CppUTest/TestHarness.h"
199+
TEST_GROUP(TestGroupName) {
200+
void setup() { /* Initialize */ }
201+
void teardown() { /* Cleanup */ }
202+
};
203+
204+
TEST(TestGroupName, TestName) {
205+
// Arrange
206+
// Act
207+
// Assert
208+
DOUBLES_EQUAL(expected, actual, tolerance);
209+
}
210+
```
211+
212+
### Running Tests
213+
```bash
214+
# Run CppUTest
215+
cd test
216+
make
217+
218+
# Run Arduino CI
219+
# Automated via GitHub Actions
220+
```
221+
222+
## Dependencies
223+
224+
### Core Dependencies
225+
- **RadioLib** (7.5.0) - RF transceiver abstraction layer
226+
- **ArduinoJson** (7.4.2) - JSON parsing for configuration
227+
- **Preferences** (2.2.2) - Flash storage API (ESP32/ESP8266)
228+
229+
### Optional Dependencies
230+
- **MQTT** (2.5.2) - MQTT client for IoT integrations
231+
- **WiFiManager** (2.0.17) - WiFi credential management
232+
- **ESP_DoubleResetDetector** (1.3.2) - Factory reset via double-reset
233+
- **ESPAsyncWebServer** (3.9.4) - Web interface for configuration
234+
- **Adafruit_SSD1306** (2.5.16) - OLED display support
235+
- **RTClib** (2.1.4) - Real-time clock support
236+
237+
## Common Tasks
238+
239+
### Adding a New Sensor Decoder
240+
1. Add sensor type constant in `WeatherSensor.h` (e.g., `#define SENSOR_TYPE_NEW 0xNN`)
241+
2. Add decoder function in `WeatherSensorDecoders.cpp`:
242+
```cpp
243+
DecodeStatus decodeBresserNewPayload(const uint8_t *msg, uint8_t msgSize) {
244+
// Validate length and CRC
245+
// Extract sensor ID and type
246+
// Decode fields with proper units
247+
// Set validity flags
248+
return DECODE_OK;
249+
}
250+
```
251+
3. Add decoder to chain in `WeatherSensor::decodeMessage()`
252+
4. Add conditional compilation guard: `#ifdef BRESSER_NEW`
253+
5. Document protocol details in comments
254+
255+
### Adding a New Board Configuration
256+
1. Add board definition to `WeatherSensorCfg.h`:
257+
```cpp
258+
#elif defined(MY_BOARD)
259+
#define PIN_RECEIVER_CS XX
260+
#define PIN_RECEIVER_IRQ XX
261+
#define PIN_RECEIVER_GPIO XX
262+
#define PIN_RECEIVER_RST XX
263+
```
264+
2. Document pin connections
265+
3. Test RF reception and decoding
266+
267+
### Adding Support for a New RF Transceiver
268+
1. Add transceiver type macro: `#define USE_NEW_RADIO`
269+
2. Add RadioLib module initialization in `WeatherSensor::begin()`
270+
3. Configure modulation parameters (FSK, frequency, bandwidth, etc.)
271+
4. Test message reception with known sensors
272+
273+
## Best Practices
274+
275+
### Memory Management
276+
- ESP8266 has limited RAM (~40KB usable) - minimize heap allocations
277+
- Use `std::vector.reserve()` if max sensor count is known
278+
- Prefer stack allocation for temporary buffers
279+
- Use unions for mutually exclusive sensor data types
280+
281+
### RF Reception
282+
- Set appropriate RX timeout based on sensor transmit intervals (typically 30-60 seconds)
283+
- Handle incomplete 6-in-1 messages (alternating temp/humidity and rain/wind)
284+
- Clear slots before each RX cycle to prevent stale data
285+
- Check `startup` flag to prevent false rain/lightning accumulation
286+
287+
### Sensor ID Filtering
288+
- Support both include and exclude lists
289+
- Use `rxFlags.DATA_COMPLETE` cautiously - some sensors never provide complete data
290+
291+
### Debugging
292+
- Use `CORE_DEBUG_LEVEL` (ESP32) or `WeatherSensorCfg.h` defines (ESP8266)
293+
- Add debug output with `log_d()`, `log_i()`, `log_v()` macros
294+
- Use `DEBUG_OUTPUT.md` for debug level documentation
295+
296+
### Version Management
297+
- Follow semantic versioning (MAJOR.MINOR.PATCH)
298+
- Update `library.properties` version field
299+
- Update `package.json` version field
300+
- Document changes in file history blocks
301+
- Update `CHANGELOG.md` (if present)
302+
303+
## Examples Organization
304+
305+
Examples demonstrate progressive complexity:
306+
1. **Basic** - Simple message reception and printing
307+
2. **Waiting/Callback** - Advanced reception strategies
308+
3. **Options** - Configuration customization
309+
4. **OLED** - Display integration
310+
5. **MQTT** - IoT platform integration
311+
6. **MQTTCustom** - Advanced MQTT with local library copy (for development)
312+
7. **Domoticz/M5Core2/CanvasGauges/SDCard** - Specific use cases
313+
314+
## Integration Guidelines
315+
316+
### MQTT Integration
317+
- Publish sensor data as JSON to topic: `<base_topic>/data`
318+
- Support MQTT auto-discovery (Home Assistant format)
319+
- Include sensor ID, type, and all available measurements
320+
- Handle TLS/SSL for secure connections
321+
322+
### Home Assistant Integration
323+
- Use MQTT auto-discovery protocol
324+
- Publish discovery configs to: `homeassistant/<component>/<object_id>/config`
325+
- Set appropriate device classes (temperature, humidity, etc.)
326+
- Include unique IDs based on sensor ID
327+
328+
## Security Considerations
329+
- Never commit WiFi credentials or MQTT passwords
330+
- Use `secrets.h` (gitignored) for sensitive data
331+
- Define `SECRETS` macro when using separate secrets file
332+
- Support secure WiFi (WPA2) and secure MQTT (TLS/SSL)
333+
334+
## References & Credits
335+
336+
### Original Work
337+
- **Bresser5in1-CC1101** by Sean Siford - Initial CC1101 implementation
338+
- **RadioLib** by Jan Gromeš - RF transceiver library
339+
- **rtl_433** by Benjamin Larsson - Protocol specifications and decoders
340+
341+
### Protocol Documentation
342+
- [rtl_433 bresser_5in1.c](https://github.com/merbanan/rtl_433/blob/master/src/devices/bresser_5in1.c)
343+
- [rtl_433 bresser_6in1.c](https://github.com/merbanan/rtl_433/blob/master/src/devices/bresser_6in1.c)
344+
- [rtl_433 bresser_7in1.c](https://github.com/merbanan/rtl_433/blob/master/src/devices/bresser_7in1.c)
345+
346+
### Project Resources
347+
- **Repository**: https://github.com/matthias-bs/BresserWeatherSensorReceiver
348+
- **Wiki**: https://github.com/matthias-bs/BresserWeatherSensorReceiver/wiki
349+
- **Issues**: https://github.com/matthias-bs/BresserWeatherSensorReceiver/issues
350+
- **Discussions**: Use GitHub Issues for questions and feature requests
351+
352+
## License
353+
This project is licensed under the MIT License. All contributions must maintain the MIT license header in source files.

0 commit comments

Comments
 (0)