Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
a39a3fb
save network config on nvs
phofmeier Jul 20, 2025
fe138bf
build factory app and releases
phofmeier Aug 9, 2025
4c9e987
correct name
phofmeier Aug 9, 2025
71124e3
correct path
phofmeier Aug 9, 2025
fa0392d
correct path
phofmeier Aug 9, 2025
556d699
tree test
phofmeier Aug 10, 2025
70323ba
move correct files
phofmeier Aug 10, 2025
ca7b3c8
move correct files
phofmeier Aug 10, 2025
b607915
pretty release
phofmeier Aug 10, 2025
c5f1a5d
first ota implementation
phofmeier Nov 23, 2025
00c48df
use cert bundle by default
phofmeier Nov 23, 2025
4489fd2
add correct requierments
phofmeier Nov 23, 2025
704e417
update after restart
phofmeier Nov 23, 2025
fd0a57b
Add feature for OTA update
phofmeier Jan 2, 2026
9a8de9f
fix pre-commit
phofmeier Jan 2, 2026
b6b71dc
print new version
phofmeier Jan 2, 2026
5905c6c
update release script
phofmeier Jan 2, 2026
a0416bf
update release workflow
phofmeier Jan 2, 2026
be58f7c
set default ota update url
phofmeier Jan 2, 2026
6c805ff
add scheduler for automatic ota updates
phofmeier Jan 3, 2026
ceef347
enable app rollback
phofmeier Jan 3, 2026
8025e90
correct cumputation of wait time
phofmeier Jan 4, 2026
7ce7d91
version extractor
phofmeier Jan 4, 2026
9f77f01
correct version handling for updates
phofmeier Jan 4, 2026
64146c1
add config page
phofmeier Jan 11, 2026
789d456
fix build
phofmeier Jan 11, 2026
c40dc51
fix config page
phofmeier Jan 13, 2026
04fa293
generate url qr code
phofmeier Jan 13, 2026
e30bae4
changelog adapted
phofmeier Jan 13, 2026
34d6c28
Update script to flash from download
phofmeier Jan 13, 2026
db39e0e
update flash script for hard reset
phofmeier Jan 13, 2026
7e7b59d
using correct task delay function
phofmeier Jan 13, 2026
bd7ebef
add force download flag to flash script
phofmeier Jan 18, 2026
d81eb43
update Readme
phofmeier Jan 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM espressif/idf:v5.4.2
FROM espressif/idf:v5.5.1

