chore: remove internal dev documents from public repo
PROJECT_CONTEXT.md, PROJECT_STRUCTURE.md, PUBLISH_TO_GITHUB.md were working notes not intended for contributors. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
8d404506c4
commit
98b40ff0cf
@@ -1,800 +0,0 @@
|
|||||||
# ESP8266 Weather Clock - Full Project Context
|
|
||||||
|
|
||||||
**Last Updated**: 2026-01-03
|
|
||||||
**Current Version**: v1.9.1 (Production Ready)
|
|
||||||
**GitHub**: https://github.com/petrochen/esp8266-weather-clock-opensource
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Table of Contents
|
|
||||||
|
|
||||||
1. [Project Overview](#project-overview)
|
|
||||||
2. [Hardware Details](#hardware-details)
|
|
||||||
3. [Development History](#development-history)
|
|
||||||
4. [Current Status (v1.9.1)](#current-status-v191)
|
|
||||||
5. [Technical Architecture](#technical-architecture)
|
|
||||||
6. [Security Issues Fixed](#security-issues-fixed)
|
|
||||||
7. [Files & Structure](#files--structure)
|
|
||||||
8. [Git Repository](#git-repository)
|
|
||||||
9. [Next Steps](#next-steps)
|
|
||||||
10. [Key Learnings](#key-learnings)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Project Overview
|
|
||||||
|
|
||||||
### What Is This?
|
|
||||||
|
|
||||||
Complete reverse engineering and firmware replacement for an ESP8266-based weather clock purchased from AliExpress (model TJ-56-654, €5).
|
|
||||||
|
|
||||||
### Why?
|
|
||||||
|
|
||||||
**Original firmware had critical security vulnerabilities:**
|
|
||||||
- WiFi password displayed in plaintext
|
|
||||||
- Persistent open access point running in parallel to home WiFi
|
|
||||||
- Dependency on Chinese cloud service (QWeather) requiring API key registration
|
|
||||||
- No OTA updates (required physical FTDI access for updates)
|
|
||||||
|
|
||||||
**Solution:** Complete custom firmware with security, performance, and features.
|
|
||||||
|
|
||||||
### Key Features
|
|
||||||
|
|
||||||
- ✅ **Security**: No password leaks, WiFiManager captive portal, no hardcoded credentials
|
|
||||||
- ✅ **Performance**: Fully async architecture, <1ms loop time (was 10ms+)
|
|
||||||
- ✅ **Weather**: Open-Meteo API (free, no registration, no API key)
|
|
||||||
- ✅ **Updates**: OTA via web interface + ArduinoOTA
|
|
||||||
- ✅ **Interface**: Web UI, REST API, full configuration
|
|
||||||
- ✅ **Display**: 3 rotating modes (time, weather, sunrise/sunset with daylight duration)
|
|
||||||
- ✅ **Time**: NTP sync with timezone + automatic European DST
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Hardware Details
|
|
||||||
|
|
||||||
### Device Purchased
|
|
||||||
|
|
||||||
- **Product**: ESP8266 Mini Weather Clock Kit
|
|
||||||
- **Model**: TJ-56-654
|
|
||||||
- **Source**: [AliExpress Link](https://pt.aliexpress.com/item/1005008333782531.html)
|
|
||||||
- **Price**: €5 EUR (~$5.50 USD)
|
|
||||||
- **Size**: 40mm x 40mm x 43mm (transparent acrylic case)
|
|
||||||
|
|
||||||
### Components
|
|
||||||
|
|
||||||
#### ESP-01S WiFi Module
|
|
||||||
- **Chip**: ESP8266EX
|
|
||||||
- **Flash**: 1MB (8Mbit)
|
|
||||||
- **RAM**: 80KB total
|
|
||||||
- **CPU**: 80MHz
|
|
||||||
- **WiFi**: 802.11 b/g/n (2.4GHz only)
|
|
||||||
- **GPIO**: Only GPIO0 and GPIO2 available
|
|
||||||
- **Voltage**: 3.3V ⚠️ NOT 5V tolerant
|
|
||||||
|
|
||||||
#### Display Module
|
|
||||||
- **Model**: GM009605v4.3
|
|
||||||
- **Type**: OLED (128x64 pixels, 0.96 inches)
|
|
||||||
- **Controller**: SSD1306/SH1106 compatible
|
|
||||||
- **Interface**: I2C
|
|
||||||
- **I2C Address**: 0x3C (default), 0x3D (fallback)
|
|
||||||
- **Colors**: Monochrome (white on black)
|
|
||||||
|
|
||||||
#### Pin Mapping (CRITICAL!)
|
|
||||||
|
|
||||||
**Non-standard I2C mapping:**
|
|
||||||
- SDA: GPIO0 (not GPIO4 as typical)
|
|
||||||
- SCL: GPIO2 (not GPIO5 as typical)
|
|
||||||
|
|
||||||
This mapping is **backwards** from standard ESP8266 breakout boards!
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
Wire.begin(0, 2); // SDA=GPIO0, SCL=GPIO2
|
|
||||||
```
|
|
||||||
|
|
||||||
### Power Supply
|
|
||||||
- Input: 5V via Micro-USB
|
|
||||||
- Current: 80-120mA typical
|
|
||||||
- Regulator: Onboard 3.3V LDO
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Development History
|
|
||||||
|
|
||||||
### Timeline
|
|
||||||
|
|
||||||
**2025-12-29**: v1.5 (unreleased)
|
|
||||||
- Attempted TM1637 7-segment display support
|
|
||||||
- ❌ Wrong - device has OLED, not 7-segment LEDs
|
|
||||||
|
|
||||||
**2025-12-30**: v1.6 (unreleased)
|
|
||||||
- Attempted TM1650 LED driver support
|
|
||||||
- ❌ Wrong - I2C addresses didn't match
|
|
||||||
|
|
||||||
**2025-12-31**: v1.7 ✅
|
|
||||||
- ✅ Identified correct display: GM009605v4.3 (SSD1306-compatible OLED)
|
|
||||||
- ✅ Discovered swapped pins: SDA=GPIO0, SCL=GPIO2
|
|
||||||
- ✅ Switched to Adafruit_SSD1306 library
|
|
||||||
- ✅ Basic time display working
|
|
||||||
- ✅ WiFiManager integration
|
|
||||||
- ✅ First OTA deployment
|
|
||||||
|
|
||||||
**2026-01-01**: v1.8 🔒
|
|
||||||
- 🔒 **Security fixes**:
|
|
||||||
- Removed hardcoded WiFi credentials
|
|
||||||
- Added config validation (magic number check)
|
|
||||||
- Input sanitization (buffer overflow protection)
|
|
||||||
- 🛠️ **Stability fixes**:
|
|
||||||
- IRAM crisis fix (94% → 70% via ICACHE_FLASH_ATTR on 26 functions)
|
|
||||||
- NTP interval bug (config value was ignored)
|
|
||||||
- Boolean parsing errors in JSON import/export
|
|
||||||
- Infinite loop protection in display rotation
|
|
||||||
- ⚡ **Performance**:
|
|
||||||
- Chunked HTTP responses (eliminated 140+ String concatenations)
|
|
||||||
- Peak heap usage reduced by ~8KB
|
|
||||||
- Memory leaks fixed
|
|
||||||
|
|
||||||
**2026-01-02**: v1.9.0 ⚡
|
|
||||||
- ⚡ **Full async refactoring**:
|
|
||||||
- Async HTTP weather fetch (AsyncHTTPRequest library)
|
|
||||||
- Custom async NTP implementation (manual UDP packets)
|
|
||||||
- Async WiFi connection (state machine)
|
|
||||||
- Removed all delay() calls from loop()
|
|
||||||
- Exponential backoff retry logic
|
|
||||||
- 📊 **Performance results**:
|
|
||||||
- Loop time: 10ms → <1ms (10x improvement)
|
|
||||||
- Weather fetch: 1-10s blocking → 0ms
|
|
||||||
- NTP sync: 5-20s blocking → 0ms
|
|
||||||
- WiFi reconnect: 15s blocking → 0ms
|
|
||||||
- ❌ **Problem discovered**:
|
|
||||||
- Display blank for 10+ seconds on boot
|
|
||||||
- "DNS resolution failed" errors
|
|
||||||
|
|
||||||
**2026-01-03**: v1.9.1 (Current) 🎯
|
|
||||||
- 🔧 **Critical fix**: Hybrid WiFi model
|
|
||||||
- Synchronous WiFi in setup() (waits up to 10 seconds)
|
|
||||||
- Async WiFi reconnect in loop() (non-blocking)
|
|
||||||
- Ensures proper initialization order: WiFi → OTA → web → NTP
|
|
||||||
- 📺 **Display improvements**:
|
|
||||||
- Fixed sunrise/sunset labels cutoff (removed labels, kept arrows)
|
|
||||||
- Superscript degree symbol (°c)
|
|
||||||
- Daylight duration display instead of static "Sun Times"
|
|
||||||
- ✅ **Result**: Production ready, tested 24/7
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Current Status (v1.9.1)
|
|
||||||
|
|
||||||
### Version Information
|
|
||||||
|
|
||||||
**Firmware**: v1.9.1 (Production Ready)
|
|
||||||
**Released**: 2026-01-03
|
|
||||||
**Status**: Actively running 24/7, stable
|
|
||||||
|
|
||||||
### Memory Usage
|
|
||||||
|
|
||||||
| Resource | Used | Total | Usage | Status |
|
|
||||||
|----------|------|-------|-------|--------|
|
|
||||||
| Flash | 408,844 | 1,048,576 | 38% | ✅ Plenty |
|
|
||||||
| RAM | 37,644 | 80,192 | 46% | ✅ Safe |
|
|
||||||
| IRAM | 61,987 | 65,536 | 94% | ⚠️ Critical but stable |
|
|
||||||
|
|
||||||
**IRAM Note**: 94% is acceptable because:
|
|
||||||
- ICACHE_FLASH_ATTR applied to 26 functions
|
|
||||||
- Stable across v1.8 → v1.9.1
|
|
||||||
- No growth observed in testing
|
|
||||||
|
|
||||||
### Performance Metrics
|
|
||||||
|
|
||||||
- **Loop time**: <1ms (was 10ms+ before async)
|
|
||||||
- **Boot to time display**: ~15 seconds
|
|
||||||
- **WiFi connection**: 5-10 seconds (synchronous in setup)
|
|
||||||
- **NTP sync interval**: Configurable (default 1 hour)
|
|
||||||
- **Weather update interval**: Configurable (default 30 minutes)
|
|
||||||
|
|
||||||
### Uptime
|
|
||||||
|
|
||||||
- ✅ 24+ hours stable
|
|
||||||
- ✅ No memory leaks
|
|
||||||
- ✅ No crashes or reboots
|
|
||||||
- ✅ OTA updates work during operation
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Technical Architecture
|
|
||||||
|
|
||||||
### Async State Machines
|
|
||||||
|
|
||||||
#### Weather State Machine
|
|
||||||
```cpp
|
|
||||||
enum WeatherState { IDLE, REQUESTING, SUCCESS, FAILED };
|
|
||||||
```
|
|
||||||
|
|
||||||
- Library: AsyncHTTPRequest_Generic v1.13.0
|
|
||||||
- API: Open-Meteo (free, no API key)
|
|
||||||
- Callback: `onWeatherResponse()`
|
|
||||||
- Retry: Exponential backoff (1s → 2s → 4s, max 3 retries)
|
|
||||||
|
|
||||||
#### NTP State Machine
|
|
||||||
```cpp
|
|
||||||
enum NTPState { IDLE, REQUEST_SENT, WAITING, SUCCESS, FAILED };
|
|
||||||
```
|
|
||||||
|
|
||||||
- Custom manual UDP packet building/parsing
|
|
||||||
- Independent epoch tracking: `syncedEpoch`, `syncedMillis`, `timeIsSynced`
|
|
||||||
- Non-blocking UDP checks via `parsePacket()`
|
|
||||||
- Timeout: 5 seconds
|
|
||||||
- Why manual? NTPClient library is inherently blocking
|
|
||||||
|
|
||||||
#### WiFi State Machine
|
|
||||||
```cpp
|
|
||||||
enum WiFiConnectionState { IDLE, CONNECTING, CONNECTED, FAILED };
|
|
||||||
```
|
|
||||||
|
|
||||||
**Hybrid model** (critical for v1.9.1):
|
|
||||||
- **Setup phase**: Synchronous (waits up to 10 seconds)
|
|
||||||
- Why? OTA, web server, NTP all need WiFi ready
|
|
||||||
- Prevents "DNS resolution failed" errors
|
|
||||||
- Ensures time appears on display immediately after WiFi connects
|
|
||||||
- **Loop phase**: Asynchronous (checks every 5 seconds)
|
|
||||||
- Why? Don't freeze device if WiFi drops during operation
|
|
||||||
- Graceful reconnection without user impact
|
|
||||||
|
|
||||||
### Configuration Storage
|
|
||||||
|
|
||||||
**EEPROM struct (512 bytes, 26 fields):**
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
struct Config {
|
|
||||||
char ssid[32]; // WiFi network name
|
|
||||||
char password[64]; // WiFi password
|
|
||||||
int timezone_offset; // Seconds from UTC
|
|
||||||
bool dst_enabled; // Auto DST (European rules)
|
|
||||||
uint8_t brightness; // Display brightness (0-7)
|
|
||||||
char ntp_server[64]; // NTP server address
|
|
||||||
unsigned long ntp_interval; // NTP sync interval (seconds)
|
|
||||||
bool hour_format_24; // 24h vs 12h display
|
|
||||||
char hostname[32]; // mDNS hostname
|
|
||||||
float latitude; // Weather location
|
|
||||||
float longitude; // Weather location
|
|
||||||
char city_name[32]; // Display in weather mode
|
|
||||||
bool weather_enabled; // Feature toggle
|
|
||||||
unsigned long weather_interval; // Update interval (seconds)
|
|
||||||
unsigned long display_rotation_sec; // Mode switch interval
|
|
||||||
bool show_weather; // Enable weather mode
|
|
||||||
bool show_sunrise_sunset; // Enable sunrise/sunset mode
|
|
||||||
uint8_t display_orientation; // Screen rotation (0-3)
|
|
||||||
uint32_t magic; // 0xC10CC10C - validation
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
**Validation**: Magic number check prevents loading corrupted EEPROM data.
|
|
||||||
|
|
||||||
### Display Modes
|
|
||||||
|
|
||||||
**Mode 1: Time Mode**
|
|
||||||
- Large HH:MM display
|
|
||||||
- Blinking colon (500ms interval)
|
|
||||||
- Day of week + date
|
|
||||||
- 24/12 hour format support
|
|
||||||
|
|
||||||
**Mode 2: Weather Mode**
|
|
||||||
- Temperature with superscript °c
|
|
||||||
- City name at bottom
|
|
||||||
- Example: "15.4°c" + "Portimao"
|
|
||||||
|
|
||||||
**Mode 3: Sunrise/Sunset Mode**
|
|
||||||
- Sunrise time with ↑ arrow
|
|
||||||
- Sunset time with ↓ arrow
|
|
||||||
- Daylight duration (e.g., "Day 9h 41m")
|
|
||||||
- Calculation: sunset - sunrise = total daylight minutes
|
|
||||||
|
|
||||||
**Rotation**: Configurable interval (default 5 seconds), gracefully skips disabled modes.
|
|
||||||
|
|
||||||
### Memory Optimization Techniques
|
|
||||||
|
|
||||||
**1. ICACHE_FLASH_ATTR**
|
|
||||||
|
|
||||||
Applied to 26 functions to move code from IRAM to Flash:
|
|
||||||
- All web handlers (15 functions)
|
|
||||||
- Setup functions (5 functions)
|
|
||||||
- Utilities (6 functions)
|
|
||||||
|
|
||||||
Result: IRAM usage manageable at 94%
|
|
||||||
|
|
||||||
**2. Chunked HTTP Responses**
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
// ❌ BAD - 140+ concatenations
|
|
||||||
String html = "";
|
|
||||||
html += F("<!DOCTYPE html>");
|
|
||||||
html += F("<head>...");
|
|
||||||
|
|
||||||
// ✅ GOOD - Chunked transfer
|
|
||||||
server.setContentLength(CONTENT_LENGTH_UNKNOWN);
|
|
||||||
server.send(200, "text/html", "");
|
|
||||||
server.sendContent_P(HTML_HEADER);
|
|
||||||
server.sendContent_P(HTML_FOOTER);
|
|
||||||
server.sendContent("");
|
|
||||||
```
|
|
||||||
|
|
||||||
Result: ~8KB peak heap reduction
|
|
||||||
|
|
||||||
**3. Fixed-Size Buffers**
|
|
||||||
|
|
||||||
No dynamic String allocations in loops:
|
|
||||||
```cpp
|
|
||||||
char buf[150];
|
|
||||||
snprintf_P(buf, sizeof(buf), PSTR("<div>IP: %s</div>"),
|
|
||||||
WiFi.localIP().toString().c_str());
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Security Issues Fixed
|
|
||||||
|
|
||||||
### Original Firmware Vulnerabilities
|
|
||||||
|
|
||||||
**1. WiFi Password Leak (CRITICAL)**
|
|
||||||
- Open access point remained active after setup
|
|
||||||
- Web interface displayed WiFi password in plaintext
|
|
||||||
- Anyone within range could connect and read password
|
|
||||||
- **Impact**: Full network compromise
|
|
||||||
|
|
||||||
**2. Cloud Dependency**
|
|
||||||
- Required QWeather API (Chinese service)
|
|
||||||
- Needed account registration + API key
|
|
||||||
- Unknown data collection practices
|
|
||||||
- **Impact**: Privacy concerns, vendor lock-in
|
|
||||||
|
|
||||||
**3. No OTA Updates**
|
|
||||||
- Required physical FTDI connection for updates
|
|
||||||
- Difficult for non-technical users
|
|
||||||
- **Impact**: Security vulnerabilities can't be patched remotely
|
|
||||||
|
|
||||||
**4. Hardcoded Credentials**
|
|
||||||
- Default WiFi credentials in source code
|
|
||||||
- No secure setup flow
|
|
||||||
- **Impact**: Easy attack vector
|
|
||||||
|
|
||||||
### Custom Firmware Solutions
|
|
||||||
|
|
||||||
**1. WiFiManager Integration ✅**
|
|
||||||
- Captive portal for secure first-time setup
|
|
||||||
- AP automatically closes after 180 seconds
|
|
||||||
- Fallback AP only on connection failure
|
|
||||||
- Password-protected fallback (customizable)
|
|
||||||
|
|
||||||
**2. Open-Meteo API ✅**
|
|
||||||
- Free weather service
|
|
||||||
- No registration required
|
|
||||||
- No API key needed
|
|
||||||
- European service (GDPR compliant)
|
|
||||||
|
|
||||||
**3. OTA Updates ✅**
|
|
||||||
- Web-based upload at `/update`
|
|
||||||
- ArduinoOTA for IDE uploads
|
|
||||||
- Password-protected (admin/admin - customizable)
|
|
||||||
- Non-blocking during operation
|
|
||||||
|
|
||||||
**4. No Hardcoded Secrets ✅**
|
|
||||||
- All credentials stored in EEPROM
|
|
||||||
- Magic number validation
|
|
||||||
- Factory reset capability
|
|
||||||
- Configuration import/export
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Files & Structure
|
|
||||||
|
|
||||||
### Project Directory
|
|
||||||
|
|
||||||
**Location**: `/Users/apetrochenko/Library/Mobile Documents/com~apple~CloudDocs/src/arduino/clock/esp8266-weather-clock-opensource`
|
|
||||||
|
|
||||||
### Key Files
|
|
||||||
|
|
||||||
**Root Level:**
|
|
||||||
- `README.md` (26KB) - Main documentation (blog-style)
|
|
||||||
- `LICENSE` - MIT License
|
|
||||||
- `CHANGELOG.md` - Version history
|
|
||||||
- `CONTRIBUTING.md` - Contribution guidelines
|
|
||||||
- `PROJECT_STRUCTURE.md` - Directory layout
|
|
||||||
- `PROJECT_CONTEXT.md` - This file
|
|
||||||
- `PUBLISH_TO_GITHUB.md` - GitHub publishing guide
|
|
||||||
- `.gitignore` - Git exclusions
|
|
||||||
|
|
||||||
**Source Code:**
|
|
||||||
- `src/clock_ntp_ota_v1.9.ino` (65KB, 2,096 lines)
|
|
||||||
|
|
||||||
**Documentation:**
|
|
||||||
- `docs/INSTALLATION.md` (18KB) - Complete installation guide
|
|
||||||
- `docs/HARDWARE.md` (8KB) - Hardware specs + pinout
|
|
||||||
- `docs/v1.9_RELEASE_NOTES.md` (7KB) - v1.9.0 changelog
|
|
||||||
- `docs/v1.9.1_HYBRID_FIX.md` (6KB, Russian) - v1.9.1 fix explanation
|
|
||||||
|
|
||||||
**Images:**
|
|
||||||
- `images/product/` - 6 AliExpress product photos
|
|
||||||
- 01-main-product.webp
|
|
||||||
- 02-components.webp
|
|
||||||
- 03-weather-forecast.webp
|
|
||||||
- 04-temperature-display.webp
|
|
||||||
- 05-details.webp
|
|
||||||
- 06-size.webp
|
|
||||||
- `images/build/` - 3 display screenshots
|
|
||||||
- display-time.png
|
|
||||||
- display-temperature.png
|
|
||||||
- display-sunrise-sunset.png
|
|
||||||
|
|
||||||
**GitHub Config:**
|
|
||||||
- `.github/workflows/build.yml` - CI/CD pipeline
|
|
||||||
- `.github/ISSUE_TEMPLATE/bug_report.md`
|
|
||||||
- `.github/ISSUE_TEMPLATE/feature_request.md`
|
|
||||||
|
|
||||||
### Compiled Artifacts (not in git)
|
|
||||||
|
|
||||||
```
|
|
||||||
build/
|
|
||||||
├── clock_ntp_ota_v1.9.ino.bin (409KB) - Flash this via OTA
|
|
||||||
├── clock_ntp_ota_v1.9.ino.elf - Debug symbols
|
|
||||||
└── clock_ntp_ota_v1.9.ino.map - Memory map
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Git Repository
|
|
||||||
|
|
||||||
### GitHub Details
|
|
||||||
|
|
||||||
- **Repository**: https://github.com/petrochen/esp8266-weather-clock-opensource
|
|
||||||
- **Owner**: petrochen (Andrey Petrochenko)
|
|
||||||
- **Visibility**: Public
|
|
||||||
- **License**: MIT
|
|
||||||
- **Created**: 2026-01-03
|
|
||||||
|
|
||||||
### Repository Configuration
|
|
||||||
|
|
||||||
**Enabled Features:**
|
|
||||||
- ✅ Issues
|
|
||||||
- ✅ Discussions
|
|
||||||
- ✅ GitHub Actions (CI/CD)
|
|
||||||
- ✅ Releases
|
|
||||||
|
|
||||||
**Topics (Tags):**
|
|
||||||
- `esp8266`, `arduino`, `iot`, `weather-station`
|
|
||||||
- `reverse-engineering`, `security`, `oled-display`
|
|
||||||
- `ntp`, `ota-updates`, `open-meteo`
|
|
||||||
|
|
||||||
**Badges:**
|
|
||||||
- Release version (auto-updates)
|
|
||||||
- License (MIT)
|
|
||||||
- Build status (CI/CD)
|
|
||||||
- Open issues count
|
|
||||||
- Hardware (ESP-01S)
|
|
||||||
- Status (Production Ready)
|
|
||||||
|
|
||||||
### Current Release
|
|
||||||
|
|
||||||
**Tag**: v1.9.1
|
|
||||||
**URL**: https://github.com/petrochen/esp8266-weather-clock-opensource/releases/tag/v1.9.1
|
|
||||||
**Status**: Production Ready
|
|
||||||
**Created**: 2026-01-03
|
|
||||||
|
|
||||||
### Git Commits
|
|
||||||
|
|
||||||
**Total**: 3 commits
|
|
||||||
1. `8f0df02` - Initial commit: v1.9.1 production firmware
|
|
||||||
2. `f2dc2fb` - Add dynamic GitHub badges to README
|
|
||||||
3. `2205445` - Update price: $12 → €5
|
|
||||||
|
|
||||||
### Web Interface URLs
|
|
||||||
|
|
||||||
- **Main**: https://github.com/petrochen/esp8266-weather-clock-opensource
|
|
||||||
- **Issues**: https://github.com/petrochen/esp8266-weather-clock-opensource/issues
|
|
||||||
- **Discussions**: https://github.com/petrochen/esp8266-weather-clock-opensource/discussions
|
|
||||||
- **Actions**: https://github.com/petrochen/esp8266-weather-clock-opensource/actions
|
|
||||||
- **Releases**: https://github.com/petrochen/esp8266-weather-clock-opensource/releases
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Next Steps
|
|
||||||
|
|
||||||
### Planned Features (v1.10 or v2.0)
|
|
||||||
|
|
||||||
**1. Home Assistant Integration (High Priority)**
|
|
||||||
|
|
||||||
User specifically wants custom display screens pulling data from Home Assistant.
|
|
||||||
|
|
||||||
**Implementation ideas:**
|
|
||||||
- Add REST API client to fetch HA sensor data
|
|
||||||
- New display modes:
|
|
||||||
- Energy usage dashboard
|
|
||||||
- Room temperatures (multiple sensors)
|
|
||||||
- Air quality / CO2 levels
|
|
||||||
- Automation states (alarm, doors, lights)
|
|
||||||
- Configuration: HA server URL, access token, entity IDs
|
|
||||||
- Update interval: configurable (default 30 seconds)
|
|
||||||
|
|
||||||
**Technical approach:**
|
|
||||||
- Use AsyncHTTPRequest for non-blocking HA API calls
|
|
||||||
- JSON parsing with ArduinoJson library
|
|
||||||
- Store HA config in EEPROM (new fields)
|
|
||||||
- New web UI section for HA configuration
|
|
||||||
|
|
||||||
**2. MQTT Support**
|
|
||||||
|
|
||||||
- Publish time/weather data to MQTT broker
|
|
||||||
- Subscribe to topics for display content
|
|
||||||
- Enable automation triggers
|
|
||||||
- Library: PubSubClient (async wrapper needed)
|
|
||||||
|
|
||||||
**3. WebSocket Live Updates**
|
|
||||||
|
|
||||||
- Replace polling with WebSocket
|
|
||||||
- Real-time config changes
|
|
||||||
- Live display preview in web UI
|
|
||||||
- Push notifications for updates
|
|
||||||
|
|
||||||
**4. Multiple Weather Locations**
|
|
||||||
|
|
||||||
- Store 2-3 favorite locations
|
|
||||||
- Rotate between them
|
|
||||||
- Useful for travelers or multiple homes
|
|
||||||
|
|
||||||
**5. Display Animations**
|
|
||||||
|
|
||||||
- Smooth transitions between modes
|
|
||||||
- Weather icons (sunny, cloudy, rainy)
|
|
||||||
- Sunrise/sunset animations
|
|
||||||
|
|
||||||
### Code Quality Improvements
|
|
||||||
|
|
||||||
**1. Modular Architecture (v2.0)**
|
|
||||||
|
|
||||||
Split monolith (2,096 lines) into modules:
|
|
||||||
```
|
|
||||||
src/
|
|
||||||
├── main.ino
|
|
||||||
├── config.h
|
|
||||||
├── display.cpp/h
|
|
||||||
├── network.cpp/h
|
|
||||||
├── weather.cpp/h
|
|
||||||
├── webserver.cpp/h
|
|
||||||
└── home_assistant.cpp/h (new)
|
|
||||||
```
|
|
||||||
|
|
||||||
**2. ArduinoJson Integration**
|
|
||||||
|
|
||||||
Replace manual JSON parsing (173 lines) with library:
|
|
||||||
- Cleaner code
|
|
||||||
- Better error handling
|
|
||||||
- Type safety
|
|
||||||
|
|
||||||
**3. Constants Organization**
|
|
||||||
|
|
||||||
Eliminate magic numbers:
|
|
||||||
```cpp
|
|
||||||
namespace Hardware {
|
|
||||||
constexpr uint8_t I2C_SDA_PIN = 0;
|
|
||||||
constexpr uint8_t I2C_SCL_PIN = 2;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**4. Unit Tests**
|
|
||||||
|
|
||||||
- Test state machines
|
|
||||||
- Test JSON parsing
|
|
||||||
- Test time calculations
|
|
||||||
- Mock network calls
|
|
||||||
|
|
||||||
### Documentation Improvements
|
|
||||||
|
|
||||||
**1. Video Tutorial**
|
|
||||||
|
|
||||||
- YouTube walkthrough
|
|
||||||
- FTDI connection demo
|
|
||||||
- OTA update demo
|
|
||||||
- Web configuration walkthrough
|
|
||||||
|
|
||||||
**2. Troubleshooting Flow Chart**
|
|
||||||
|
|
||||||
Visual guide for common issues:
|
|
||||||
- Display not working
|
|
||||||
- WiFi not connecting
|
|
||||||
- Time not syncing
|
|
||||||
- Weather not updating
|
|
||||||
|
|
||||||
**3. Localization**
|
|
||||||
|
|
||||||
Translate docs to:
|
|
||||||
- Russian (v1.9.1_HYBRID_FIX.md already in Russian)
|
|
||||||
- Spanish
|
|
||||||
- Portuguese
|
|
||||||
|
|
||||||
**4. Home Assistant Integration Guide**
|
|
||||||
|
|
||||||
Complete guide when HA support is added.
|
|
||||||
|
|
||||||
### Community Engagement
|
|
||||||
|
|
||||||
**1. Reddit Posts**
|
|
||||||
|
|
||||||
Subreddits to share on:
|
|
||||||
- r/esp8266
|
|
||||||
- r/arduino
|
|
||||||
- r/selfhosted
|
|
||||||
- r/homeassistant (after HA integration)
|
|
||||||
- r/ReverseEngineering
|
|
||||||
|
|
||||||
**2. Hackaday**
|
|
||||||
|
|
||||||
Submit project tip: https://hackaday.com/submit-a-tip/
|
|
||||||
|
|
||||||
**3. Hackster.io**
|
|
||||||
|
|
||||||
Create full project page with build guide.
|
|
||||||
|
|
||||||
**4. Awesome Lists**
|
|
||||||
|
|
||||||
Add to "awesome ESP8266" and "awesome IoT" lists.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Key Learnings
|
|
||||||
|
|
||||||
### Hardware
|
|
||||||
|
|
||||||
1. **Always verify pinouts** - Don't assume standard mappings
|
|
||||||
2. **FTDI is essential** - $2 adapter unlocks any ESP8266 device
|
|
||||||
3. **Read PCB markings** - Model numbers save hours of guessing
|
|
||||||
4. **Test voltage** - ESP8266 is NOT 5V tolerant
|
|
||||||
5. **Document discoveries** - Pin mappings, I2C addresses, display models
|
|
||||||
|
|
||||||
### Software
|
|
||||||
|
|
||||||
1. **Async is hard but worth it** - Fully non-blocking eliminates freezes
|
|
||||||
2. **IRAM is precious** - Use ICACHE_FLASH_ATTR liberally on ESP8266
|
|
||||||
3. **Hybrid approaches work** - Don't be dogmatic (sync WiFi in setup() was correct)
|
|
||||||
4. **State machines scale** - Better than callback hell for complex async
|
|
||||||
5. **Test on real hardware** - Emulators miss pin issues and memory constraints
|
|
||||||
|
|
||||||
### Security
|
|
||||||
|
|
||||||
1. **IoT security is often terrible** - Always audit before trusting
|
|
||||||
2. **Open source is safer** - Closed firmware is a black box
|
|
||||||
3. **Defaults matter** - Insecure defaults (open AP, plaintext passwords) are vulnerabilities
|
|
||||||
4. **Defense in depth** - Multiple layers catch mistakes
|
|
||||||
5. **Update mechanism is critical** - OTA enables security patches
|
|
||||||
|
|
||||||
### Development
|
|
||||||
|
|
||||||
1. **OTA from day 1** - FTDI flashing gets old fast
|
|
||||||
2. **Version control** - Backups (.bak, .bak2) saved the project multiple times
|
|
||||||
3. **Document as you go** - Release notes prevent "what was I thinking?" moments
|
|
||||||
4. **Incremental improvements** - v1.7 → v1.8 → v1.9.x made debugging manageable
|
|
||||||
5. **User testing** - Photos from user revealed display cutoff issues
|
|
||||||
|
|
||||||
### Project Management
|
|
||||||
|
|
||||||
1. **Understand user needs** - User wanted Home Assistant integration (plan for it)
|
|
||||||
2. **Security first** - Privacy/security was main motivation
|
|
||||||
3. **Performance matters** - 10ms loop → <1ms dramatically improves UX
|
|
||||||
4. **Documentation is product** - Good docs = more users = more contributors
|
|
||||||
5. **Publish early** - GitHub repo enables community contributions
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Quick Reference
|
|
||||||
|
|
||||||
### Current Device Configuration
|
|
||||||
|
|
||||||
**Hardware:**
|
|
||||||
- Device: TJ-56-654 Weather Clock
|
|
||||||
- Location: User's home network
|
|
||||||
- IP: 192.168.2.47
|
|
||||||
- Hostname: tj56654-clock.local
|
|
||||||
|
|
||||||
**Software:**
|
|
||||||
- Firmware: v1.9.1
|
|
||||||
- WiFi: SibWings
|
|
||||||
- Weather: Portimao, Portugal (37.19°N, 8.54°W)
|
|
||||||
- Timezone: UTC+0 (Lisbon) with auto DST
|
|
||||||
- NTP: pool.ntp.org (1 hour interval)
|
|
||||||
|
|
||||||
**Access:**
|
|
||||||
- Web UI: http://192.168.2.47 or http://tj56654-clock.local
|
|
||||||
- OTA Update: http://192.168.2.47/update (admin/admin)
|
|
||||||
- API Base: http://192.168.2.47/api/
|
|
||||||
|
|
||||||
### Important Commands
|
|
||||||
|
|
||||||
**Compile:**
|
|
||||||
```bash
|
|
||||||
arduino-cli compile --fqbn esp8266:esp8266:generic \
|
|
||||||
src/clock_ntp_ota_v1.9.ino
|
|
||||||
```
|
|
||||||
|
|
||||||
**Upload OTA:**
|
|
||||||
```bash
|
|
||||||
curl -u admin:admin \
|
|
||||||
-F "file=@build/clock_ntp_ota_v1.9.ino.bin" \
|
|
||||||
http://192.168.2.47/update
|
|
||||||
```
|
|
||||||
|
|
||||||
**Check status:**
|
|
||||||
```bash
|
|
||||||
curl http://192.168.2.47/api/status | jq
|
|
||||||
```
|
|
||||||
|
|
||||||
**View logs:**
|
|
||||||
```bash
|
|
||||||
# Connect via serial (if FTDI attached)
|
|
||||||
screen /dev/cu.usbserial* 115200
|
|
||||||
```
|
|
||||||
|
|
||||||
### Library Dependencies
|
|
||||||
|
|
||||||
Required libraries (install via Arduino Library Manager):
|
|
||||||
|
|
||||||
| Library | Version | Purpose |
|
|
||||||
|---------|---------|---------|
|
|
||||||
| Adafruit GFX Library | 1.11.0+ | Graphics primitives |
|
|
||||||
| Adafruit SSD1306 | 2.5.0+ | OLED display driver |
|
|
||||||
| NTPClient | 3.2.0+ | NTP time sync (base) |
|
|
||||||
| WiFiManager | 2.0.0+ | Captive portal |
|
|
||||||
| AsyncHTTPRequest_Generic | 1.13.0+ | Async weather fetch |
|
|
||||||
| ESPAsyncTCP | 1.2.2+ | Async TCP layer |
|
|
||||||
|
|
||||||
### External APIs
|
|
||||||
|
|
||||||
**Open-Meteo:**
|
|
||||||
- URL: https://api.open-meteo.com/v1/forecast
|
|
||||||
- Authentication: None (free, no API key)
|
|
||||||
- Rate limit: None (reasonable use)
|
|
||||||
- Documentation: https://open-meteo.com/en/docs
|
|
||||||
|
|
||||||
**NTP:**
|
|
||||||
- Default: pool.ntp.org
|
|
||||||
- Protocol: UDP port 123
|
|
||||||
- Fallbacks: time.google.com, time.cloudflare.com
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Contact & Collaboration
|
|
||||||
|
|
||||||
**GitHub**: https://github.com/petrochen/esp8266-weather-clock-opensource
|
|
||||||
**Issues**: https://github.com/petrochen/esp8266-weather-clock-opensource/issues
|
|
||||||
**Discussions**: https://github.com/petrochen/esp8266-weather-clock-opensource/discussions
|
|
||||||
|
|
||||||
**Contributions welcome!** See [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Summary
|
|
||||||
|
|
||||||
This project successfully transformed a €5 AliExpress IoT device with critical security vulnerabilities into a fully secure, high-performance, feature-rich smart clock with open-source firmware.
|
|
||||||
|
|
||||||
**Key achievements:**
|
|
||||||
- ✅ Eliminated WiFi password leak vulnerability
|
|
||||||
- ✅ Achieved <1ms loop time (10x performance improvement)
|
|
||||||
- ✅ Enabled OTA updates (no more FTDI wiring)
|
|
||||||
- ✅ Free weather API (no registration)
|
|
||||||
- ✅ Full async architecture (zero blocking)
|
|
||||||
- ✅ Production-ready stability (24/7 uptime)
|
|
||||||
- ✅ Open-source on GitHub (MIT license)
|
|
||||||
- ✅ Comprehensive documentation (100KB+ docs)
|
|
||||||
|
|
||||||
**Next milestone**: Home Assistant integration for custom display screens.
|
|
||||||
|
|
||||||
**Status**: Project complete and ready for community contributions! 🚀
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Last session work (2026-01-03):**
|
|
||||||
1. ✅ Compiled v1.9.1 with daylight duration feature
|
|
||||||
2. ✅ Uploaded via OTA to device (192.168.2.47)
|
|
||||||
3. ✅ Created complete GitHub repository structure
|
|
||||||
4. ✅ Published to https://github.com/petrochen/esp8266-weather-clock-opensource
|
|
||||||
5. ✅ Created release v1.9.1
|
|
||||||
6. ✅ Added badges, topics, documentation
|
|
||||||
7. ✅ Fixed price ($12 → €5)
|
|
||||||
8. ✅ Saved full project context
|
|
||||||
|
|
||||||
**Repository ready for sharing on Reddit, Hackaday, and other communities!**
|
|
||||||
@@ -1,249 +0,0 @@
|
|||||||
# Project Structure
|
|
||||||
|
|
||||||
This document describes the organization of the ESP8266 Weather Clock firmware repository.
|
|
||||||
|
|
||||||
## Directory Layout
|
|
||||||
|
|
||||||
```
|
|
||||||
esp8266-weather-clock-opensource/
|
|
||||||
│
|
|
||||||
├── README.md # Main documentation (start here!)
|
|
||||||
├── LICENSE # MIT License
|
|
||||||
├── CHANGELOG.md # Version history
|
|
||||||
├── CONTRIBUTING.md # Contribution guidelines
|
|
||||||
├── PROJECT_STRUCTURE.md # This file
|
|
||||||
├── .gitignore # Git exclusions
|
|
||||||
│
|
|
||||||
├── src/ # Source code
|
|
||||||
│ └── clock_ntp_ota_v1.9.ino # Main firmware (2,096 lines)
|
|
||||||
│
|
|
||||||
├── docs/ # Documentation
|
|
||||||
│ ├── INSTALLATION.md # Complete installation guide
|
|
||||||
│ ├── HARDWARE.md # Hardware specs and pinout
|
|
||||||
│ ├── v1.9_RELEASE_NOTES.md # v1.9.0 release notes
|
|
||||||
│ └── v1.9.1_HYBRID_FIX.md # v1.9.1 WiFi startup fix
|
|
||||||
│
|
|
||||||
├── images/ # Photos and screenshots
|
|
||||||
│ ├── product/ # AliExpress product photos
|
|
||||||
│ │ ├── 01-main-product.webp # Main product shot
|
|
||||||
│ │ ├── 02-components.webp # Kit components
|
|
||||||
│ │ ├── 03-weather-forecast.webp
|
|
||||||
│ │ ├── 04-temperature-display.webp
|
|
||||||
│ │ ├── 05-details.webp # Transparent case details
|
|
||||||
│ │ └── 06-size.webp # Dimensions (40x40x43mm)
|
|
||||||
│ │
|
|
||||||
│ └── build/ # Custom firmware screenshots
|
|
||||||
│ ├── display-time.png # Time display mode
|
|
||||||
│ ├── display-temperature.png # Weather display mode
|
|
||||||
│ └── display-sunrise-sunset.png # Solar display mode
|
|
||||||
│
|
|
||||||
└── .github/ # GitHub-specific files
|
|
||||||
├── workflows/
|
|
||||||
│ └── build.yml # CI: Auto-build on push
|
|
||||||
│
|
|
||||||
└── ISSUE_TEMPLATE/
|
|
||||||
├── bug_report.md # Bug report template
|
|
||||||
└── feature_request.md # Feature request template
|
|
||||||
```
|
|
||||||
|
|
||||||
## Key Files
|
|
||||||
|
|
||||||
### Root Level
|
|
||||||
|
|
||||||
**README.md** (11KB)
|
|
||||||
- Main project documentation
|
|
||||||
- Blog-style narrative about reverse engineering
|
|
||||||
- Security issues discovered
|
|
||||||
- Complete feature list
|
|
||||||
- Installation quickstart
|
|
||||||
- API documentation
|
|
||||||
|
|
||||||
**LICENSE** (MIT)
|
|
||||||
- Permissive open source license
|
|
||||||
- Use freely, modify, distribute
|
|
||||||
|
|
||||||
**CHANGELOG.md**
|
|
||||||
- Version history: v1.5 → v1.9.1
|
|
||||||
- Features, fixes, breaking changes
|
|
||||||
- Migration notes
|
|
||||||
|
|
||||||
**CONTRIBUTING.md**
|
|
||||||
- How to contribute
|
|
||||||
- Code style guidelines
|
|
||||||
- Testing requirements
|
|
||||||
|
|
||||||
### Source Code (`/src`)
|
|
||||||
|
|
||||||
**clock_ntp_ota_v1.9.ino**
|
|
||||||
- Main firmware file (2,096 lines)
|
|
||||||
- ESP8266 Arduino sketch
|
|
||||||
- Requires libraries:
|
|
||||||
- Adafruit GFX & SSD1306
|
|
||||||
- NTPClient
|
|
||||||
- WiFiManager
|
|
||||||
- AsyncHTTPRequest_Generic
|
|
||||||
- ESPAsyncTCP
|
|
||||||
|
|
||||||
**Architecture:**
|
|
||||||
- Fully async (zero blocking in loop)
|
|
||||||
- State machines: WiFi, NTP, Weather
|
|
||||||
- Hybrid model: sync WiFi in setup(), async in loop()
|
|
||||||
- Memory-optimized: ICACHE_FLASH_ATTR on 26 functions
|
|
||||||
|
|
||||||
**Configuration:**
|
|
||||||
- 26-field struct stored in EEPROM
|
|
||||||
- Magic number validation
|
|
||||||
- Web-based config UI
|
|
||||||
|
|
||||||
### Documentation (`/docs`)
|
|
||||||
|
|
||||||
**INSTALLATION.md** (18KB)
|
|
||||||
- Complete step-by-step installation guide
|
|
||||||
- Arduino IDE setup
|
|
||||||
- FTDI wiring diagrams
|
|
||||||
- OTA update instructions
|
|
||||||
- Comprehensive troubleshooting
|
|
||||||
|
|
||||||
**HARDWARE.md** (8KB)
|
|
||||||
- ESP-01S specifications
|
|
||||||
- Pin mapping (SDA=GPIO0, SCL=GPIO2)
|
|
||||||
- Display module details (GM009605v4.3)
|
|
||||||
- Power requirements
|
|
||||||
- Memory layout
|
|
||||||
- Safety warnings
|
|
||||||
|
|
||||||
**v1.9_RELEASE_NOTES.md** (7KB)
|
|
||||||
- Detailed v1.9.0 changelog
|
|
||||||
- Performance improvements
|
|
||||||
- Async architecture explanation
|
|
||||||
- Memory usage comparison
|
|
||||||
- Testing checklist
|
|
||||||
|
|
||||||
**v1.9.1_HYBRID_FIX.md** (Russian, 6KB)
|
|
||||||
- Critical startup fix documentation
|
|
||||||
- WiFi synchronous vs async tradeoffs
|
|
||||||
- Timeline diagrams
|
|
||||||
- Before/after comparison
|
|
||||||
|
|
||||||
### Images (`/images`)
|
|
||||||
|
|
||||||
**Product Photos** (`/product`)
|
|
||||||
- Original AliExpress product images
|
|
||||||
- DIY kit components
|
|
||||||
- Transparent acrylic case
|
|
||||||
- Size reference (40mm cube)
|
|
||||||
|
|
||||||
**Build Photos** (`/build`)
|
|
||||||
- Custom firmware screenshots
|
|
||||||
- Three display modes:
|
|
||||||
1. Time mode (10:34 + date)
|
|
||||||
2. Weather mode (15.4°c + city)
|
|
||||||
3. Sunrise/sunset mode (times + daylight duration)
|
|
||||||
|
|
||||||
### GitHub Config (`/.github`)
|
|
||||||
|
|
||||||
**Workflows**
|
|
||||||
- `build.yml`: CI pipeline
|
|
||||||
- Auto-compile on push
|
|
||||||
- Check firmware size < 470KB
|
|
||||||
- Upload build artifacts
|
|
||||||
- Attach binaries to releases
|
|
||||||
|
|
||||||
**Issue Templates**
|
|
||||||
- `bug_report.md`: Structured bug reports
|
|
||||||
- `feature_request.md`: Feature suggestions
|
|
||||||
|
|
||||||
## Build Artifacts (ignored by git)
|
|
||||||
|
|
||||||
When you compile locally, these are created:
|
|
||||||
|
|
||||||
```
|
|
||||||
build/
|
|
||||||
├── clock_ntp_ota_v1.9.ino.bin # Flash this via OTA
|
|
||||||
├── clock_ntp_ota_v1.9.ino.elf # Debug symbols
|
|
||||||
└── clock_ntp_ota_v1.9.ino.map # Memory map
|
|
||||||
```
|
|
||||||
|
|
||||||
**Note**: `build/` is in `.gitignore` - artifacts not committed to repo.
|
|
||||||
|
|
||||||
## File Sizes
|
|
||||||
|
|
||||||
| File | Size | Description |
|
|
||||||
|------|------|-------------|
|
|
||||||
| `src/*.ino` | 65KB | Main source code |
|
|
||||||
| `build/*.bin` | 409KB | Compiled firmware |
|
|
||||||
| `README.md` | 45KB | Main docs |
|
|
||||||
| `docs/INSTALLATION.md` | 18KB | Install guide |
|
|
||||||
| `docs/HARDWARE.md` | 8KB | Hardware specs |
|
|
||||||
|
|
||||||
## Memory Usage
|
|
||||||
|
|
||||||
**Compiled firmware (v1.9.1):**
|
|
||||||
- Flash: 408,844 / 1,048,576 bytes (38%)
|
|
||||||
- RAM: 37,644 / 80,192 bytes (46%)
|
|
||||||
- IRAM: 61,987 / 65,536 bytes (94%) ⚠️
|
|
||||||
|
|
||||||
**Why 94% IRAM is acceptable:**
|
|
||||||
- ICACHE_FLASH_ATTR applied to all web handlers
|
|
||||||
- Stable across versions v1.8-v1.9.1
|
|
||||||
- No IRAM growth observed in testing
|
|
||||||
|
|
||||||
## Version Control
|
|
||||||
|
|
||||||
**Branches:**
|
|
||||||
- `main`: Stable releases (v1.9.1)
|
|
||||||
- `develop`: Work-in-progress features
|
|
||||||
- `feature/*`: New feature branches
|
|
||||||
|
|
||||||
**Tags:**
|
|
||||||
- `v1.9.1`: Current production release
|
|
||||||
- `v1.9.0`: Async refactoring
|
|
||||||
- `v1.8.0`: Security + stability fixes
|
|
||||||
- `v1.7.0`: Initial working firmware
|
|
||||||
|
|
||||||
## Not Included (Why)
|
|
||||||
|
|
||||||
**What's NOT in this repo:**
|
|
||||||
- Build artifacts (`.bin`, `.elf`, `.map`) - generated locally
|
|
||||||
- Backup files (`.bak`, `.bak2`) - development artifacts
|
|
||||||
- IDE configs (`.vscode/`, `.idea/`) - personal preferences
|
|
||||||
- macOS metadata (`.DS_Store`) - system files
|
|
||||||
- Secrets (`config_local.h`) - would leak credentials
|
|
||||||
|
|
||||||
These are excluded via `.gitignore`.
|
|
||||||
|
|
||||||
## How to Navigate
|
|
||||||
|
|
||||||
**For users:**
|
|
||||||
1. Start with `README.md` (overview + quickstart)
|
|
||||||
2. Follow `docs/INSTALLATION.md` (step-by-step setup)
|
|
||||||
3. Check `CHANGELOG.md` (version history)
|
|
||||||
|
|
||||||
**For developers:**
|
|
||||||
1. Read `CONTRIBUTING.md` (guidelines)
|
|
||||||
2. Study `src/clock_ntp_ota_v1.9.ino` (source code)
|
|
||||||
3. Review `docs/HARDWARE.md` (hardware constraints)
|
|
||||||
4. Check `.github/workflows/build.yml` (CI setup)
|
|
||||||
|
|
||||||
**For hardware hackers:**
|
|
||||||
1. Check `docs/HARDWARE.md` (pinout, specs)
|
|
||||||
2. View `images/product/` (original device photos)
|
|
||||||
3. Read `README.md` section "Hardware Discovery"
|
|
||||||
|
|
||||||
**For troubleshooters:**
|
|
||||||
1. Open `docs/INSTALLATION.md`
|
|
||||||
2. Jump to "Troubleshooting" section
|
|
||||||
3. Check `images/build/` for reference screenshots
|
|
||||||
|
|
||||||
## Quick Links
|
|
||||||
|
|
||||||
- **Main docs**: [README.md](README.md)
|
|
||||||
- **Install guide**: [docs/INSTALLATION.md](docs/INSTALLATION.md)
|
|
||||||
- **Hardware specs**: [docs/HARDWARE.md](docs/HARDWARE.md)
|
|
||||||
- **Changelog**: [CHANGELOG.md](CHANGELOG.md)
|
|
||||||
- **Contributing**: [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Last updated**: 2026-01-03
|
|
||||||
**Repository**: https://github.com/your-username/esp8266-weather-clock-opensource
|
|
||||||
@@ -1,440 +0,0 @@
|
|||||||
# Publishing to GitHub - Step by Step Guide
|
|
||||||
|
|
||||||
This file contains instructions for publishing this project to GitHub.
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
1. **GitHub account** - Sign up at https://github.com if you don't have one
|
|
||||||
2. **Git installed** - Check with `git --version` in terminal
|
|
||||||
3. **GitHub CLI (optional)** - Makes repository creation easier: https://cli.github.com/
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Option 1: Using GitHub Web Interface (Easiest)
|
|
||||||
|
|
||||||
### Step 1: Create Repository on GitHub
|
|
||||||
|
|
||||||
1. Go to https://github.com/new
|
|
||||||
2. Fill in:
|
|
||||||
- **Repository name**: `esp8266-weather-clock-opensource`
|
|
||||||
- **Description**: `Secure open-source firmware for ESP8266 weather clock - reverse engineered from AliExpress DIY kit`
|
|
||||||
- **Visibility**: Public ✅
|
|
||||||
- **Initialize**: ❌ Do NOT check "Add README" (we have one)
|
|
||||||
3. Click: **Create repository**
|
|
||||||
|
|
||||||
### Step 2: Initialize Local Git Repository
|
|
||||||
|
|
||||||
Open terminal and navigate to project directory:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd "/Users/apetrochenko/Library/Mobile Documents/com~apple~CloudDocs/src/arduino/clock/esp8266-weather-clock-opensource"
|
|
||||||
```
|
|
||||||
|
|
||||||
Initialize git and add files:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Initialize git
|
|
||||||
git init
|
|
||||||
|
|
||||||
# Add all files
|
|
||||||
git add .
|
|
||||||
|
|
||||||
# Create first commit
|
|
||||||
git commit -m "Initial commit: v1.9.1 production firmware
|
|
||||||
|
|
||||||
- Complete reverse engineering of TJ-56-654 weather clock
|
|
||||||
- Fixes security issues (WiFi password leak)
|
|
||||||
- Fully async architecture (zero blocking)
|
|
||||||
- OTA updates, web interface, REST API
|
|
||||||
- Open-Meteo weather (free, no API key)
|
|
||||||
- Comprehensive documentation"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step 3: Connect to GitHub
|
|
||||||
|
|
||||||
Replace `YOUR_USERNAME` with your actual GitHub username:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Add remote
|
|
||||||
git remote add origin https://github.com/YOUR_USERNAME/esp8266-weather-clock-opensource.git
|
|
||||||
|
|
||||||
# Set main branch
|
|
||||||
git branch -M main
|
|
||||||
|
|
||||||
# Push to GitHub
|
|
||||||
git push -u origin main
|
|
||||||
```
|
|
||||||
|
|
||||||
**If prompted for credentials:**
|
|
||||||
- Username: Your GitHub username
|
|
||||||
- Password: Use **Personal Access Token** (not your password!)
|
|
||||||
- Create token at: https://github.com/settings/tokens
|
|
||||||
- Select scopes: `repo` (full control of private repositories)
|
|
||||||
|
|
||||||
### Step 4: Verify Upload
|
|
||||||
|
|
||||||
1. Browse to: `https://github.com/YOUR_USERNAME/esp8266-weather-clock-opensource`
|
|
||||||
2. You should see:
|
|
||||||
- README.md rendered nicely
|
|
||||||
- All directories and files
|
|
||||||
- First commit visible
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Option 2: Using GitHub CLI (Faster)
|
|
||||||
|
|
||||||
If you have GitHub CLI installed:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Navigate to project
|
|
||||||
cd "/Users/apetrochenko/Library/Mobile Documents/com~apple~CloudDocs/src/arduino/clock/esp8266-weather-clock-opensource"
|
|
||||||
|
|
||||||
# Authenticate (one-time)
|
|
||||||
gh auth login
|
|
||||||
|
|
||||||
# Create repo and push in one command
|
|
||||||
gh repo create esp8266-weather-clock-opensource \
|
|
||||||
--public \
|
|
||||||
--source=. \
|
|
||||||
--description="Secure open-source firmware for ESP8266 weather clock" \
|
|
||||||
--push
|
|
||||||
```
|
|
||||||
|
|
||||||
Done! Repository is created and pushed.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Step 5: Configure Repository Settings
|
|
||||||
|
|
||||||
### Add Topics (Tags)
|
|
||||||
|
|
||||||
1. Go to your repo on GitHub
|
|
||||||
2. Click: **⚙️ Settings** (top right near About)
|
|
||||||
3. Under "Topics", add:
|
|
||||||
- `esp8266`
|
|
||||||
- `arduino`
|
|
||||||
- `iot`
|
|
||||||
- `weather-station`
|
|
||||||
- `reverse-engineering`
|
|
||||||
- `security`
|
|
||||||
- `oled-display`
|
|
||||||
- `ntp`
|
|
||||||
- `ota-updates`
|
|
||||||
- `open-meteo`
|
|
||||||
|
|
||||||
### Update About Section
|
|
||||||
|
|
||||||
1. Go to repo main page
|
|
||||||
2. Click: **⚙️** (gear icon) next to "About"
|
|
||||||
3. Set:
|
|
||||||
- **Description**: `Secure open-source firmware for ESP8266 weather clock - reverse engineered from AliExpress DIY kit to fix security flaws`
|
|
||||||
- **Website**: `https://open-meteo.com` (or your personal site if you blog about it)
|
|
||||||
- **Topics**: Should already be set from above
|
|
||||||
|
|
||||||
### Enable Features
|
|
||||||
|
|
||||||
In **Settings → General**:
|
|
||||||
|
|
||||||
**Features**:
|
|
||||||
- ✅ Issues (for bug reports)
|
|
||||||
- ✅ Discussions (for questions)
|
|
||||||
- ❌ Wiki (not needed, we have docs/)
|
|
||||||
- ❌ Projects (not needed yet)
|
|
||||||
|
|
||||||
**Pull Requests**:
|
|
||||||
- ✅ Allow squash merging
|
|
||||||
- ✅ Automatically delete head branches
|
|
||||||
|
|
||||||
### Set Up GitHub Actions
|
|
||||||
|
|
||||||
The CI workflow should activate automatically on first push. Check:
|
|
||||||
1. Go to: **Actions** tab
|
|
||||||
2. You should see: "Build Firmware" workflow
|
|
||||||
3. It should run and ✅ pass (compiles firmware)
|
|
||||||
|
|
||||||
If it fails:
|
|
||||||
- Check library names in `.github/workflows/build.yml`
|
|
||||||
- Some libraries may need exact version pinning
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Step 6: Create First Release
|
|
||||||
|
|
||||||
### Tag the Release Locally
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Create annotated tag
|
|
||||||
git tag -a v1.9.1 -m "Release v1.9.1: Production-ready firmware
|
|
||||||
|
|
||||||
Features:
|
|
||||||
- Hybrid WiFi model (sync on boot, async in loop)
|
|
||||||
- Daylight duration display
|
|
||||||
- Fully async NTP, weather, WiFi reconnect
|
|
||||||
- OTA updates, web interface, REST API
|
|
||||||
- Open-Meteo weather (free API)
|
|
||||||
- Security fixes (no WiFi password leak)
|
|
||||||
|
|
||||||
Fixes:
|
|
||||||
- Startup display blank for 10+ seconds
|
|
||||||
- DNS resolution failed errors
|
|
||||||
- Sunrise/sunset label cutoff"
|
|
||||||
|
|
||||||
# Push tag to GitHub
|
|
||||||
git push origin v1.9.1
|
|
||||||
```
|
|
||||||
|
|
||||||
### Create Release on GitHub
|
|
||||||
|
|
||||||
1. Go to: **Releases** (right sidebar)
|
|
||||||
2. Click: **Draft a new release**
|
|
||||||
3. Fill in:
|
|
||||||
- **Tag**: `v1.9.1` (should appear in dropdown)
|
|
||||||
- **Release title**: `v1.9.1 - Production Ready`
|
|
||||||
- **Description**:
|
|
||||||
```markdown
|
|
||||||
## 🎉 First Public Release
|
|
||||||
|
|
||||||
Secure, open-source replacement firmware for ESP8266 weather clocks.
|
|
||||||
|
|
||||||
### ✨ Highlights
|
|
||||||
- **Security**: Fixes WiFi password leak in original firmware
|
|
||||||
- **Performance**: Fully async architecture, <1ms loop time
|
|
||||||
- **Features**: OTA updates, web UI, REST API, NTP time, weather
|
|
||||||
- **Free API**: Uses Open-Meteo (no registration required)
|
|
||||||
|
|
||||||
### 📦 Downloads
|
|
||||||
- `esp8266-weather-clock-v1.9.1.bin` - Flash this via OTA or FTDI
|
|
||||||
|
|
||||||
### 📖 Documentation
|
|
||||||
- [Installation Guide](docs/INSTALLATION.md)
|
|
||||||
- [Hardware Specs](docs/HARDWARE.md)
|
|
||||||
- [Full Changelog](CHANGELOG.md)
|
|
||||||
|
|
||||||
### 🚀 Quick Start
|
|
||||||
1. Download `.bin` file
|
|
||||||
2. Flash via FTDI (first time) or OTA (updates)
|
|
||||||
3. Connect to `TJ56654-Setup` WiFi
|
|
||||||
4. Configure your network
|
|
||||||
5. Access web UI at `http://tj56654-clock.local`
|
|
||||||
|
|
||||||
See [README](README.md) for complete instructions.
|
|
||||||
|
|
||||||
### 🐛 Known Issues
|
|
||||||
None! This release is production-ready and tested 24/7.
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Attach binary** (if you have it locally):
|
|
||||||
- Compile firmware first: Arduino IDE → Sketch → Export Compiled Binary
|
|
||||||
- Or use GitHub Actions artifact
|
|
||||||
- Drag `build/clock_ntp_ota_v1.9.ino.bin` to release assets
|
|
||||||
- Rename to: `esp8266-weather-clock-v1.9.1.bin`
|
|
||||||
|
|
||||||
5. Click: **Publish release**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Step 7: Add Shields/Badges to README
|
|
||||||
|
|
||||||
Edit `README.md` and add at the top (after title):
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
<p align="center">
|
|
||||||
<a href="https://github.com/YOUR_USERNAME/esp8266-weather-clock-opensource/releases">
|
|
||||||
<img src="https://img.shields.io/github/v/release/YOUR_USERNAME/esp8266-weather-clock-opensource?style=flat-square" alt="Release">
|
|
||||||
</a>
|
|
||||||
<a href="https://github.com/YOUR_USERNAME/esp8266-weather-clock-opensource/blob/main/LICENSE">
|
|
||||||
<img src="https://img.shields.io/github/license/YOUR_USERNAME/esp8266-weather-clock-opensource?style=flat-square" alt="License">
|
|
||||||
</a>
|
|
||||||
<a href="https://github.com/YOUR_USERNAME/esp8266-weather-clock-opensource/actions">
|
|
||||||
<img src="https://img.shields.io/github/actions/workflow/status/YOUR_USERNAME/esp8266-weather-clock-opensource/build.yml?style=flat-square" alt="Build">
|
|
||||||
</a>
|
|
||||||
<a href="https://github.com/YOUR_USERNAME/esp8266-weather-clock-opensource/issues">
|
|
||||||
<img src="https://img.shields.io/github/issues/YOUR_USERNAME/esp8266-weather-clock-opensource?style=flat-square" alt="Issues">
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
```
|
|
||||||
|
|
||||||
Replace `YOUR_USERNAME` with actual username.
|
|
||||||
|
|
||||||
Commit and push:
|
|
||||||
```bash
|
|
||||||
git add README.md
|
|
||||||
git commit -m "Add badges to README"
|
|
||||||
git push
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Step 8: Share Your Project
|
|
||||||
|
|
||||||
### Post on Social Media
|
|
||||||
|
|
||||||
**Reddit:**
|
|
||||||
- r/esp8266
|
|
||||||
- r/arduino
|
|
||||||
- r/selfhosted
|
|
||||||
- r/homeassistant (when you add HA integration)
|
|
||||||
|
|
||||||
**Hackaday:**
|
|
||||||
- Submit project tip: https://hackaday.com/submit-a-tip/
|
|
||||||
|
|
||||||
**Hackster.io:**
|
|
||||||
- Create project page: https://www.hackster.io/
|
|
||||||
|
|
||||||
**Twitter/X:**
|
|
||||||
```
|
|
||||||
Just reverse-engineered a $12 AliExpress weather clock and found it was leaking WiFi passwords!
|
|
||||||
|
|
||||||
Replaced the firmware with secure open-source version:
|
|
||||||
- ✅ No password leak
|
|
||||||
- ✅ OTA updates
|
|
||||||
- ✅ Free weather API
|
|
||||||
- ✅ Full async arch
|
|
||||||
|
|
||||||
Check it out: [your-repo-link]
|
|
||||||
|
|
||||||
#ESP8266 #IoTSecurity #Arduino
|
|
||||||
```
|
|
||||||
|
|
||||||
### Add to Awesome Lists
|
|
||||||
|
|
||||||
Search for "awesome ESP8266" and submit PR to add your project.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Maintenance Tips
|
|
||||||
|
|
||||||
### Keep README Updated
|
|
||||||
|
|
||||||
When you add features:
|
|
||||||
1. Update README.md
|
|
||||||
2. Update CHANGELOG.md
|
|
||||||
3. Create new git tag
|
|
||||||
4. Create GitHub release
|
|
||||||
|
|
||||||
### Respond to Issues
|
|
||||||
|
|
||||||
Enable email notifications:
|
|
||||||
1. Go to: repo → **Watch** → **Custom**
|
|
||||||
2. Check: ✅ Issues, ✅ Pull requests, ✅ Discussions
|
|
||||||
|
|
||||||
### Version Numbering
|
|
||||||
|
|
||||||
Use semantic versioning (semver.org):
|
|
||||||
- `v2.0.0`: Breaking changes (incompatible config)
|
|
||||||
- `v1.10.0`: New features (backward-compatible)
|
|
||||||
- `v1.9.2`: Bug fixes only
|
|
||||||
|
|
||||||
### Automated Releases
|
|
||||||
|
|
||||||
GitHub Actions can auto-build on new tags. Check `.github/workflows/build.yml`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### "Permission denied" when pushing
|
|
||||||
|
|
||||||
**Solution**: Use Personal Access Token instead of password
|
|
||||||
1. Generate: https://github.com/settings/tokens
|
|
||||||
2. Scopes: `repo` (full control)
|
|
||||||
3. Use token as password when prompted
|
|
||||||
|
|
||||||
Or configure SSH keys:
|
|
||||||
```bash
|
|
||||||
# Generate SSH key
|
|
||||||
ssh-keygen -t ed25519 -C "your_email@example.com"
|
|
||||||
|
|
||||||
# Add to GitHub: Settings → SSH Keys → New SSH key
|
|
||||||
# Paste contents of ~/.ssh/id_ed25519.pub
|
|
||||||
|
|
||||||
# Change remote to SSH
|
|
||||||
git remote set-url origin git@github.com:YOUR_USERNAME/esp8266-weather-clock-opensource.git
|
|
||||||
```
|
|
||||||
|
|
||||||
### "This repository is empty"
|
|
||||||
|
|
||||||
You forgot to push:
|
|
||||||
```bash
|
|
||||||
git push -u origin main
|
|
||||||
```
|
|
||||||
|
|
||||||
### Files too large
|
|
||||||
|
|
||||||
GitHub has 100MB file size limit. If you accidentally added build artifacts:
|
|
||||||
```bash
|
|
||||||
# Remove from staging
|
|
||||||
git reset HEAD build/
|
|
||||||
|
|
||||||
# Add to .gitignore
|
|
||||||
echo "build/" >> .gitignore
|
|
||||||
|
|
||||||
# Commit
|
|
||||||
git commit -m "Ignore build artifacts"
|
|
||||||
```
|
|
||||||
|
|
||||||
### CI build fails
|
|
||||||
|
|
||||||
Check:
|
|
||||||
- Library names are correct in `build.yml`
|
|
||||||
- All libraries are available via Arduino Library Manager
|
|
||||||
- Firmware compiles locally first
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Next Steps After Publishing
|
|
||||||
|
|
||||||
1. **Star your own repo** (to make it discoverable)
|
|
||||||
2. **Watch releases** (be notified of activity)
|
|
||||||
3. **Enable Discussions** (for community Q&A)
|
|
||||||
4. **Create SECURITY.md** (if you want responsible disclosure process)
|
|
||||||
5. **Add funding links** (GitHub Sponsors, Buy Me a Coffee, etc.)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## GitHub Repository Best Practices
|
|
||||||
|
|
||||||
### Essential Files (✅ You have these!)
|
|
||||||
- ✅ README.md
|
|
||||||
- ✅ LICENSE
|
|
||||||
- ✅ CONTRIBUTING.md
|
|
||||||
- ✅ CHANGELOG.md
|
|
||||||
- ✅ .gitignore
|
|
||||||
- ✅ Issue templates
|
|
||||||
|
|
||||||
### Nice-to-Have
|
|
||||||
- CODE_OF_CONDUCT.md (for community standards)
|
|
||||||
- SECURITY.md (vulnerability disclosure policy)
|
|
||||||
- FUNDING.yml (donation links)
|
|
||||||
|
|
||||||
### Pin Important Files
|
|
||||||
|
|
||||||
On your repo page, pin:
|
|
||||||
1. README.md (auto-pinned)
|
|
||||||
2. INSTALLATION.md (pin in About section)
|
|
||||||
3. Latest release (pin in sidebar)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Success Checklist
|
|
||||||
|
|
||||||
After publishing, verify:
|
|
||||||
- [ ] Repository is public and accessible
|
|
||||||
- [ ] README renders correctly (images, links work)
|
|
||||||
- [ ] All documentation files are present
|
|
||||||
- [ ] CI/CD pipeline passes (green checkmark)
|
|
||||||
- [ ] First release is tagged and published
|
|
||||||
- [ ] Binary is attached to release
|
|
||||||
- [ ] Topics/tags are set
|
|
||||||
- [ ] License is visible
|
|
||||||
- [ ] Issues and Discussions are enabled
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Congratulations!** Your project is now public and ready to help the world build secure IoT devices. 🚀
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Repository URL**: https://github.com/YOUR_USERNAME/esp8266-weather-clock-opensource
|
|
||||||
|
|
||||||
Don't forget to replace `YOUR_USERNAME` with your actual GitHub username!
|
|
||||||
Reference in New Issue
Block a user