fonctionnel
This commit is contained in:
parent
7f2a5633d5
commit
8c796dbb9d
159
.devcontainer/Dockerfile
Normal file
159
.devcontainer/Dockerfile
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
# Copy paste of https://github.com/espressif/esp-idf/blob/master/tools/docker/Dockerfile
|
||||||
|
# but with ubuntu image downgraded.
|
||||||
|
# You must download https://github.com/espressif/esp-idf/blob/master/tools/docker/entrypoint.sh
|
||||||
|
# and place it in the .devcontainer directory.
|
||||||
|
#FROM ubuntu:24.04
|
||||||
|
FROM ubuntu:22.04
|
||||||
|
|
||||||
|
ARG DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
RUN : \
|
||||||
|
&& apt-get update \
|
||||||
|
&& apt-get install -y \
|
||||||
|
apt-utils \
|
||||||
|
bison \
|
||||||
|
bzip2 \
|
||||||
|
ca-certificates \
|
||||||
|
ccache \
|
||||||
|
check \
|
||||||
|
curl \
|
||||||
|
flex \
|
||||||
|
git \
|
||||||
|
git-lfs \
|
||||||
|
gperf \
|
||||||
|
lcov \
|
||||||
|
libbsd-dev \
|
||||||
|
libffi-dev \
|
||||||
|
libglib2.0-0 \
|
||||||
|
libncurses-dev \
|
||||||
|
libpixman-1-0 \
|
||||||
|
libsdl2-2.0-0 \
|
||||||
|
libslirp0 \
|
||||||
|
libusb-1.0-0-dev \
|
||||||
|
make \
|
||||||
|
ninja-build \
|
||||||
|
python3 \
|
||||||
|
python3-venv \
|
||||||
|
ruby \
|
||||||
|
unzip \
|
||||||
|
wget \
|
||||||
|
xz-utils \
|
||||||
|
zip \
|
||||||
|
&& apt-get autoremove -y \
|
||||||
|
&& rm -rf /var/lib/apt/lists/* \
|
||||||
|
&& update-alternatives --install /usr/bin/python python /usr/bin/python3 10 \
|
||||||
|
&& :
|
||||||
|
|
||||||
|
# To build the image for a branch or a tag of IDF, pass --build-arg IDF_CLONE_BRANCH_OR_TAG=name.
|
||||||
|
# To build the image with a specific commit ID of IDF, pass --build-arg IDF_CHECKOUT_REF=commit-id.
|
||||||
|
# It is possible to combine both, e.g.:
|
||||||
|
# IDF_CLONE_BRANCH_OR_TAG=release/vX.Y
|
||||||
|
# IDF_CHECKOUT_REF=<some commit on release/vX.Y branch>.
|
||||||
|
# Use IDF_CLONE_SHALLOW=1 to perform shallow clone (i.e. --depth=1 --shallow-submodules)
|
||||||
|
# Use IDF_CLONE_SHALLOW_DEPTH=X to define the depth if IDF_CLONE_SHALLOW is used (i.e. --depth=X)
|
||||||
|
# Use IDF_INSTALL_TARGETS to install tools only for selected chip targets (CSV)
|
||||||
|
|
||||||
|
ARG IDF_CLONE_URL=https://github.com/espressif/esp-idf.git
|
||||||
|
ARG IDF_CLONE_BRANCH_OR_TAG=master
|
||||||
|
ARG IDF_CHECKOUT_REF=
|
||||||
|
ARG IDF_CLONE_SHALLOW=
|
||||||
|
ARG IDF_CLONE_SHALLOW_DEPTH=1
|
||||||
|
ARG IDF_INSTALL_TARGETS=all
|
||||||
|
|
||||||
|
ENV IDF_PATH=/opt/esp/idf
|
||||||
|
ENV IDF_TOOLS_PATH=/opt/esp
|
||||||
|
|
||||||
|
# install build essential needed for linux target apps, which is a preview target so it is installed with "all" only
|
||||||
|
RUN if [ "$IDF_INSTALL_TARGETS" = "all" ]; then \
|
||||||
|
apt-get update \
|
||||||
|
&& apt-get install -y build-essential \
|
||||||
|
&& apt-get autoremove -y \
|
||||||
|
&& rm -rf /var/lib/apt/lists/* ; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
RUN echo IDF_CHECKOUT_REF=$IDF_CHECKOUT_REF IDF_CLONE_BRANCH_OR_TAG=$IDF_CLONE_BRANCH_OR_TAG && \
|
||||||
|
git clone --recursive \
|
||||||
|
${IDF_CLONE_SHALLOW:+--depth=${IDF_CLONE_SHALLOW_DEPTH} --shallow-submodules} \
|
||||||
|
${IDF_CLONE_BRANCH_OR_TAG:+-b $IDF_CLONE_BRANCH_OR_TAG} \
|
||||||
|
$IDF_CLONE_URL $IDF_PATH && \
|
||||||
|
git config --system --add safe.directory $IDF_PATH && \
|
||||||
|
if [ -n "$IDF_CHECKOUT_REF" ]; then \
|
||||||
|
cd $IDF_PATH && \
|
||||||
|
if [ -n "$IDF_CLONE_SHALLOW" ]; then \
|
||||||
|
git fetch origin --depth=${IDF_CLONE_SHALLOW_DEPTH} --recurse-submodules ${IDF_CHECKOUT_REF}; \
|
||||||
|
fi && \
|
||||||
|
git checkout $IDF_CHECKOUT_REF && \
|
||||||
|
git submodule update --init --recursive; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install all the required tools
|
||||||
|
RUN : \
|
||||||
|
&& update-ca-certificates --fresh \
|
||||||
|
&& $IDF_PATH/tools/idf_tools.py --non-interactive install required --targets=${IDF_INSTALL_TARGETS} \
|
||||||
|
&& $IDF_PATH/tools/idf_tools.py --non-interactive install qemu* --targets=${IDF_INSTALL_TARGETS} \
|
||||||
|
&& $IDF_PATH/tools/idf_tools.py --non-interactive install cmake \
|
||||||
|
&& $IDF_PATH/tools/idf_tools.py --non-interactive install-python-env \
|
||||||
|
&& rm -rf $IDF_TOOLS_PATH/dist \
|
||||||
|
&& :
|
||||||
|
|
||||||
|
# Add get_idf as alias
|
||||||
|
RUN echo 'alias get_idf=". /opt/esp/idf/export.sh"' >> /root/.bashrc
|
||||||
|
|
||||||
|
# The constraint file has been downloaded and the right Python package versions installed. No need to check and
|
||||||
|
# download this at every invocation of the container.
|
||||||
|
ENV IDF_PYTHON_CHECK_CONSTRAINTS=no
|
||||||
|
|
||||||
|
# Ccache is installed, enable it by default
|
||||||
|
ENV IDF_CCACHE_ENABLE=1
|
||||||
|
|
||||||
|
COPY entrypoint.sh /opt/esp/entrypoint.sh
|
||||||
|
RUN chmod +x /opt/esp/entrypoint.sh
|
||||||
|
|
||||||
|
#Original file starts here
|
||||||
|
#FROM espressif/idf
|
||||||
|
|
||||||
|
#ARG DEBIAN_FRONTEND=nointeractive
|
||||||
|
ARG CONTAINER_USER=esp
|
||||||
|
ARG USER_UID=1050
|
||||||
|
ARG USER_GID=$USER_UID
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt install -y -q \
|
||||||
|
cmake \
|
||||||
|
git \
|
||||||
|
libglib2.0-0 \
|
||||||
|
libnuma1 \
|
||||||
|
libpixman-1-0 \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# QEMU
|
||||||
|
ENV QEMU_REL=esp_develop_8.2.0_20240122
|
||||||
|
ENV QEMU_SHA256=e7c72ef5705ad1444d391711088c8717fc89f42e9bf6d1487f9c2a326b8cfa83
|
||||||
|
ENV QEMU_DIST=qemu-xtensa-softmmu-${QEMU_REL}-x86_64-linux-gnu.tar.xz
|
||||||
|
ENV QEMU_URL=https://github.com/espressif/qemu/releases/download/esp-develop-8.2.0-20240122/${QEMU_DIST}
|
||||||
|
|
||||||
|
ENV LC_ALL=C.UTF-8
|
||||||
|
ENV LANG=C.UTF-8
|
||||||
|
|
||||||
|
RUN wget --no-verbose ${QEMU_URL} \
|
||||||
|
&& echo "${QEMU_SHA256} *${QEMU_DIST}" | sha256sum --check --strict - \
|
||||||
|
&& tar -xf $QEMU_DIST -C /opt \
|
||||||
|
&& rm ${QEMU_DIST}
|
||||||
|
|
||||||
|
ENV PATH=/opt/qemu/bin:${PATH}
|
||||||
|
|
||||||
|
RUN groupadd --gid $USER_GID $CONTAINER_USER \
|
||||||
|
&& adduser --uid $USER_UID --gid $USER_GID --disabled-password --gecos "" ${CONTAINER_USER} \
|
||||||
|
&& usermod -a -G root $CONTAINER_USER && usermod -a -G dialout $CONTAINER_USER
|
||||||
|
|
||||||
|
RUN chmod -R 775 /opt/esp/python_env/
|
||||||
|
|
||||||
|
USER ${CONTAINER_USER}
|
||||||
|
ENV USER=${CONTAINER_USER}
|
||||||
|
WORKDIR /home/${CONTAINER_USER}
|
||||||
|
|
||||||
|
RUN echo "source /opt/esp/idf/export.sh > /dev/null 2>&1" >> ~/.bashrc
|
||||||
|
|
||||||
|
ENTRYPOINT [ "/opt/esp/entrypoint.sh" ]
|
||||||
|
|
||||||
|
CMD ["/bin/bash", "-c"]
|
||||||
33
.devcontainer/devcontainer.json
Normal file
33
.devcontainer/devcontainer.json
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"name": "ESP-IDF QEMU",
|
||||||
|
"build": {
|
||||||
|
"dockerfile": "Dockerfile"
|
||||||
|
},
|
||||||
|
"customizations": {
|
||||||
|
"vscode": {
|
||||||
|
"settings": {
|
||||||
|
"terminal.integrated.defaultProfile.linux": "bash",
|
||||||
|
"idf.espIdfPath": "/opt/esp/idf",
|
||||||
|
"idf.toolsPath": "/opt/esp",
|
||||||
|
"idf.gitPath": "/usr/bin/git"
|
||||||
|
},
|
||||||
|
"extensions": [
|
||||||
|
"espressif.esp-idf-extension",
|
||||||
|
"espressif.esp-idf-web"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"codespaces": {
|
||||||
|
"settings": {
|
||||||
|
"terminal.integrated.defaultProfile.linux": "bash",
|
||||||
|
"idf.espIdfPath": "/opt/esp/idf",
|
||||||
|
"idf.toolsPath": "/opt/esp",
|
||||||
|
"idf.gitPath": "/usr/bin/git"
|
||||||
|
},
|
||||||
|
"extensions": [
|
||||||
|
"espressif.esp-idf-extension",
|
||||||
|
"espressif.esp-idf-web"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runArgs": ["--privileged"]
|
||||||
|
}
|
||||||
20
.devcontainer/entrypoint.sh
Normal file
20
.devcontainer/entrypoint.sh
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# IDF_GIT_SAFE_DIR has the same format as system PATH environment variable.
|
||||||
|
# All path specified in IDF_GIT_SAFE_DIR will be added to user's
|
||||||
|
# global git config as safe.directory paths. For more information
|
||||||
|
# see git-config manual page.
|
||||||
|
if [ -n "${IDF_GIT_SAFE_DIR+x}" ]
|
||||||
|
then
|
||||||
|
echo "Adding following directories into git's safe.directory"
|
||||||
|
echo "$IDF_GIT_SAFE_DIR" | tr ':' '\n' | while read -r dir
|
||||||
|
do
|
||||||
|
git config --global --add safe.directory "$dir"
|
||||||
|
echo " $dir"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
. $IDF_PATH/export.sh
|
||||||
|
|
||||||
|
exec "$@"
|
||||||
22
.vscode/c_cpp_properties.json
vendored
22
.vscode/c_cpp_properties.json
vendored
@ -1,20 +1,22 @@
|
|||||||
{
|
{
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "Win32",
|
"name": "ESP-IDF",
|
||||||
|
"compilerPath": "${config:idf.toolsPathWin}\\tools\\xtensa-esp-elf\\esp-13.2.0_20230928\\xtensa-esp-elf\\bin\\xtensa-esp32s3-elf-gcc.exe",
|
||||||
|
"compileCommands": "${config:idf.buildPath}/compile_commands.json",
|
||||||
"includePath": [
|
"includePath": [
|
||||||
|
"${config:idf.espIdfPath}/components/**",
|
||||||
|
"${config:idf.espIdfPathWin}/components/**",
|
||||||
"${workspaceFolder}/**"
|
"${workspaceFolder}/**"
|
||||||
],
|
],
|
||||||
"defines": [
|
"browse": {
|
||||||
"_DEBUG",
|
"path": [
|
||||||
"UNICODE",
|
"${config:idf.espIdfPath}/components",
|
||||||
"_UNICODE"
|
"${config:idf.espIdfPathWin}/components",
|
||||||
|
"${workspaceFolder}"
|
||||||
],
|
],
|
||||||
"compilerPath": "C:\\msys64\\mingw64\\bin\\gcc.exe",
|
"limitSymbolsToIncludedHeaders": true
|
||||||
"cStandard": "c17",
|
}
|
||||||
"cppStandard": "gnu++17",
|
|
||||||
"intelliSenseMode": "windows-gcc-x64",
|
|
||||||
"compileCommands": "${workspaceFolder}/build/compile_commands.json"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"version": 4
|
"version": 4
|
||||||
|
|||||||
15
.vscode/launch.json
vendored
Normal file
15
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "gdbtarget",
|
||||||
|
"request": "attach",
|
||||||
|
"name": "Eclipse CDT GDB Adapter"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "espidf",
|
||||||
|
"name": "Launch",
|
||||||
|
"request": "launch"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
36
.vscode/settings.json
vendored
36
.vscode/settings.json
vendored
@ -1,34 +1,12 @@
|
|||||||
{
|
{
|
||||||
"idf.adapterTargetName": "esp32s3",
|
"idf.adapterTargetName": "esp32s3",
|
||||||
"idf.openOcdConfigs": [
|
|
||||||
"board/esp32s3-builtin.cfg"
|
|
||||||
],
|
|
||||||
"idf.flashType": "UART",
|
"idf.flashType": "UART",
|
||||||
"idf.portWin": "COM12",
|
"idf.portWin": "COM11",
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"string_view": "c",
|
"wifi.h": "c",
|
||||||
"regex": "c",
|
"esp_log.h": "c",
|
||||||
"bitset": "c",
|
"esp_wifi.h": "c",
|
||||||
"chrono": "c",
|
"esp_lvgl_port.h": "c",
|
||||||
"random": "c",
|
"mqtt.h": "c"
|
||||||
"limits": "c",
|
}
|
||||||
"string": "c",
|
|
||||||
"format": "c",
|
|
||||||
"*.tcc": "c",
|
|
||||||
"ctime": "c",
|
|
||||||
"iomanip": "c",
|
|
||||||
"task.h": "c",
|
|
||||||
"semaphore": "c",
|
|
||||||
"typeinfo": "c",
|
|
||||||
"freertos.h": "c",
|
|
||||||
"esp_err.h": "c",
|
|
||||||
"esp_lcd_panel_rgb.h": "c",
|
|
||||||
"esp_lcd_touch_gt911.h": "c",
|
|
||||||
"esp_lcd_panel_io.h": "c",
|
|
||||||
"esp_check.h": "c",
|
|
||||||
"compare": "c",
|
|
||||||
"cstdint": "c",
|
|
||||||
"esp_sntp.h": "c"
|
|
||||||
},
|
|
||||||
"search.useIgnoreFiles": false
|
|
||||||
}
|
}
|
||||||
23
.vscode__/c_cpp_properties.json
Normal file
23
.vscode__/c_cpp_properties.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "ESP-IDF",
|
||||||
|
"compilerPath": "C:\\espidftools\\tools\\xtensa-esp-elf\\esp-13.2.0_20230928\\xtensa-esp-elf\\bin\\xtensa-esp32s3-elf-gcc.exe",
|
||||||
|
"compileCommands": "${config:idf.buildPath}/compile_commands.json",
|
||||||
|
"includePath": [
|
||||||
|
"${config:idf.espIdfPath}/components/**",
|
||||||
|
"${config:idf.espIdfPathWin}/components/**",
|
||||||
|
"${workspaceFolder}/**"
|
||||||
|
],
|
||||||
|
"browse": {
|
||||||
|
"path": [
|
||||||
|
"${config:idf.espIdfPath}/components",
|
||||||
|
"${config:idf.espIdfPathWin}/components",
|
||||||
|
"${workspaceFolder}"
|
||||||
|
],
|
||||||
|
"limitSymbolsToIncludedHeaders": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
||||||
90
.vscode__/launch.json
Normal file
90
.vscode__/launch.json
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "gdbtarget",
|
||||||
|
"request": "attach",
|
||||||
|
"name": "Eclipse CDT GDB Adapter"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "gdb",
|
||||||
|
"request": "attach",
|
||||||
|
"name": "NativeDebug",
|
||||||
|
"target": "extended-remote :3333",
|
||||||
|
"executable": "${workspaceFolder}/build/${command:espIdf.getProjectName}.elf",
|
||||||
|
"gdbpath": "${command:espIdf.getToolchainGdb}",
|
||||||
|
"cwd": "${workspaceRoot}",
|
||||||
|
"autorun": [
|
||||||
|
"mon reset halt",
|
||||||
|
"maintenance flush register-cache",
|
||||||
|
"thb app_main"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "GDB",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"MIMode": "gdb",
|
||||||
|
"miDebuggerPath": "${command:espIdf.getToolchainGdb}",
|
||||||
|
"requireExactSource": true,
|
||||||
|
"stopAtEntry": true,
|
||||||
|
"program": "${workspaceFolder}/build/${command:espIdf.getProjectName}.elf",
|
||||||
|
"windows": {
|
||||||
|
"program": "${workspaceFolder}\\build\\${command:espIdf.getProjectName}.elf"
|
||||||
|
},
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"setupCommands": [
|
||||||
|
{ "text": "set remotetimeout 20" },
|
||||||
|
],
|
||||||
|
"postRemoteConnectCommands": [
|
||||||
|
{ "text": "mon reset halt" },
|
||||||
|
{ "text": "maintenance flush register-cache"},
|
||||||
|
],
|
||||||
|
"externalConsole": false,
|
||||||
|
"logging": {
|
||||||
|
"engineLogging": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "espidf",
|
||||||
|
"name": "Launch",
|
||||||
|
"request": "launch",
|
||||||
|
"debugPort": 9998,
|
||||||
|
"logLevel": 2,
|
||||||
|
"mode": "manual",
|
||||||
|
"verifyAppBinBeforeDebug": false,
|
||||||
|
"tmoScaleFactor": 1,
|
||||||
|
"initGdbCommands": [
|
||||||
|
"target remote :3333",
|
||||||
|
"set remotetimeout 20",
|
||||||
|
"symbol-file /path/to/program.elf",
|
||||||
|
"mon reset halt",
|
||||||
|
"maintenance flush register-cache",
|
||||||
|
"thb app_main"
|
||||||
|
],
|
||||||
|
"env": {
|
||||||
|
"CUSTOM_ENV_VAR": "SOME_VALUE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "gdbtarget",
|
||||||
|
"request": "attach",
|
||||||
|
"name": "Eclipse CDT Remote",
|
||||||
|
"program": "${workspaceFolder}/build/${command:espIdf.getProjectName}.elf",
|
||||||
|
"initCommands": [
|
||||||
|
"set remotetimeout 20",
|
||||||
|
"set remote hardware-watchpoint-limit 2",
|
||||||
|
"mon reset halt",
|
||||||
|
"maintenance flush register-cache",
|
||||||
|
"thb app_main",
|
||||||
|
],
|
||||||
|
"gdb": "${command:espIdf.getToolchainGdb}",
|
||||||
|
"target": {
|
||||||
|
"port": "3333"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
9
.vscode__/settings.json
Normal file
9
.vscode__/settings.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"idf.adapterTargetName": "esp32s3",
|
||||||
|
"idf.flashType": "UART",
|
||||||
|
"idf.portWin": "COM11",
|
||||||
|
"files.associations": {
|
||||||
|
"string.h": "c"
|
||||||
|
},
|
||||||
|
"idf.espIdfPathWin": "C:\\espidf\\v5.2.3\\esp-idf"
|
||||||
|
}
|
||||||
3
components/image_downloader/CMakeLists.txt
Normal file
3
components/image_downloader/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
idf_component_register(SRCS "image_downloader.c"
|
||||||
|
INCLUDE_DIRS "include"
|
||||||
|
REQUIRES json esp_http_client esp-tls esp_timer fatfs sdmmc vfs)
|
||||||
209
components/image_downloader/image_downloader.c
Normal file
209
components/image_downloader/image_downloader.c
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
// Note: Run menuconfig to set the WiFi Credentials -> CALE Configuration
|
||||||
|
// Requirements: Needs to have an EPD Class defined. Needs PSRAM.
|
||||||
|
// This example does not use a decoded buffer hence leaves more external RAM free
|
||||||
|
// At the same time it looses the JPG_DITHER functionality in favour of render speed.
|
||||||
|
// As default only configured for parallel epapers
|
||||||
|
#include "esp_heap_caps.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_types.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/event_groups.h"
|
||||||
|
#include "esp_sleep.h"
|
||||||
|
// WiFi related
|
||||||
|
#include "esp_event.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_timer.h"
|
||||||
|
#include "lwip/err.h"
|
||||||
|
#include "lwip/sys.h"
|
||||||
|
// HTTP Client + time
|
||||||
|
#include "esp_http_client.h"
|
||||||
|
#include "esp_sntp.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define EXAMPLE_MAX_CHAR_SIZE 64
|
||||||
|
|
||||||
|
|
||||||
|
// JPG decoder
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 4 // IDF 4+
|
||||||
|
#include "esp32/rom/tjpgd.h"
|
||||||
|
#else // ESP32 Before IDF 4.0
|
||||||
|
#include "rom/tjpgd.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "esp_task_wdt.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h> // round + pow
|
||||||
|
#include "image_downloader.h"
|
||||||
|
|
||||||
|
#define MOUNT_POINT "/sdcard"
|
||||||
|
static const char *TAG = "ImgDwn";
|
||||||
|
|
||||||
|
// Image URL and jpg settings. Make sure to update EPD_WIDTH/HEIGHT if using loremflickr
|
||||||
|
// Note: Only HTTP protocol supported (Check README to use SSL secure URLs) loremflickr
|
||||||
|
#define STR_HELPER(x) #x
|
||||||
|
#define STR(x) STR_HELPER(x)
|
||||||
|
|
||||||
|
#define IMGDWN_WIDTH 600
|
||||||
|
#define IMGDWN_HEIGHT 460
|
||||||
|
#define IMGDWN_URL2 ("http://vps-edf71efa.vps.ovh.net:3000/render/d-solo/7BtRMrv4k/temperatures?orgId=1&var-emplacement=entree_ECS&var-emplacement=entree_reseauSol&panelId=4&width=650&height=460&scale=1&tz=Europe%2FParis/")
|
||||||
|
#define IMGDWN_URL ("http://vps-edf71efa.vps.ovh.net:3000/render/d-solo/bOcPeysGz/hauteur-cuve?orgId=1&from=now-2d&refresh=1m&panelId=4&width=650&height=460&scale=1&tz=Europe%2FParis")
|
||||||
|
// As default is 512 without setting buffer_size property in esp_http_client_config_t
|
||||||
|
#define HTTP_RECEIVE_BUFFER_SIZE 1938
|
||||||
|
|
||||||
|
#define DEBUG_VERBOSE false
|
||||||
|
|
||||||
|
// Buffers
|
||||||
|
uint8_t *fb; // EPD 2bpp buffer
|
||||||
|
uint8_t *source_buf; // JPG download buffer
|
||||||
|
uint8_t *decoded_image; // RAW decoded image
|
||||||
|
|
||||||
|
uint32_t buffer_pos = 0;
|
||||||
|
uint32_t time_download = 0;
|
||||||
|
uint32_t time_decomp = 0;
|
||||||
|
uint32_t time_render = 0;
|
||||||
|
|
||||||
|
uint16_t countDataEventCalls = 0;
|
||||||
|
uint32_t countDataBytes = 0;
|
||||||
|
uint32_t img_buf_pos = 0;
|
||||||
|
uint32_t dataLenTotal = 0;
|
||||||
|
uint64_t startTime = 0;
|
||||||
|
|
||||||
|
void create_file_app(uint8_t *buffer, uint32_t size)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Opening file");
|
||||||
|
//ESP_LOGI(TAG, "output buffer to spiffs: %s \n", buffer);
|
||||||
|
FILE* f = fopen(MOUNT_POINT"/hello2.png", "wb+");
|
||||||
|
if (f == NULL) {
|
||||||
|
ESP_LOGE(TAG, "Failed to open file for writing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for(int i=0; i<size;i++){
|
||||||
|
fprintf(f, "%c", buffer[i]);
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
ESP_LOGI(TAG, "File written");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handles Htpp events and is in charge of buffering source_buf (jpg compressed image)
|
||||||
|
esp_err_t _http_event_handler_id(esp_http_client_event_t *evt)
|
||||||
|
{
|
||||||
|
switch (evt->event_id)
|
||||||
|
{
|
||||||
|
case HTTP_EVENT_ERROR:
|
||||||
|
ESP_LOGE(TAG, "HTTP_EVENT_ERROR");
|
||||||
|
break;
|
||||||
|
case HTTP_EVENT_ON_CONNECTED:
|
||||||
|
ESP_LOGI(TAG, "HTTP_EVENT_ON_CONNECTED");
|
||||||
|
break;
|
||||||
|
case HTTP_EVENT_HEADER_SENT:
|
||||||
|
ESP_LOGI(TAG, "HTTP_EVENT_HEADER_SENT");
|
||||||
|
break;
|
||||||
|
case HTTP_EVENT_ON_HEADER:
|
||||||
|
#if DEBUG_VERBOSE
|
||||||
|
ESP_LOGI(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case HTTP_EVENT_ON_DATA:
|
||||||
|
++countDataEventCalls;
|
||||||
|
#if DEBUG_VERBOSE
|
||||||
|
if (countDataEventCalls%10==0) {
|
||||||
|
ESP_LOGI(TAG, "%d len:%d\n", countDataEventCalls, evt->data_len);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
dataLenTotal += evt->data_len;
|
||||||
|
|
||||||
|
if (countDataEventCalls == 1) startTime = esp_timer_get_time();
|
||||||
|
// Append received data into source_buf
|
||||||
|
memcpy(&source_buf[img_buf_pos], evt->data, evt->data_len);
|
||||||
|
img_buf_pos += evt->data_len;
|
||||||
|
|
||||||
|
// Optional hexa dump
|
||||||
|
//ESP_LOG_BUFFER_HEX(TAG, source_buf, 100);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HTTP_EVENT_REDIRECT:
|
||||||
|
break;
|
||||||
|
case HTTP_EVENT_ON_FINISH:
|
||||||
|
// Do not draw if it's a redirect (302)
|
||||||
|
if (esp_http_client_get_status_code(evt->client) == 200) {
|
||||||
|
printf("%li bytes read from %s\nIMG_BUF size: %li\n", img_buf_pos, IMGDWN_URL, img_buf_pos);
|
||||||
|
//drawBufJpeg(source_buf, 0, 0);
|
||||||
|
create_file_app(source_buf,img_buf_pos); //function which opens and records data to spiffs file
|
||||||
|
time_download = (esp_timer_get_time()-startTime)/1000;
|
||||||
|
ESP_LOGI("www-dw", "%li ms - download", time_download);
|
||||||
|
// Refresh display
|
||||||
|
//display.update();
|
||||||
|
|
||||||
|
ESP_LOGI("total", "%li ms - total time spent\n", time_download+time_decomp+time_render);
|
||||||
|
} else {
|
||||||
|
printf("HTTP on finish got status code: %d\n", esp_http_client_get_status_code(evt->client));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HTTP_EVENT_DISCONNECTED:
|
||||||
|
ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handles http request
|
||||||
|
static void download(void)
|
||||||
|
{
|
||||||
|
esp_http_client_config_t config = {
|
||||||
|
.url = IMGDWN_URL,
|
||||||
|
.disable_auto_redirect = false,
|
||||||
|
.event_handler = _http_event_handler_id,
|
||||||
|
.buffer_size = HTTP_RECEIVE_BUFFER_SIZE,
|
||||||
|
.timeout_ms = 50000
|
||||||
|
};
|
||||||
|
|
||||||
|
esp_http_client_handle_t client = esp_http_client_init(&config);
|
||||||
|
|
||||||
|
#if DEBUG_VERBOSE
|
||||||
|
printf("Free heap before HTTP download: %d\n", xPortGetFreeHeapSize());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
esp_err_t err = esp_http_client_perform(client);
|
||||||
|
if (err == ESP_OK)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "\nIMAGE URL: %s\n\nHTTP GET Status = %d, content_length = %lli\n",
|
||||||
|
IMGDWN_URL,
|
||||||
|
esp_http_client_get_status_code(client),
|
||||||
|
esp_http_client_get_content_length(client));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "\nHTTP GET request failed: %s", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("Go to sleep %d minutes\n", CONFIG_DEEPSLEEP_MINUTES_AFTER_RENDER);
|
||||||
|
esp_http_client_cleanup(client);
|
||||||
|
vTaskDelay(3600000 / portTICK_PERIOD_MS);
|
||||||
|
//deepsleep();
|
||||||
|
}
|
||||||
|
|
||||||
|
void imgdwn(void *pvParameter) {
|
||||||
|
|
||||||
|
ESP_LOGE(TAG, "beginning");
|
||||||
|
|
||||||
|
// Should be big enough to allocate the JPEG file size, width * height should suffice
|
||||||
|
source_buf = (uint8_t *)heap_caps_malloc(IMGDWN_HEIGHT * IMGDWN_WIDTH, MALLOC_CAP_SPIRAM);
|
||||||
|
if (source_buf == NULL) {
|
||||||
|
ESP_LOGE(TAG, "Initial alloc source_buf failed!");
|
||||||
|
}
|
||||||
|
printf("Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
|
||||||
|
|
||||||
|
download();
|
||||||
|
|
||||||
|
heap_caps_free(source_buf);
|
||||||
|
printf("Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
2
components/image_downloader/include/image_downloader.h
Normal file
2
components/image_downloader/include/image_downloader.h
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
void imgdwn();
|
||||||
|
#pragma once
|
||||||
@ -1,4 +1,5 @@
|
|||||||
|
|
||||||
|
#include "time.h"
|
||||||
|
|
||||||
struct node {
|
struct node {
|
||||||
struct node *next;
|
struct node *next;
|
||||||
@ -10,20 +11,32 @@ struct Hashtable {
|
|||||||
struct node *Cells;
|
struct node *Cells;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct forecast_temp{
|
struct dailyforecast_prev{
|
||||||
float min;
|
float min;
|
||||||
float max;
|
float max;
|
||||||
char desc[25];
|
char desc[25];
|
||||||
char icon[9];
|
char icon[9];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct forecast_prev{
|
||||||
|
float value;
|
||||||
|
char desc[25];
|
||||||
|
char icon[9];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct meteodailyforecast_data{
|
||||||
|
time_t datetime;
|
||||||
|
bool isValid;
|
||||||
|
struct dailyforecast_prev previsions;
|
||||||
|
};
|
||||||
|
|
||||||
struct meteoforecast_data{
|
struct meteoforecast_data{
|
||||||
time_t datetime;
|
time_t datetime;
|
||||||
bool isValid;
|
bool isValid;
|
||||||
struct forecast_temp previsions;
|
struct forecast_prev previsions;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*weather_data_callback)(struct meteoforecast_data *datas);
|
typedef void (*weather_data_callback)(struct meteodailyforecast_data *datas, struct meteoforecast_data *datasf);
|
||||||
typedef void (*weather_data_start_callback)();
|
typedef void (*weather_data_start_callback)();
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -35,8 +48,12 @@ typedef struct {
|
|||||||
weather_data_start_callback data_retreived_cb_start;
|
weather_data_start_callback data_retreived_cb_start;
|
||||||
} weather_data;
|
} weather_data;
|
||||||
|
|
||||||
void printftemp(struct forecast_temp *tmp);
|
void printdftemp(struct dailyforecast_prev *tmp);
|
||||||
void printffd(struct meteoforecast_data *tmp);
|
void printftemp(struct forecast_prev *tmp);
|
||||||
|
void printfdf(struct meteodailyforecast_data *tmp);
|
||||||
|
void dtToString(time_t, char *buffer);
|
||||||
|
void dtHToString(time_t, char *buffer);
|
||||||
|
void printff(struct meteoforecast_data *tmp);
|
||||||
|
|
||||||
void on_weather_data_retrieval(weather_data_callback data_retreived_cb);
|
void on_weather_data_retrieval(weather_data_callback data_retreived_cb);
|
||||||
void on_weather_data_retrieval_start(weather_data_callback data_retreived_cb);
|
void on_weather_data_retrieval_start(weather_data_callback data_retreived_cb);
|
||||||
|
|||||||
@ -40,16 +40,48 @@ static const char* TAG = "MeteoFrance";
|
|||||||
#define MAX_HTTP_OUTPUT_BUFFER 32000
|
#define MAX_HTTP_OUTPUT_BUFFER 32000
|
||||||
|
|
||||||
static weather_data weather;
|
static weather_data weather;
|
||||||
static struct meteoforecast_data datas[5];
|
static struct meteodailyforecast_data dailydatas[5];
|
||||||
|
static struct meteoforecast_data forecastdatas[5];
|
||||||
|
|
||||||
inline int MIN(int a, int b) { return a > b ? b : a; }
|
inline int MIN(int a, int b) { return a > b ? b : a; }
|
||||||
|
|
||||||
void printftemp(struct forecast_temp *tmp){
|
void printdftemp(struct dailyforecast_prev *tmp)
|
||||||
|
{
|
||||||
printf(" Temps Min:%f, Max:%f", tmp->min, tmp->max);
|
printf(" Temps Min:%f, Max:%f", tmp->min, tmp->max);
|
||||||
}
|
}
|
||||||
|
void printftemp(struct forecast_prev *tmp)
|
||||||
|
{
|
||||||
|
printf(" Temps Value:%f", tmp->value);
|
||||||
|
}
|
||||||
#define MAX_SIZE 80
|
#define MAX_SIZE 80
|
||||||
|
|
||||||
void printffd(struct meteoforecast_data *tmp){
|
void printfdf(struct meteodailyforecast_data *tmp)
|
||||||
|
{
|
||||||
|
char buffer[MAX_SIZE];
|
||||||
|
time_t timeToTransform = tmp->datetime;
|
||||||
|
dtToString(timeToTransform,buffer);
|
||||||
|
//ESP_LOGE(TAG, "%s", strftime_buf);
|
||||||
|
printf("IsValid:%s date:%s, Min:%.1f Max:%.1f Desc:%s Icon: %s\n", tmp->isValid ? "true" : "false", buffer, tmp->previsions.min, tmp->previsions.max, tmp->previsions.desc, tmp->previsions.icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dtToString(time_t ttt, char* buffer){
|
||||||
|
struct tm timeinfo = {0};
|
||||||
|
localtime_r(&ttt, &timeinfo);
|
||||||
|
strftime(buffer, MAX_SIZE, "%d/%m", &timeinfo);
|
||||||
|
//char strftime_buf[64];
|
||||||
|
//sprintf(strftime_buf, "%d %d %d", timeinfo.tm_wday, timeinfo.tm_mday, timeinfo.tm_mon + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dtHToString(time_t ttt, char* buffer){
|
||||||
|
struct tm timeinfo = {0};
|
||||||
|
localtime_r(&ttt, &timeinfo);
|
||||||
|
strftime(buffer, MAX_SIZE, "%H:%M", &timeinfo);
|
||||||
|
//char strftime_buf[64];
|
||||||
|
//sprintf(strftime_buf, "%d %d %d", timeinfo.tm_wday, timeinfo.tm_mday, timeinfo.tm_mon + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printff(struct meteoforecast_data *tmp)
|
||||||
|
{
|
||||||
struct tm timeinfo = {0};
|
struct tm timeinfo = {0};
|
||||||
localtime_r(&tmp->datetime, &timeinfo);
|
localtime_r(&tmp->datetime, &timeinfo);
|
||||||
char buffer[MAX_SIZE];
|
char buffer[MAX_SIZE];
|
||||||
@ -57,14 +89,15 @@ void printffd(struct meteoforecast_data *tmp){
|
|||||||
char strftime_buf[64];
|
char strftime_buf[64];
|
||||||
sprintf(strftime_buf, "%d %d %d", timeinfo.tm_wday, timeinfo.tm_mday, timeinfo.tm_mon + 1);
|
sprintf(strftime_buf, "%d %d %d", timeinfo.tm_wday, timeinfo.tm_mday, timeinfo.tm_mon + 1);
|
||||||
ESP_LOGE(TAG, "%s", strftime_buf);
|
ESP_LOGE(TAG, "%s", strftime_buf);
|
||||||
printf("IsValid:%s date:%s, Min:%.1f Max:%.1f Desc:%s\n", tmp->isValid ?"true":"false", buffer, tmp->previsions.min, tmp->previsions.max, tmp->previsions.desc);
|
printf("IsValid:%s date:%s, Temp:%.1f Desc:%s\n", tmp->isValid ? "true" : "false", buffer, tmp->previsions.value, tmp->previsions.desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t _http_event_handler(esp_http_client_event_t *evt)
|
esp_err_t _http_event_handler(esp_http_client_event_t *evt)
|
||||||
{
|
{
|
||||||
static char *output_buffer; // Buffer to store response of http request from event handler
|
static char *output_buffer; // Buffer to store response of http request from event handler
|
||||||
static int output_len; // Stores number of bytes read
|
static int output_len; // Stores number of bytes read
|
||||||
switch(evt->event_id) {
|
switch (evt->event_id)
|
||||||
|
{
|
||||||
case HTTP_EVENT_ERROR:
|
case HTTP_EVENT_ERROR:
|
||||||
ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
|
ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
|
||||||
break;
|
break;
|
||||||
@ -80,7 +113,8 @@ esp_err_t _http_event_handler(esp_http_client_event_t *evt)
|
|||||||
case HTTP_EVENT_ON_DATA:
|
case HTTP_EVENT_ON_DATA:
|
||||||
ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
|
ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
|
||||||
// Clean the buffer in case of a new request
|
// Clean the buffer in case of a new request
|
||||||
if (output_len == 0 && evt->user_data) {
|
if (output_len == 0 && evt->user_data)
|
||||||
|
{
|
||||||
// we are just starting to copy the output data into the use
|
// we are just starting to copy the output data into the use
|
||||||
memset(evt->user_data, 0, MAX_HTTP_OUTPUT_BUFFER);
|
memset(evt->user_data, 0, MAX_HTTP_OUTPUT_BUFFER);
|
||||||
}
|
}
|
||||||
@ -88,28 +122,36 @@ esp_err_t _http_event_handler(esp_http_client_event_t *evt)
|
|||||||
* Check for chunked encoding is added as the URL for chunked encoding used in this example returns binary data.
|
* Check for chunked encoding is added as the URL for chunked encoding used in this example returns binary data.
|
||||||
* However, event handler can also be used in case chunked encoding is used.
|
* However, event handler can also be used in case chunked encoding is used.
|
||||||
*/
|
*/
|
||||||
if (!esp_http_client_is_chunked_response(evt->client)) {
|
if (!esp_http_client_is_chunked_response(evt->client))
|
||||||
|
{
|
||||||
// If user_data buffer is configured, copy the response into the buffer
|
// If user_data buffer is configured, copy the response into the buffer
|
||||||
int copy_len = 0;
|
int copy_len = 0;
|
||||||
if (evt->user_data) {
|
if (evt->user_data)
|
||||||
|
{
|
||||||
// The last byte in evt->user_data is kept for the NULL character in case of out-of-bound access.
|
// The last byte in evt->user_data is kept for the NULL character in case of out-of-bound access.
|
||||||
copy_len = MIN(evt->data_len, (MAX_HTTP_OUTPUT_BUFFER - output_len));
|
copy_len = MIN(evt->data_len, (MAX_HTTP_OUTPUT_BUFFER - output_len));
|
||||||
if (copy_len) {
|
if (copy_len)
|
||||||
|
{
|
||||||
memcpy(evt->user_data + output_len, evt->data, copy_len);
|
memcpy(evt->user_data + output_len, evt->data, copy_len);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
int content_len = esp_http_client_get_content_length(evt->client);
|
int content_len = esp_http_client_get_content_length(evt->client);
|
||||||
if (output_buffer == NULL) {
|
if (output_buffer == NULL)
|
||||||
|
{
|
||||||
// We initialize output_buffer with 0 because it is used by strlen() and similar functions therefore should be null terminated.
|
// We initialize output_buffer with 0 because it is used by strlen() and similar functions therefore should be null terminated.
|
||||||
output_buffer = (char *)calloc(content_len + 1, sizeof(char));
|
output_buffer = (char *)calloc(content_len + 1, sizeof(char));
|
||||||
output_len = 0;
|
output_len = 0;
|
||||||
if (output_buffer == NULL) {
|
if (output_buffer == NULL)
|
||||||
|
{
|
||||||
ESP_LOGE(TAG, "Failed to allocate memory for output buffer");
|
ESP_LOGE(TAG, "Failed to allocate memory for output buffer");
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
copy_len = MIN(evt->data_len, (content_len - output_len));
|
copy_len = MIN(evt->data_len, (content_len - output_len));
|
||||||
if (copy_len) {
|
if (copy_len)
|
||||||
|
{
|
||||||
memcpy(output_buffer + output_len, evt->data, copy_len);
|
memcpy(output_buffer + output_len, evt->data, copy_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,7 +161,8 @@ esp_err_t _http_event_handler(esp_http_client_event_t *evt)
|
|||||||
break;
|
break;
|
||||||
case HTTP_EVENT_ON_FINISH:
|
case HTTP_EVENT_ON_FINISH:
|
||||||
ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
|
ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
|
||||||
if (output_buffer != NULL) {
|
if (output_buffer != NULL)
|
||||||
|
{
|
||||||
// Response is accumulated in output_buffer. Uncomment the below line to print the accumulated response
|
// Response is accumulated in output_buffer. Uncomment the below line to print the accumulated response
|
||||||
// ESP_LOG_BUFFER_HEX(TAG, output_buffer, output_len);
|
// ESP_LOG_BUFFER_HEX(TAG, output_buffer, output_len);
|
||||||
free(output_buffer);
|
free(output_buffer);
|
||||||
@ -131,11 +174,13 @@ esp_err_t _http_event_handler(esp_http_client_event_t *evt)
|
|||||||
ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");
|
ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");
|
||||||
int mbedtls_err = 0;
|
int mbedtls_err = 0;
|
||||||
esp_err_t err = esp_tls_get_and_clear_last_error((esp_tls_error_handle_t)evt->data, &mbedtls_err, NULL);
|
esp_err_t err = esp_tls_get_and_clear_last_error((esp_tls_error_handle_t)evt->data, &mbedtls_err, NULL);
|
||||||
if (err != 0) {
|
if (err != 0)
|
||||||
|
{
|
||||||
ESP_LOGI(TAG, "Last esp error code: 0x%x", err);
|
ESP_LOGI(TAG, "Last esp error code: 0x%x", err);
|
||||||
ESP_LOGI(TAG, "Last mbedtls failure: 0x%x", mbedtls_err);
|
ESP_LOGI(TAG, "Last mbedtls failure: 0x%x", mbedtls_err);
|
||||||
}
|
}
|
||||||
if (output_buffer != NULL) {
|
if (output_buffer != NULL)
|
||||||
|
{
|
||||||
free(output_buffer);
|
free(output_buffer);
|
||||||
output_buffer = NULL;
|
output_buffer = NULL;
|
||||||
}
|
}
|
||||||
@ -151,34 +196,52 @@ esp_err_t _http_event_handler(esp_http_client_event_t *evt)
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *JSON_Types(int type) {
|
char *JSON_Types(int type)
|
||||||
if (type == cJSON_Invalid) return ("cJSON_Invalid");
|
{
|
||||||
if (type == cJSON_False) return ("cJSON_False");
|
if (type == cJSON_Invalid)
|
||||||
if (type == cJSON_True) return ("cJSON_True");
|
return ("cJSON_Invalid");
|
||||||
if (type == cJSON_NULL) return ("cJSON_NULL");
|
if (type == cJSON_False)
|
||||||
if (type == cJSON_Number) return ("cJSON_Number");
|
return ("cJSON_False");
|
||||||
if (type == cJSON_String) return ("cJSON_String");
|
if (type == cJSON_True)
|
||||||
if (type == cJSON_Array) return ("cJSON_Array");
|
return ("cJSON_True");
|
||||||
if (type == cJSON_Object) return ("cJSON_Object");
|
if (type == cJSON_NULL)
|
||||||
if (type == cJSON_Raw) return ("cJSON_Raw");
|
return ("cJSON_NULL");
|
||||||
|
if (type == cJSON_Number)
|
||||||
|
return ("cJSON_Number");
|
||||||
|
if (type == cJSON_String)
|
||||||
|
return ("cJSON_String");
|
||||||
|
if (type == cJSON_Array)
|
||||||
|
return ("cJSON_Array");
|
||||||
|
if (type == cJSON_Object)
|
||||||
|
return ("cJSON_Object");
|
||||||
|
if (type == cJSON_Raw)
|
||||||
|
return ("cJSON_Raw");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JSON_Parse(const cJSON * const root) {
|
void JSON_Parse(const cJSON *const root)
|
||||||
|
{
|
||||||
// ESP_LOGI(TAG, "root->type=%s", JSON_Types(root->type));
|
// ESP_LOGI(TAG, "root->type=%s", JSON_Types(root->type));
|
||||||
cJSON *current_element = NULL;
|
cJSON *current_element = NULL;
|
||||||
// ESP_LOGI(TAG, "roo->child=%p", root->child);
|
// ESP_LOGI(TAG, "roo->child=%p", root->child);
|
||||||
// ESP_LOGI(TAG, "roo->next =%p", root->next);
|
// ESP_LOGI(TAG, "roo->next =%p", root->next);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
// Récupération previsions journalieres (15j par défaut mais on en récupere 3)
|
||||||
cJSON *df = cJSON_GetObjectItem(root, "daily_forecast");
|
cJSON *df = cJSON_GetObjectItem(root, "daily_forecast");
|
||||||
if(!cJSON_IsArray(df)){
|
if (!cJSON_IsArray(df))
|
||||||
|
{
|
||||||
ESP_LOGE(TAG, "Pas de tableau ^^");
|
ESP_LOGE(TAG, "Pas de tableau ^^");
|
||||||
}else{
|
}
|
||||||
cJSON_ArrayForEach(current_element, df) {
|
else
|
||||||
struct meteoforecast_data datasT;
|
{
|
||||||
|
cJSON_ArrayForEach(current_element, df)
|
||||||
|
{
|
||||||
|
struct meteodailyforecast_data datasT;
|
||||||
// ESP_LOGI(TAG, "type=%s", JSON_Types(current_element->type));
|
// ESP_LOGI(TAG, "type=%s", JSON_Types(current_element->type));
|
||||||
cJSON *dt = cJSON_GetObjectItem(current_element, "dt");
|
cJSON *dt = cJSON_GetObjectItem(current_element, "dt");
|
||||||
if(cJSON_IsNumber(dt)){
|
if (cJSON_IsNumber(dt))
|
||||||
|
{
|
||||||
datasT.datetime = dt->valueint;
|
datasT.datetime = dt->valueint;
|
||||||
cJSON *temps = cJSON_GetObjectItem(current_element, "T");
|
cJSON *temps = cJSON_GetObjectItem(current_element, "T");
|
||||||
datasT.previsions.min = cJSON_GetObjectItem(temps, "min")->valuedouble;
|
datasT.previsions.min = cJSON_GetObjectItem(temps, "min")->valuedouble;
|
||||||
@ -190,12 +253,59 @@ void JSON_Parse(const cJSON * const root) {
|
|||||||
datasT.isValid = true;
|
datasT.isValid = true;
|
||||||
// ESP_LOGE(TAG,"Donnees lues");
|
// ESP_LOGE(TAG,"Donnees lues");
|
||||||
// printffd(&datasT);
|
// printffd(&datasT);
|
||||||
datas[i++]=datasT;
|
dailydatas[i++] = datasT;
|
||||||
if(i==3){break;}
|
if (i == 3)
|
||||||
|
{
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Récupération previsions du jour ("matin/midi/am/soir")
|
||||||
|
cJSON *fore = cJSON_GetObjectItem(root, "forecast");
|
||||||
|
if(!cJSON_IsArray(fore)){
|
||||||
|
ESP_LOGE(TAG, "Pas de tableau forecast");
|
||||||
|
}else{
|
||||||
|
i=0;
|
||||||
|
//On garde les données de 10h 14h 18h
|
||||||
|
cJSON_ArrayForEach(current_element, fore){
|
||||||
|
struct meteoforecast_data datasT;
|
||||||
|
cJSON *dt = cJSON_GetObjectItem(current_element, "dt");
|
||||||
|
if (cJSON_IsNumber(dt))
|
||||||
|
{
|
||||||
|
datasT.datetime = dt->valueint;
|
||||||
|
struct tm timeinfo = {0};
|
||||||
|
localtime_r(&(datasT.datetime), &timeinfo);
|
||||||
|
if(timeinfo.tm_hour==10 || timeinfo.tm_hour==14 || timeinfo.tm_hour==18){
|
||||||
|
cJSON *temps = cJSON_GetObjectItem(current_element, "T");
|
||||||
|
datasT.previsions.value = cJSON_GetObjectItem(temps, "value")->valuedouble;
|
||||||
|
cJSON *weather = cJSON_GetObjectItem(current_element, "weather");
|
||||||
|
strncpy(datasT.previsions.desc, cJSON_GetObjectItem(weather, "desc")->valuestring, 24);
|
||||||
|
strncpy(datasT.previsions.icon, cJSON_GetObjectItem(weather, "icon")->valuestring, 8);
|
||||||
|
datasT.isValid = true;
|
||||||
|
// ESP_LOGE(TAG,"Donnees lues");
|
||||||
|
// printffd(&datasT);
|
||||||
|
forecastdatas[i++] = datasT;
|
||||||
|
printff(&datasT);
|
||||||
|
if (i == 3)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
//ESP_LOGE(TAG,"heure = %i on ne garde pas...", timeinfo.tm_hour);
|
||||||
|
//char buffer[MAX_SIZE];
|
||||||
|
//strftime(buffer, MAX_SIZE, "%c", &timeinfo);
|
||||||
|
//printf("date:%s %lli", buffer, datasT.datetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
ESP_LOGI(TAG,"dt n'est pas au format attendu ^^");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ESP_LOGI(TAG, "Prévisions lues !");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool process_response_body(const char *body)
|
static bool process_response_body(const char *body)
|
||||||
{
|
{
|
||||||
@ -205,10 +315,10 @@ static bool process_response_body(const char * body)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void http_request_task(void *pvParameter)
|
static void http_request_task(void *pvParameter)
|
||||||
{
|
{
|
||||||
while(1) {
|
while (1)
|
||||||
|
{
|
||||||
ESP_LOGE(TAG, "Début recup méteo --------------------------");
|
ESP_LOGE(TAG, "Début recup méteo --------------------------");
|
||||||
weather.data_retreived_cb_start(NULL);
|
weather.data_retreived_cb_start(NULL);
|
||||||
char *local_response_buffer = heap_caps_malloc((MAX_HTTP_OUTPUT_BUFFER + 1) * (sizeof(char)), MALLOC_CAP_SPIRAM);
|
char *local_response_buffer = heap_caps_malloc((MAX_HTTP_OUTPUT_BUFFER + 1) * (sizeof(char)), MALLOC_CAP_SPIRAM);
|
||||||
@ -236,17 +346,21 @@ static void http_request_task(void *pvParameter)
|
|||||||
|
|
||||||
// GET
|
// GET
|
||||||
esp_err_t err = esp_http_client_perform(client);
|
esp_err_t err = esp_http_client_perform(client);
|
||||||
if (err == ESP_OK) {
|
if (err == ESP_OK)
|
||||||
|
{
|
||||||
ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %" PRId64,
|
ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %" PRId64,
|
||||||
esp_http_client_get_status_code(client),
|
esp_http_client_get_status_code(client),
|
||||||
esp_http_client_get_content_length(client));
|
esp_http_client_get_content_length(client));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));
|
ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));
|
||||||
}
|
}
|
||||||
// ESP_LOGE(TAG, "%s",local_response_buffer);
|
// ESP_LOGE(TAG, "%s",local_response_buffer);
|
||||||
|
|
||||||
process_response_body(local_response_buffer);
|
process_response_body(local_response_buffer);
|
||||||
weather.data_retreived_cb(datas);
|
weather.data_retreived_cb(dailydatas, forecastdatas);
|
||||||
|
heap_caps_free(local_response_buffer);
|
||||||
esp_http_client_cleanup(client);
|
esp_http_client_cleanup(client);
|
||||||
|
|
||||||
// http_client_request(&http_client, WEB_SERVER, get_request);
|
// http_client_request(&http_client, WEB_SERVER, get_request);
|
||||||
@ -270,6 +384,10 @@ void initialise_weather_data_retrieval(unsigned long retreival_period)
|
|||||||
|
|
||||||
// http_client_on_process_chunk(&http_client, process_chunk);
|
// http_client_on_process_chunk(&http_client, process_chunk);
|
||||||
// http_client_on_disconnected(&http_client, disconnected);
|
// http_client_on_disconnected(&http_client, disconnected);
|
||||||
xTaskCreate(&http_request_task, "http_request_task", 10 * 2048, NULL, 5, NULL);
|
TaskHandle_t xHandle = NULL;
|
||||||
|
BaseType_t ret1 = xTaskCreate(&http_request_task, "http_request_task", 8 * 1024, NULL, 5, &xHandle);
|
||||||
|
if(ret1!=pdPASS ){
|
||||||
|
ESP_LOGE(TAG, "Impossible de creer la tache %i", ret1);
|
||||||
|
}
|
||||||
ESP_LOGI(TAG, "HTTP request task started");
|
ESP_LOGI(TAG, "HTTP request task started");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,29 +1,59 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
espressif/esp_lcd_touch:
|
espressif/esp_lcd_touch:
|
||||||
component_hash: 779b4ba2464a3ae85681e4b860caa5fdc35801458c23f3039ee761bae7f442a4
|
component_hash: 779b4ba2464a3ae85681e4b860caa5fdc35801458c23f3039ee761bae7f442a4
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=4.4.2'
|
||||||
source:
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
type: service
|
type: service
|
||||||
version: 1.1.2
|
version: 1.1.2
|
||||||
espressif/esp_lcd_touch_gt911:
|
espressif/esp_lcd_touch_gt911:
|
||||||
component_hash: 664c544533b91497f29b41e045bb4374a0d4d002f9d8c67c7c1bf43fb4179e3f
|
component_hash: f90c3f82f052d1ccdfd71895a062f396ccc1c90ec69d8a99c483180387230bac
|
||||||
|
dependencies:
|
||||||
|
- name: espressif/esp_lcd_touch
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
|
require: public
|
||||||
|
version: ^1.1.0
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=4.4.2'
|
||||||
source:
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
type: service
|
type: service
|
||||||
version: 1.1.1
|
version: 1.1.1~1
|
||||||
espressif/esp_lvgl_port:
|
espressif/esp_lvgl_port:
|
||||||
component_hash: 531c0525b5a5d6c05c45a147baa0626209aea6b6c0e01a7af7e6bf151878d056
|
component_hash: 8bcec6b1144750343ce7e411a7a1057a75a6348d3edc137bd5792ccba7f6c270
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
require: private
|
||||||
|
version: '>=4.4'
|
||||||
|
- name: lvgl/lvgl
|
||||||
|
registry_url: https://components.espressif.com
|
||||||
|
require: public
|
||||||
|
version: '>=8,<10'
|
||||||
source:
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
type: service
|
type: service
|
||||||
version: 2.2.2
|
version: 2.3.2
|
||||||
idf:
|
idf:
|
||||||
component_hash: null
|
|
||||||
source:
|
source:
|
||||||
type: idf
|
type: idf
|
||||||
version: 5.1.4
|
version: 5.3.1
|
||||||
lvgl/lvgl:
|
lvgl/lvgl:
|
||||||
component_hash: 2a8f619b5c2b1c7ad116c33d43dae8989c76739068f406a7e8ba9221e1085f17
|
component_hash: 2409fdc84e9766d2a18afd84b051aef3f838348136cdb1c10ac2e8bcdb012bf6
|
||||||
|
dependencies: []
|
||||||
source:
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
type: service
|
type: service
|
||||||
version: 9.1.0
|
version: 9.2.0
|
||||||
manifest_hash: 00b1178407be665595f229a4c10495a43316f71ef19242ff89f82944e383f982
|
direct_dependencies:
|
||||||
|
- espressif/esp_lcd_touch_gt911
|
||||||
|
- espressif/esp_lvgl_port
|
||||||
|
- idf
|
||||||
|
- lvgl/lvgl
|
||||||
|
manifest_hash: b5600105e7af98260d4afd2580596fd962c4f216e9d70b5059131b98ee207d7d
|
||||||
target: esp32s3
|
target: esp32s3
|
||||||
version: 1.0.0
|
version: 2.0.0
|
||||||
|
|||||||
6
gdbinit
Normal file
6
gdbinit
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
target remote :3333
|
||||||
|
set remote hardware-watchpoint-limit 2
|
||||||
|
mon reset halt
|
||||||
|
maintenance flush register-cache
|
||||||
|
thb app_main
|
||||||
|
c
|
||||||
18
heaptrace-gdbinit
Normal file
18
heaptrace-gdbinit
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
set pagination off
|
||||||
|
target remote :3333
|
||||||
|
|
||||||
|
mon reset halt
|
||||||
|
flushregs
|
||||||
|
|
||||||
|
tb heap_trace_start
|
||||||
|
commands
|
||||||
|
mon esp sysview start file://c:/marc/Projects/IDF/rgb_lcd/trace/htrace_1729789901521.svdat
|
||||||
|
c
|
||||||
|
end
|
||||||
|
|
||||||
|
tb heap_trace_stop
|
||||||
|
commands
|
||||||
|
mon esp sysview stop
|
||||||
|
end
|
||||||
|
|
||||||
|
c
|
||||||
@ -1,75 +1,76 @@
|
|||||||
idf_component_register(SRC_DIRS . fonts
|
idf_component_register(SRC_DIRS . fonts
|
||||||
INCLUDE_DIRS "."
|
INCLUDE_DIRS "."
|
||||||
REQUIRES esp_wifi nvs_flash mqtt meteofrance esp_netif)
|
REQUIRES heap esp_wifi nvs_flash mqtt meteofrance esp_netif image_downloader)
|
||||||
lvgl_port_create_c_image("images/esp_logo.png" "images/" "ARGB8888" "NONE")
|
lvgl_port_create_c_image("images/p13bisj.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p10j.png" "images/" "ARGB8888" "NONE")
|
#lvgl_port_create_c_image("images/esp_logo.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p10n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p10j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p11j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p10n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p11n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p11j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p12j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p11n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p12bisj.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p12j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p12n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p12bisj.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p13j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p12n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p13n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p13j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p14bisj.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p13n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p14j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p14bisj.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p14n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p14j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p15j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p14n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p15n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p15j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p16bisj.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p15n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p16j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p16bisj.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p16n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p16j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p17j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p16n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p17n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p17j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p18j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p17n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p18n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p18j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p19j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p18n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p19n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p19j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p1j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p19n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p1n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p1j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p20j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p1n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p20n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p20j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p21j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p20n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p21n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p21j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p22j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p21n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p22n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p22j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p23j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p22n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p23n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p23j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p24j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p23n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p24n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p24j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p25j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p24n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p25n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p25j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p26j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p25n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p26n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p26j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p27j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p26n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p27n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p27j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p28j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p27n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p28n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p28j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p29j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p28n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p29n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p29j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p2j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p29n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p2n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p2j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p30j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p2n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p30n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p30j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p31j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p30n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p31n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p31j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p32j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p31n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p32n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p32j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p3j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p32n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p3n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p3j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p4j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p3n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p4n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p4j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p5bisj.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p4n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p5j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p5bisj.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p5n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p5j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p6j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p5n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p6n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p6j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p7j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p6n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p7n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p7j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p8j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p7n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p8n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p8j.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p9j.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p8n.png" "images/" "ARGB8888" "NONE")
|
||||||
lvgl_port_create_c_image("images/p9n.png" "images/" "ARGB8888" "NONE")
|
# lvgl_port_create_c_image("images/p9j.png" "images/" "ARGB8888" "NONE")
|
||||||
|
# lvgl_port_create_c_image("images/p9n.png" "images/" "ARGB8888" "NONE")
|
||||||
|
|
||||||
lvgl_port_add_images(${COMPONENT_LIB} "images/")
|
lvgl_port_add_images(${COMPONENT_LIB} "images/")
|
||||||
|
|
||||||
|
|||||||
18
main/fatfs.c
Normal file
18
main/fatfs.c
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* @file lv_fs_fatfs.c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* INCLUDES
|
||||||
|
*********************/
|
||||||
|
#include "ff.h"
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* DEFINES
|
||||||
|
*********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* TYPEDEFS
|
||||||
|
**********************/
|
||||||
|
|
||||||
2
main/fatfs.h
Normal file
2
main/fatfs.h
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
void my_fatfs_init(void);
|
||||||
|
#pragma once
|
||||||
@ -2,6 +2,8 @@ dependencies:
|
|||||||
esp_lcd_touch_gt911:
|
esp_lcd_touch_gt911:
|
||||||
version: ^1
|
version: ^1
|
||||||
esp_lvgl_port:
|
esp_lvgl_port:
|
||||||
version: '*'
|
version: 2.3.2
|
||||||
idf:
|
idf:
|
||||||
version: '>=5.0'
|
version: '>=5.0'
|
||||||
|
lvgl/lvgl:
|
||||||
|
version: 9.2.0
|
||||||
BIN
main/images/p13bisj.png
Normal file
BIN
main/images/p13bisj.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
83
main/include/fmeteod.h
Normal file
83
main/include/fmeteod.h
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
static void weatherdata_obs_cb(lv_observer_t *observer, lv_subject_t *subject)
|
||||||
|
{
|
||||||
|
// Retrieve weatherdata
|
||||||
|
struct meteodailyforecast_data *data = subject->value.pointer;
|
||||||
|
//printffd(data);
|
||||||
|
char buff[40] = {};
|
||||||
|
// sprintf(buff,"%s %.1f %.1f", data->previsions.desc, data->previsions.min, data->previsions.max);
|
||||||
|
|
||||||
|
lv_obj_t *parent = (lv_obj_t *)(observer->target);
|
||||||
|
lv_obj_t *datefld = lv_obj_get_child(parent, 0);
|
||||||
|
lv_obj_t *desc_icon = lv_obj_get_child(parent, 1);
|
||||||
|
lv_obj_t *temps = lv_obj_get_child(parent, 2);
|
||||||
|
if (strcmp(data->previsions.icon, "p1j") == 0)
|
||||||
|
{
|
||||||
|
lv_image_set_src(lv_obj_get_child(desc_icon, 0), &p1j);
|
||||||
|
}else if (strcmp(data->previsions.icon, "p2j") == 0)
|
||||||
|
{
|
||||||
|
lv_image_set_src(lv_obj_get_child(desc_icon, 0), &p2j);
|
||||||
|
}else if (strcmp(data->previsions.icon, "p3j") == 0)
|
||||||
|
{
|
||||||
|
lv_image_set_src(lv_obj_get_child(desc_icon, 0), &p3j);
|
||||||
|
}else if (strcmp(data->previsions.icon, "p5bisj") == 0)
|
||||||
|
{
|
||||||
|
lv_image_set_src(lv_obj_get_child(desc_icon, 0), &p5bisj);
|
||||||
|
}else if (strcmp(data->previsions.icon, "p12j") == 0)
|
||||||
|
{
|
||||||
|
lv_image_set_src(lv_obj_get_child(desc_icon, 0), &p12j);
|
||||||
|
}else if (strcmp(data->previsions.icon, "p12bisj") == 0)
|
||||||
|
{
|
||||||
|
lv_image_set_src(lv_obj_get_child(desc_icon, 0), &p12bisj);
|
||||||
|
}else if (strcmp(data->previsions.icon, "p14j") == 0)
|
||||||
|
{
|
||||||
|
lv_image_set_src(lv_obj_get_child(desc_icon, 0), &p14j);
|
||||||
|
}else if (strcmp(data->previsions.icon, "p24j") == 0)
|
||||||
|
{
|
||||||
|
lv_image_set_src(lv_obj_get_child(desc_icon, 0), &p24j);
|
||||||
|
}else if (strcmp(data->previsions.icon, "p25j") == 0)
|
||||||
|
{
|
||||||
|
lv_image_set_src(lv_obj_get_child(desc_icon, 0), &p25j);
|
||||||
|
}else if (strcmp(data->previsions.icon, "p26j") == 0)
|
||||||
|
{
|
||||||
|
lv_image_set_src(lv_obj_get_child(desc_icon, 0), &p26j);
|
||||||
|
}else if (strcmp(data->previsions.icon, "p27j") == 0)
|
||||||
|
{
|
||||||
|
lv_image_set_src(lv_obj_get_child(desc_icon, 0), &p27j);
|
||||||
|
}else if (strcmp(data->previsions.icon, "p28j") == 0)
|
||||||
|
{
|
||||||
|
lv_image_set_src(lv_obj_get_child(desc_icon, 0), &p28j);
|
||||||
|
}else if (strcmp(data->previsions.icon, "p29j") == 0)
|
||||||
|
{
|
||||||
|
lv_image_set_src(lv_obj_get_child(desc_icon, 0), &p29j);
|
||||||
|
}else{
|
||||||
|
ESP_LOGE(TAG, "Image %s non connue",data->previsions.icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
char buffer[80];
|
||||||
|
dtToString(data->datetime,buffer);
|
||||||
|
|
||||||
|
lv_label_set_text(datefld, buffer);
|
||||||
|
lv_label_set_text(lv_obj_get_child(desc_icon, 1), data->previsions.desc);
|
||||||
|
lv_label_set_text_fmt(lv_obj_get_child(temps, 0), "%.1f°C", data->previsions.max);
|
||||||
|
lv_label_set_text_fmt(lv_obj_get_child(temps, 1), "%.1f°C", data->previsions.min);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct weatherDay_fragment_t
|
||||||
|
{
|
||||||
|
/* IMPORTANT: don't miss this part */
|
||||||
|
lv_fragment_t base;
|
||||||
|
/* States, object references and data fields for this fragment */
|
||||||
|
int dayNr;
|
||||||
|
bool showTitle;
|
||||||
|
const char *title;
|
||||||
|
float minTemp;
|
||||||
|
float maxTemp;
|
||||||
|
};
|
||||||
|
static void weatherDay_fragment_ctor(lv_fragment_t *self, void * args)
|
||||||
|
{
|
||||||
|
int dayNo = ((int *)args)[0];
|
||||||
|
bool showDate = ((int*)args)[1];
|
||||||
|
((struct weatherDay_fragment_t *)self)->dayNr = dayNo;
|
||||||
|
((struct weatherDay_fragment_t *)self)->showTitle = showDate;
|
||||||
|
ESP_LOGI(TAG, "Fragment initialisé avec le jour n°%d - Afficher la date %d",dayNo, showDate);
|
||||||
|
}
|
||||||
1255
main/main.c
1255
main/main.c
File diff suppressed because it is too large
Load Diff
3
main/main.h
Normal file
3
main/main.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "mqtt_client.h"
|
||||||
|
static void showMeteoIcon(const char *icon, lv_obj_t *desc_icon, int childNr);
|
||||||
232
main/mqtt.c
Normal file
232
main/mqtt.c
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
#include "mqtt.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_lvgl_port.h"
|
||||||
|
#include "mqtt_client.h"
|
||||||
|
|
||||||
|
esp_mqtt_client_handle_t client;
|
||||||
|
extern lv_subject_t mqttStatus;
|
||||||
|
extern lv_subject_t tempIntSubj;
|
||||||
|
extern lv_subject_t tempExtSubj;
|
||||||
|
extern lv_subject_t hauteurCuveSubj;
|
||||||
|
extern lv_subject_t hauteurCuveEvolSubj;
|
||||||
|
|
||||||
|
static const char *TAG = "mqtt";
|
||||||
|
|
||||||
|
char *upEvent = "monter";
|
||||||
|
char *downEvent = "descendre";
|
||||||
|
|
||||||
|
char *topicTempExt = "house/temp/282A802600008059";
|
||||||
|
char *topicHauteurCuve = "house/cuve/hauteur";
|
||||||
|
char *topicTempInt = "house/temp/287DCF1E00008020";
|
||||||
|
char *topicHauteurCuveEvol = "house/cuve/hauteurEvol";
|
||||||
|
|
||||||
|
static void log_error_if_nonzero(const char *message, int error_code)
|
||||||
|
{
|
||||||
|
if (error_code != 0)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Last error %s: 0x%x", message, error_code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void splitIt(char *payload, unsigned int length, float *datas)
|
||||||
|
{
|
||||||
|
char *sep = ",";
|
||||||
|
char *token;
|
||||||
|
char *saveptr1;
|
||||||
|
|
||||||
|
token = strtok_r(payload, sep, &saveptr1);
|
||||||
|
datas[0] = atoff(token);
|
||||||
|
ESP_LOGE(TAG,"%f",datas[0]);
|
||||||
|
|
||||||
|
token = strtok_r(NULL, sep, &saveptr1);
|
||||||
|
datas[1] = atoff(token);
|
||||||
|
ESP_LOGE(TAG,"%f",datas[1]);
|
||||||
|
|
||||||
|
token = strtok_r(NULL, sep, &saveptr1);
|
||||||
|
datas[2] = atoff(token);
|
||||||
|
ESP_LOGE(TAG,"%f",datas[2]);
|
||||||
|
|
||||||
|
token = strtok_r(NULL, sep, &saveptr1);
|
||||||
|
datas[3] = atoff(token);
|
||||||
|
ESP_LOGE(TAG,"%f",datas[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief Event handler registered to receive MQTT events
|
||||||
|
*
|
||||||
|
* This function is called by the MQTT client event loop.
|
||||||
|
*
|
||||||
|
* @param handler_args user data registered to the event.
|
||||||
|
* @param base Event base for the handler(always MQTT Base in this example).
|
||||||
|
* @param event_id The id for the received event.
|
||||||
|
* @param event_data The data for the event, esp_mqtt_event_handle_t.
|
||||||
|
*/
|
||||||
|
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
|
||||||
|
{
|
||||||
|
ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%" PRIi32 "", base, event_id);
|
||||||
|
esp_mqtt_event_handle_t event = event_data;
|
||||||
|
esp_mqtt_client_handle_t client = event->client;
|
||||||
|
int msg_id;
|
||||||
|
switch ((esp_mqtt_event_id_t)event_id)
|
||||||
|
{
|
||||||
|
case MQTT_EVENT_CONNECTED:
|
||||||
|
if(lvgl_port_lock(0)){
|
||||||
|
ESP_LOGE(TAG,"Statut mqttStatus 1");
|
||||||
|
lv_subject_set_int(&mqttStatus,1);
|
||||||
|
lvgl_port_unlock();
|
||||||
|
}
|
||||||
|
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
|
||||||
|
//msg_id = esp_mqtt_client_publish(client, "/topic/qos1", "data_3", 0, 1, 0);
|
||||||
|
//ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||||
|
|
||||||
|
msg_id = esp_mqtt_client_subscribe(client, topicTempExt, 0);
|
||||||
|
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||||
|
|
||||||
|
msg_id = esp_mqtt_client_subscribe(client, topicTempInt, 0);
|
||||||
|
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||||
|
|
||||||
|
msg_id = esp_mqtt_client_subscribe(client, topicHauteurCuve, 0);
|
||||||
|
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||||
|
|
||||||
|
msg_id = esp_mqtt_client_subscribe(client, topicHauteurCuveEvol, 0);
|
||||||
|
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||||
|
|
||||||
|
//msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
|
||||||
|
//ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||||
|
|
||||||
|
//msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
|
||||||
|
//ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
|
||||||
|
break;
|
||||||
|
case MQTT_EVENT_DISCONNECTED:
|
||||||
|
if(lvgl_port_lock(0)){
|
||||||
|
ESP_LOGE(TAG,"Statut mqttStatus 0");
|
||||||
|
lv_subject_set_int(&mqttStatus,0);
|
||||||
|
lvgl_port_unlock();
|
||||||
|
}
|
||||||
|
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MQTT_EVENT_SUBSCRIBED:
|
||||||
|
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
|
||||||
|
//msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
|
||||||
|
//ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||||
|
break;
|
||||||
|
case MQTT_EVENT_UNSUBSCRIBED:
|
||||||
|
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||||
|
break;
|
||||||
|
case MQTT_EVENT_PUBLISHED:
|
||||||
|
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
|
||||||
|
break;
|
||||||
|
case MQTT_EVENT_DATA:
|
||||||
|
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
|
||||||
|
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
|
||||||
|
printf("DATA=%.*s\r\n", event->data_len, event->data);
|
||||||
|
if (strncmp(event->topic, topicTempExt, 27) == 0)
|
||||||
|
{
|
||||||
|
lvgl_port_lock(0);
|
||||||
|
// on retransforme en float pour ne garder que la partie entiere de la température
|
||||||
|
float temp = strtof(event->data, NULL);
|
||||||
|
char buff[5];
|
||||||
|
sprintf(buff,"%.1f",temp);
|
||||||
|
lv_subject_copy_string(&tempExtSubj, buff);
|
||||||
|
lvgl_port_unlock();
|
||||||
|
}
|
||||||
|
else if (strncmp(event->topic, topicTempInt, 27) == 0)
|
||||||
|
{
|
||||||
|
lvgl_port_lock(0);
|
||||||
|
// on retransforme en float pour ne garder que la partie entiere de la température
|
||||||
|
float temp = strtof(event->data, NULL);
|
||||||
|
char buff[5];
|
||||||
|
sprintf(buff,"%.1f",temp);
|
||||||
|
lv_subject_copy_string(&tempIntSubj, buff);
|
||||||
|
lvgl_port_unlock();
|
||||||
|
}
|
||||||
|
else if (strncmp(event->topic, topicHauteurCuveEvol, 22) == 0)
|
||||||
|
{
|
||||||
|
/* float datas[4] = {};
|
||||||
|
splitIt(event->data, event->data_len, datas);
|
||||||
|
ser1->y_points[0] = 130 - (int)datas[0];
|
||||||
|
ser1->y_points[1] = 130 - (int)datas[1];
|
||||||
|
ser1->y_points[2] = 130 - (int)datas[2];
|
||||||
|
ser1->y_points[3] = 130 - (int)datas[3];
|
||||||
|
lvgl_port_lock(0);
|
||||||
|
lv_chart_refresh(chart);
|
||||||
|
lvgl_port_unlock();
|
||||||
|
*/
|
||||||
|
|
||||||
|
// lv_subject_copy_string(&hauteurCuveEvolSubj, event->data);
|
||||||
|
}
|
||||||
|
else if (strncmp(event->topic, topicHauteurCuve, 18) == 0)
|
||||||
|
{
|
||||||
|
lvgl_port_lock(0);
|
||||||
|
char *datas = NULL;
|
||||||
|
datas = (char *)malloc(event->data_len * sizeof(char));
|
||||||
|
stpncpy(datas, event->data, event->data_len);
|
||||||
|
datas[event->data_len] = '\0';
|
||||||
|
lv_subject_copy_string(&hauteurCuveSubj, datas);
|
||||||
|
free(datas);
|
||||||
|
lvgl_port_unlock();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "None match :-(");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MQTT_EVENT_ERROR:
|
||||||
|
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
|
||||||
|
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT)
|
||||||
|
{
|
||||||
|
log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
|
||||||
|
log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
|
||||||
|
log_error_if_nonzero("captured as transport's socket errno", event->error_handle->esp_transport_sock_errno);
|
||||||
|
ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void mqtt_app_start(void)
|
||||||
|
{
|
||||||
|
esp_mqtt_client_config_t mqtt_cfg = {
|
||||||
|
.broker.address.uri = "mqtt://192.168.0.10",
|
||||||
|
.network.timeout_ms = 1000};
|
||||||
|
#if CONFIG_BROKER_URL_FROM_STDIN
|
||||||
|
char line[128];
|
||||||
|
|
||||||
|
if (strcmp(mqtt_cfg.broker.address.uri, "FROM_STDIN") == 0)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
printf("Please enter url of mqtt broker\n");
|
||||||
|
while (count < 128)
|
||||||
|
{
|
||||||
|
int c = fgetc(stdin);
|
||||||
|
if (c == '\n')
|
||||||
|
{
|
||||||
|
line[count] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (c > 0 && c < 127)
|
||||||
|
{
|
||||||
|
line[count] = c;
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||||
|
}
|
||||||
|
mqtt_cfg.broker.address.uri = line;
|
||||||
|
printf("Broker url: %s\n", line);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Configuration mismatch: wrong broker url");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BROKER_URL_FROM_STDIN */
|
||||||
|
|
||||||
|
client = esp_mqtt_client_init(&mqtt_cfg);
|
||||||
|
/* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
|
||||||
|
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
|
||||||
|
esp_mqtt_client_start(client);
|
||||||
|
}
|
||||||
|
|
||||||
3
main/mqtt.h
Normal file
3
main/mqtt.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
void mqtt_app_start(void);
|
||||||
32
main/obtain_time.c
Normal file
32
main/obtain_time.c
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_netif_sntp.h"
|
||||||
|
#include "esp_sntp.h"
|
||||||
|
#include "obtain_time.h"
|
||||||
|
|
||||||
|
static const char *TAG = "sntp";
|
||||||
|
|
||||||
|
void time_sync_notification_cb(struct timeval *tv)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Notification of a time synchronization event");
|
||||||
|
}
|
||||||
|
|
||||||
|
void obtain_time(void)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Initializing and starting SNTP");
|
||||||
|
esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG("pool.ntp.org");
|
||||||
|
config.sync_cb = time_sync_notification_cb; // Note: This is only needed if we want
|
||||||
|
esp_netif_sntp_init(&config);
|
||||||
|
|
||||||
|
// wait for time to be set
|
||||||
|
time_t now = 0;
|
||||||
|
struct tm timeinfo = { 0 };
|
||||||
|
int retry = 0;
|
||||||
|
const int retry_count = 15;
|
||||||
|
while (esp_netif_sntp_sync_wait(2000 / portTICK_PERIOD_MS) == ESP_ERR_TIMEOUT && ++retry < retry_count) {
|
||||||
|
ESP_LOGI(TAG, "Waiting for system time to be set... (%d/%d)", retry, retry_count);
|
||||||
|
}
|
||||||
|
time(&now);
|
||||||
|
localtime_r(&now, &timeinfo);
|
||||||
|
|
||||||
|
esp_netif_sntp_deinit();
|
||||||
|
}
|
||||||
2
main/obtain_time.h
Normal file
2
main/obtain_time.h
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
void obtain_time(void);
|
||||||
|
#pragma once
|
||||||
152
main/wifi.c
Normal file
152
main/wifi.c
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
#include "wifi.h"
|
||||||
|
#include "esp_wifi.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_lvgl_port.h"
|
||||||
|
|
||||||
|
/* FreeRTOS event group to signal when we are connected*/
|
||||||
|
static EventGroupHandle_t s_wifi_event_group;
|
||||||
|
|
||||||
|
/* The event group allows multiple bits for each event, but we only care about two events:
|
||||||
|
* - we are connected to the AP with an IP
|
||||||
|
* - we failed to connect after the maximum amount of retries */
|
||||||
|
#define WIFI_CONNECTED_BIT BIT0
|
||||||
|
#define WIFI_FAIL_BIT BIT1
|
||||||
|
|
||||||
|
#define EXAMPLE_ESP_WIFI_SSID "wifimms3"
|
||||||
|
#define EXAMPLE_ESP_WIFI_PASS "mmswifi0611"
|
||||||
|
#define EXAMPLE_ESP_MAXIMUM_RETRY 5
|
||||||
|
|
||||||
|
#define ESP_WIFI_SAE_MODE WPA3_SAE_PWE_BOTH
|
||||||
|
#define EXAMPLE_H2E_IDENTIFIER CONFIG_ESP_WIFI_PW_ID
|
||||||
|
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK
|
||||||
|
|
||||||
|
static const char *TAG = "wifi";
|
||||||
|
|
||||||
|
static int s_retry_num = 0;
|
||||||
|
|
||||||
|
extern lv_subject_t wifiStatus;
|
||||||
|
|
||||||
|
static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
|
||||||
|
{
|
||||||
|
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
|
||||||
|
{
|
||||||
|
esp_wifi_connect();
|
||||||
|
}
|
||||||
|
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
|
||||||
|
{
|
||||||
|
if(lvgl_port_lock(0)){
|
||||||
|
ESP_LOGE(TAG,"Statut Wifi 0");
|
||||||
|
lv_subject_set_int(&wifiStatus,0);
|
||||||
|
lvgl_port_unlock();
|
||||||
|
}
|
||||||
|
if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY)
|
||||||
|
{
|
||||||
|
esp_wifi_connect();
|
||||||
|
s_retry_num++;
|
||||||
|
ESP_LOGI(TAG, "retry to connect to the AP");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
|
||||||
|
}
|
||||||
|
ESP_LOGI(TAG, "connect to the AP fail");
|
||||||
|
}
|
||||||
|
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
|
||||||
|
{
|
||||||
|
if(lvgl_port_lock(0)){
|
||||||
|
ESP_LOGE(TAG,"Statut Wifi 1");
|
||||||
|
lv_subject_set_int(&wifiStatus,1);
|
||||||
|
lvgl_port_unlock();
|
||||||
|
}
|
||||||
|
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
|
||||||
|
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
|
||||||
|
s_retry_num = 0;
|
||||||
|
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void wifi_init_sta(void)
|
||||||
|
{
|
||||||
|
s_wifi_event_group = xEventGroupCreate();
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_netif_init());
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||||
|
esp_netif_create_default_wifi_sta();
|
||||||
|
|
||||||
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||||
|
|
||||||
|
esp_event_handler_instance_t instance_any_id;
|
||||||
|
esp_event_handler_instance_t instance_got_ip;
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
||||||
|
ESP_EVENT_ANY_ID,
|
||||||
|
&wifi_event_handler,
|
||||||
|
NULL,
|
||||||
|
&instance_any_id));
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
|
||||||
|
IP_EVENT_STA_GOT_IP,
|
||||||
|
&wifi_event_handler,
|
||||||
|
NULL,
|
||||||
|
&instance_got_ip));
|
||||||
|
|
||||||
|
wifi_config_t wifi_config = {
|
||||||
|
.sta = {
|
||||||
|
.ssid = EXAMPLE_ESP_WIFI_SSID,
|
||||||
|
.password = EXAMPLE_ESP_WIFI_PASS,
|
||||||
|
/* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (pasword len => 8).
|
||||||
|
* If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value
|
||||||
|
* to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to
|
||||||
|
* WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards.
|
||||||
|
*/
|
||||||
|
.threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD,
|
||||||
|
.sae_pwe_h2e = ESP_WIFI_SAE_MODE,
|
||||||
|
.sae_h2e_identifier = EXAMPLE_H2E_IDENTIFIER,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_start());
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "wifi_init_sta finished.");
|
||||||
|
|
||||||
|
/* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
|
||||||
|
* number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
|
||||||
|
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
|
||||||
|
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
|
||||||
|
pdFALSE,
|
||||||
|
pdFALSE,
|
||||||
|
portMAX_DELAY);
|
||||||
|
|
||||||
|
/* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
|
||||||
|
* happened. */
|
||||||
|
if (bits & WIFI_CONNECTED_BIT)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
|
||||||
|
EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
|
||||||
|
if(lvgl_port_lock(0)){
|
||||||
|
ESP_LOGE(TAG,"Statut Wifi 1");
|
||||||
|
lv_subject_set_int(&wifiStatus,1);
|
||||||
|
lvgl_port_unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (bits & WIFI_FAIL_BIT)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
|
||||||
|
EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
|
||||||
|
if(lvgl_port_lock(0)){
|
||||||
|
ESP_LOGE(TAG,"Statut Wifi 0");
|
||||||
|
lv_subject_set_int(&wifiStatus,0);
|
||||||
|
lvgl_port_unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "UNEXPECTED EVENT");
|
||||||
|
if(lvgl_port_lock(0)){
|
||||||
|
ESP_LOGE(TAG,"Statut Wifi 0");
|
||||||
|
lv_subject_set_int(&wifiStatus,0);
|
||||||
|
lvgl_port_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
2
main/wifi.h
Normal file
2
main/wifi.h
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#pragma once
|
||||||
|
void wifi_init_sta(void);
|
||||||
BIN
partition_table/partitionTable.bin
Normal file
BIN
partition_table/partitionTable.bin
Normal file
Binary file not shown.
9
partition_table/partitionTable.csv
Normal file
9
partition_table/partitionTable.csv
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# ESP-IDF Partition Table
|
||||||
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
|
nvs,data,nvs,0x9000,24K,
|
||||||
|
otadata,data,ota,0xf000,8K,
|
||||||
|
phy_init,data,phy,0x11000,4K,
|
||||||
|
factory,app,factory,0x20000,3M,
|
||||||
|
ota_0,app,ota_0,0x320000,3M,
|
||||||
|
ota_1,app,ota_1,0x620000,3M,
|
||||||
|
datas,data,spiffs,0x920000,1M,
|
||||||
|
5
partitions copy.csv
Normal file
5
partitions copy.csv
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
|
# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
|
||||||
|
nvs, data, nvs, 0x9000, 0x6000,
|
||||||
|
phy_init, data, phy, 0xf000, 0x1000,
|
||||||
|
factory, app, factory, 0x10000, 3M,
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
|
# ESP-IDF Partition Table
|
||||||
# Name, Type, SubType, Offset, Size, Flags
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
|
nvs,data,nvs,,0x6000,,
|
||||||
nvs, data, nvs, 0x9000, 0x6000,
|
otadata,data,ota,,0x2000,,
|
||||||
phy_init, data, phy, 0xf000, 0x1000,
|
phy_init,data,phy,,0x1000,,
|
||||||
factory, app, factory, 0x10000, 3M,
|
factory,app,factory,,3M,,
|
||||||
|
ota_0,app,ota_0,,3M,,
|
||||||
|
ota_1,app,ota_1,,3M,,
|
||||||
|
datas,data,spiffs,,1M,,
|
||||||
|
|||||||
|
@ -11,8 +11,6 @@ CONFIG_SPIRAM_SPEED_80M=y
|
|||||||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
|
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
|
||||||
CONFIG_ESP32S3_DATA_CACHE_LINE_64B=y
|
CONFIG_ESP32S3_DATA_CACHE_LINE_64B=y
|
||||||
CONFIG_FREERTOS_HZ=1000
|
CONFIG_FREERTOS_HZ=1000
|
||||||
CONFIG_LV_MEM_CUSTOM=y
|
|
||||||
CONFIG_LV_MEMCPY_MEMSET_STD=y
|
|
||||||
CONFIG_LV_ATTRIBUTE_FAST_MEM_USE_IRAM=y
|
CONFIG_LV_ATTRIBUTE_FAST_MEM_USE_IRAM=y
|
||||||
CONFIG_LV_FONT_MONTSERRAT_12=y
|
CONFIG_LV_FONT_MONTSERRAT_12=y
|
||||||
CONFIG_LV_FONT_MONTSERRAT_16=y
|
CONFIG_LV_FONT_MONTSERRAT_16=y
|
||||||
|
|||||||
604
sdkconfig.old
604
sdkconfig.old
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user