ARG DEBIAN_FRONTEND=nointeractive
ARG CONTAINER_USER=esp
Expand All @@ -19,6 +19,8 @@ RUN apt update \
cppcheck \
# iwyu \
# cpplint \
qrencode \
wget \
&& rm -rf /var/lib/apt/lists/*

# QEMU
Expand Down
5 changes: 3 additions & 2 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
},
"runArgs": [
"--privileged",
"--device=/dev/ttyUSB0"
"--device=/dev/ttyUSB0",
"-p=8070:8070"
],
"postCreateCommand": "pip install --upgrade pip && pip install pre-commit && pre-commit install --install-hooks"
"postCreateCommand": "pip install --upgrade pip && pip install setuptools -U && pip install pre-commit && pre-commit install --install-hooks"
}
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ jobs:
imageName: ghcr.io/${{ github.repository_owner }}/ebbflowcontrol-devcontainer
# Change this to be your CI task/script
runCmd: |
idf.py build
./build_all.sh
62 changes: 62 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Create Release

on:
push:
# Sequence of patterns matched against refs/tags
tags:
- "v*" # Push events to matching v*, i.e. v1.0, v20.15.10

jobs:
create_release:
name: Create Release
runs-on: ubuntu-latest
steps:
- name: Get version from tag
id: tag_name
run: |
echo "current_version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
shell: bash
- name: Checkout code
uses: actions/checkout@v4
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and run Dev Container task
uses: devcontainers/ci@v0.3
with:
# Change this to point to your image name
imageName: ghcr.io/${{ github.repository_owner }}/ebbflowcontrol-devcontainer
# Change this to be your CI task/script
runCmd: |
./build_all.sh
- name: Zip factory build files
run: |
# Extract filenames from flash_project_args (keeping paths)
FILES_TO_ZIP=$(awk 'NR > 1 {print "./build_factory/"$2}' ./build_factory/flash_project_args | tr '\n' ' ')
# Add additional files
FILES_TO_ZIP="$FILES_TO_ZIP EbbFlowControl-Setup_wifi_qr.png EbbFlowControl-Setup_connection_url_qr.png ./build_factory/flash_project_args"
echo "Files to zip: $FILES_TO_ZIP"
zip FactoryBuildFiles.zip $FILES_TO_ZIP
- name: Get Changelog Entry
id: changelog_reader
uses: mindsers/changelog-reader-action@v2
with:
validation_level: warn
version: ${{ steps.tag_name.outputs.current_version }}
path: ./CHANGELOG.md
- name: Create Release
id: create_release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.changelog_reader.outputs.version }}
name: Release ${{ steps.changelog_reader.outputs.version }}
body: ${{ steps.changelog_reader.outputs.changes }}
prerelease: ${{ steps.changelog_reader.outputs.status == 'prereleased' }}
draft: ${{ steps.changelog_reader.outputs.status == 'unreleased' }}
token: ${{ secrets.GITHUB_TOKEN }}
files: |
./build_app/EbbFlowControl.bin
FactoryBuildFiles.zip
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,14 @@ Mkfile.old
dkms.conf

build/
build_factory/
build_app/
sdkconfig
sdkconfig.old
node_modules
warnings.txt
tools/ota_server/ca_cert.pem
tools/ota_server/ca_key.pem
log.*
FactoryBuildFiles.zip
downloads/
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ repos:
"--suppress=missingIncludeSystem",
"--suppress=unusedFunction",
"--suppress=missingInclude",
"--inline-suppr"
]
# - id: cpplint
# - id: include-what-you-use
Expand Down
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,15 @@ Use the following labels:
- `Fixed` for any bug fixes.
- `Security` in case of vulnerabilities.

## [UNRELEASED]
## [0.1.1] - 2026-01-13

- [Patch] Add configuration webpage for network configuration.

## [0.1.0] - 2026-01-03

- [Minor] Add over the air update feature.
- [Minor] Add factory build to load latest version.
- [Minor] Add automatic update scheduler.

## [0.0.1] - 2025-07-11

Expand Down
28 changes: 28 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,33 @@
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)

option(BUILD_FACTORY "Build the factory app" OFF)
message(STATUS "Build Factory Flag: ${BUILD_FACTORY}")

set(SDKCONFIG "${CMAKE_BINARY_DIR}/sdkconfig")

include($ENV{IDF_PATH}/tools/cmake/project.cmake)

if(BUILD_FACTORY)
project(EbbFlowControl-factory)
message(STATUS "Build Factory")
else()
project(EbbFlowControl)
message(STATUS "Build Normal Application")
endif()

# Custom command to generate QR code for WiFi credentials
set(QR_CODE_FILE "${CMAKE_SOURCE_DIR}/${CONFIG_WIFI_SOFT_AP_SSID}_wifi_qr.png")
add_custom_command(
OUTPUT ${QR_CODE_FILE}
COMMAND ${CMAKE_COMMAND} -E echo "Generating WiFi QR code..."
COMMAND ./scripts/generate_wifi_qr_code.sh "${CONFIG_WIFI_SOFT_AP_SSID}" "${CONFIG_WIFI_SOFT_AP_PASSWORD}" "192.168.4.1" "80" "WPA2"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS ${SDKCONFIG}
COMMENT "Generating QR code for SoftAP WiFi credentials"
)

# Custom target to generate QR code
add_custom_target(generate_wifi_qr
DEPENDS ${QR_CODE_FILE}
)
Binary file added EbbFlowControl-Setup_connection_url_qr.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added EbbFlowControl-Setup_wifi_qr.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 41 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,53 @@
![GitHub release (latest by date)](https://img.shields.io/github/v/release/phofmeier/EbbFlowControl?label=Current%20Release)
[![build](https://github.com/phofmeier/EbbFlowControl/actions/workflows/build.yml/badge.svg)](https://github.com/phofmeier/EbbFlowControl/actions/workflows/build.yml)
[![pre-commit](https://github.com/phofmeier/EbbFlowControl/actions/workflows/pre-commit.yml/badge.svg)](https://github.com/phofmeier/EbbFlowControl/actions/workflows/pre-commit.yml)

# Ebb Flow Control

This repository hold the software for a controller for an automated ebb flow hydroponic grow system. The controller runs on an ESP32 and can be configured via MQTT. The MQTT connection is additionally used to send status information and data for monitoring to an overall system.

## Quick Start

Use the script `scripts/download_and_flash_release.sh` to download and flash the newest released software version to your ESP32 Board.

### First configuration

Scan the QR Code to connect to the Wifi.

![Wifi QR Code](EbbFlowControl-Setup_wifi_qr.png?raw=True)

Scan the QR Code to show the Configuration Website.

![Config Website URL](EbbFlowControl-Setup_connection_url_qr.png?raw=True)


## Over the Air (OTA) updates

There are two different apps built for this project.

### Factory application

The factory application does not hold the normal application. It only serves for a first initial configuration and downloading the latests main application. It starts an Wifi Access point and host a webpage to configure the device for the first time. The Wifi and webpage can be joind by scanning the qr-codes shown [here](#first-configuration). After submitting the correct configuration it downloads the latest version of the main application and starts it.

### Main application

The main application is running always. It serves all the implemented features. It can be updated over the air by having always teo copies of the application. Always when a new version is released it is downloaded automatically at around midnight and is written on en extra partition. Be aware that it never overrides the factory app. After a successful update the new code needs to run for more than 24h to be considered valid. A restart during this timeframe would consider the update as invalid and the old app would be booted again.

## Build and Flash

The easiest way to build the software is to run the Docker devcontainer.
Inside the container you can use the espressif idf build environment. Run the following commands to build flash and monitor the device on the software.
If you do not need any special configuration you can just download and flash the prebuild release version with the script located `scripts/download_and_flash_release.sh`.

```
idf.py build
idf.py flash
idf.py monitor
```
If you need to change anything the easiest way to build the software is to run the Docker devcontainer.
Inside the container you can use the espressif idf build environment.

### Factory vs Application build

For building the factory or main application the profile files can be used. The following list shows the how to use them.

- Build application: `idf.py @profiles/app build`
- Flash application: `idf.py @profiles/app flash`
- Build factory: `idf.py @profiles/factory build`
- Flash factory: `idf.py @profiles/factory flash`

For configuration use the idf configuration environment. See the paragraph about the [configuration](#configuration) for more details.

Expand Down Expand Up @@ -123,6 +156,7 @@ Data:
| id | uint_8 | Id of the specific board Integer between 0 and 255 |
| connection | string | Current connection status to the MQTT Broker. "connected" or "disconnected" |
| rssi_level | int | Connection strength of the Wifi connection. -100 if an error occurs. |
| version | string | Version string of the current running version. |

Example:

Expand Down
16 changes: 16 additions & 0 deletions build_all.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash

# Build script for two apps

set -e

echo "Building Application"
idf.py @profiles/app build || { echo "Application build failed"; exit -1; }

echo "Building Factory"
idf.py @profiles/factory build || { echo "Factory build failed"; exit -1; }

cmake --build build_factory --target generate_wifi_qr || { echo "QR code generation failed"; exit -1; }

echo "Build finished.."
exit 0
4 changes: 4 additions & 0 deletions components/config_page/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
idf_component_register(SRCS "config_page.c"
INCLUDE_DIRS "include"
REQUIRES esp_http_server configuration
EMBED_FILES html/config_page.html)
Loading