Updated IDF, connect to TB.

Signed-off-by: Yilin Sun <imi415@imi.moe>
This commit is contained in:
Yilin Sun 2023-05-21 18:43:13 +08:00
parent bc4499b02f
commit dfb86f939c
Signed by: imi415
GPG Key ID: 17F01E106F9F5E0A
23 changed files with 732 additions and 332 deletions

12
.clang-format Normal file
View File

@ -0,0 +1,12 @@
BasedOnStyle: Google
IndentWidth: 4
AlignConsecutiveMacros: Consecutive
AlignConsecutiveDeclarations: Consecutive
AlignConsecutiveAssignments: Consecutive
AllowShortFunctionsOnASingleLine: None
BreakBeforeBraces: Custom
BraceWrapping:
AfterEnum: false
AfterStruct: false
SplitEmptyFunction: false
ColumnLimit: 120

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
/assets/certs
/build
/cmake-build-*
/managed_components
/sdkconfig
/sdkconfig.old

View File

@ -4,7 +4,3 @@ cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(dht_temp)
# Add client certificate, private key and CA bundle to project:
target_add_binary_data(${CMAKE_PROJECT_NAME}.elf "assets/client.crt" TEXT)
target_add_binary_data(${CMAKE_PROJECT_NAME}.elf "assets/client.key" TEXT)

View File

@ -1,68 +1,64 @@
-----BEGIN CERTIFICATE-----
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
OBsrrOf8vtk=
MIIFsDCCA5igAwIBAgIIV8SXmpyaArYwDQYJKoZIhvcNAQELBQAwSTELMAkGA1UE
BhMCQ04xDzANBgNVBAoTBmlNLkluYzEMMAoGA1UECxMDSW9UMRswGQYDVQQDExJp
TS5JbmMgSW9UIFJvb3QgRzMwHhcNMjMwNTIxMDI1NTAwWhcNMjgwNTIxMDI1NTAw
WjBMMQswCQYDVQQGEwJDTjEPMA0GA1UEChMGaU0uSW5jMQwwCgYDVQQLEwNJb1Qx
HjAcBgNVBAMTFWlNLkluYyBJb1QgR2VuZXJhbCBDQTCCAiIwDQYJKoZIhvcNAQEB
BQADggIPADCCAgoCggIBAJjgX2un2L1LVIbZO9uGvMLxFOy8Z+27drWw7pBAV4eO
OpRsxW2Ai8xiHtdSz5fwSlPEIoBG0TsPS2NczNdlpUkjX3Io6kC+hoGonAwVueki
kIaap3rx5XeJtzOiLvWFrPJF6iKzkHZ77fDRrmeeALJ7goYH9s+QZhkQFkyqA1Ft
8isLY4dORXD0ZahWJvSq3n2scpspmkC3a+WYsIjx91YLUKh3AmNw8umsMfqVSu5P
22V4olmTZHXMZTjR/WKu4/WsNMPcdj9zR6xVu17T92wIrkQKxKZxvQDVtL2jYULG
YHPvCJjhskiiA5O/ERnTGmQU9tb1E76AQMnLTwvSB60fOBUlQVaMly7PfxTGrZpC
J8f/pc70j8qTN7HqPmEFcFTymaHI7UTrbj6oCAp0oalLQ/II+yFlGJnJ/9DGbfGX
qzJCJqe9sx20yFPVd1/lcKhHpC+bF6e2/eoN0ATuSUi2PWBVseQaJY7TkDoUTTP3
6016G6mfSHGDO07QeWysBC/Sq+2ngO4obsyhx02NAXRBBQ5X3jcdRlnfKHO/30zN
yU9BA4EMFwkZG8udP63ndvq6yokjW71QGgK6SUEO/QMIWJAkOo8GMv2nNsUE5DSF
psBhIMObp2A8AY42zV7bPPx3Rn8lVKpTzxEsO1SNPQKMvbdkLIbY1uLv6Z9j8npT
AgMBAAGjgZgwgZUwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUh+j/sQfC
RNTcHUZUPxUC0Q/WqxcwDgYDVR0PAQH/BAQDAgEGMB0GA1UdJQQWMBQGCCsGAQUF
BwMBBggrBgEFBQcDAjARBglghkgBhvhCAQEEBAMCAAcwHgYJYIZIAYb4QgENBBEW
D3hjYSBjZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQsFAAOCAgEAI6n4BQO7Y75a7Evk
NH58tcjUvHVb5vKHg3i2+UV36hTiXHdcWaDpq1fgeDUMHetdLn9YEH8EXaCUisYA
chmQ1o5OMyp+vU6rC9hhCPkREYdGRRO6lHjXw40v+nCtKl8oDKgDbC+qgaczNM3J
397bL6kYUhEHHuE8zZqhCSw9iZOJubEB3gQ1J8K91rvZqCXstOAQ9nqFZkxZQu1y
rbDxXr3xc7TEj33Jct2DlB5T6J/wAXEkVhwXafrjz+FQfkNHyMNcNZbYFKDioNGA
/JDYvKoUN/K7ZZtDh7ldCLIANZswIb+zAU2URnxIMJVdM5u8tkcy6qDO2SwI1766
1xyB61qNcupI+kUgxwXQ5DfWGrBQZ6HpYO+77pH5yuPnFlFwORvblhn+kk6VpoWe
NYfHBQjDBq0iCutX/oGB4sA3Iwh8QLQIGka+0MYoWM5AtygMU6byHpzm2JdfsVCJ
YJVAFxVpgfy82s7iWWorHimLlkeNpjdovTLK+fZhz6o24ZoYCWvyEbHuvFrR9ct0
tSP50Ulf9Vb7qQ+w94rplVe09K8jIfi7i4OPWR4aSX1VqtOBZ36tsjxuD+uCs2Ok
ZPOWwxkSbJMkfvzG03IFfmjQp0dolT9Ev9wyp6qrJVVZZydzqJO5qAzYqafLtU3O
9WslzbtdtaD4TSXd2OvbRehTPsU=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
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
DXBx2FuyJRFR9As=
MIIFbDCCA1SgAwIBAgIIARtSAxfPbhEwDQYJKoZIhvcNAQELBQAwSTELMAkGA1UE
BhMCQ04xDzANBgNVBAoTBmlNLkluYzEMMAoGA1UECxMDSW9UMRswGQYDVQQDExJp
TS5JbmMgSW9UIFJvb3QgRzMwHhcNMjMwNTIxMDI0OTAwWhcNNDMwNTIxMDI0OTAw
WjBJMQswCQYDVQQGEwJDTjEPMA0GA1UEChMGaU0uSW5jMQwwCgYDVQQLEwNJb1Qx
GzAZBgNVBAMTEmlNLkluYyBJb1QgUm9vdCBHMzCCAiIwDQYJKoZIhvcNAQEBBQAD
ggIPADCCAgoCggIBAMhol1Ne58LkklAUhUsaohwZDFaeeddemHKwvaF0gQ3xfF1Z
49Zf0OMpgPcjmZhZFySRoSblX7ZIoNt42DShTiTQSESwhszeLpOJ2Ls2uJKVkdIn
qyspcUnHk02MtGf9MLvPC+JVM5nal2rV5pM7gqvR4Um4qfjIEBKYnHxx451Mg9QF
lnsOFurnPMEZGbS0DwbeLqCvDo1/8f0DIAxRLixetPjzfjXkR8CKd7Khqvy/fbou
TeV2nHFvWTlFyJjbVqj8XOdVMA97o13lKrdFDom1tf2r4QUywoe6tpbgeEWmxddn
8MSeA8rBB8HdeyzB2NaYoFa0vZG6pvVlbG07YNJ6Y+wLj3Rjid5WuhkN0YMYg7M5
WNNkaOHa4V6Y8sAQvznBfdJsktxtaatPY9BWQEpJOzfycGZXZMWp5JmRCwFBtaRG
/Wk7f8aLTx+eu5/57pmeW9t1nNHnJKuFQggzRwzqB3f+ghKIw4FfIrAGrxaoT4Lw
DbB5KBS4SieJ20lOz3qtPkJDmOtuu3oHJnrPEZXWO5GXbBe59FCoLlDOtOZJqXuH
Ft3ZkzCYEDgZy94XmgDwAPhEOH0+1kVJ+7sX90y7wGaCyiGh9eoS39tqZl2NR980
7qUA4yIzDF6KxC/cvUwIdZfO64OHLYai9+lZ5+5GYOe4e+ct58/CZUwQIfGVAgMB
AAGjWDBWMBIGA1UdEwEB/wQIMAYBAf8CAQMwHQYDVR0OBBYEFBkJ75xuhZoReb/k
QvuF1qq0uJxvMA4GA1UdDwEB/wQEAwIBBjARBglghkgBhvhCAQEEBAMCAAcwDQYJ
KoZIhvcNAQELBQADggIBAKu6tobcojcwhOwNhRZE6+aDcZA3lpNVTKZ34FkgSQXf
FNwCurS2kkYOfrZ912Yt/b0ScJ7uQG0NDV+LyzewcO0IV//LkvompQHLhowaTRHG
4NfQ/3sjv3vg3kgro8dEQfDSApC6kif9wZ6ATaM9kxjqrLEbJK3zBjy4IVqh61Zs
xl8QxqOUX4oXH6TiTpuyyFHq3kNEsEHpkGASer4y0RV/frz6+7UoypCdnyLmHDJL
4jJeMmvdgSCwjGBEIxlL1Zt5DUo7TiQXGEhpbiyayMywvqmis8RTG0XikYFqC/3o
rbKOxiyt4ij4L3LrmZc/iCKMjoZhFnExcS39gkLj4AMnDqTVQx8vW57Uam+UR0E2
P5UBxgLOzoHircv50dtL7wds7UtzFF5GsogMZjaT+S2xTr/T+pjNRxVFO39flf+y
BmPoS3Kbv0Efbl8XMxKYolVDf7Vb4IG+WdkJJgA+ioAKzrs8ZumT58ihm5NNWQtw
q+RFuXLlHnA3ILubGzalT0iwYHdDTnNLr4N/APcwqlxQqjyC0ieuO15+b6x6S8wx
vKTtx1Kwo+1MMsrreh2KjFmn8Y/krWmqI4a/5bDFbqX7ZeR5eAU9WG/RNeZITbgI
34uqEApf6gPNv/sTIIBPXm9T6hpAcKwNNDhWbU0RrpAGKiCu54H2Gxzc1qJahASX
-----END CERTIFICATE-----

View File

@ -1,29 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIE5jCCAs6gAwIBAgIBBDANBgkqhkiG9w0BAQsFADB7MRMwEQYKCZImiZPyLGQB
GRYDbW9lMRMwEQYKCZImiZPyLGQBGRYDaW1pMQ8wDQYDVQQKDAZpTS5JbmMxHjAc
BgNVBAsMFWlNLkluYyBJb1QgU2lnbmluZyBDQTEeMBwGA1UEAwwVaU0uSW5jIElv
VCBTaWduaW5nIENBMB4XDTIyMDcwNDEzNDkxNVoXDTI0MDcwMzEzNDkxNVowZzET
MBEGCgmSJomT8ixkARkWA21vZTETMBEGCgmSJomT8ixkARkWA2ltaTEPMA0GA1UE
CgwGaU0uSW5jMRMwEQYDVQQLDApJb1QgU3lzdGVtMRUwEwYDVQQDDAxFU1BfREhU
X1RlbXAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtKqSGU7OsJQKE
/ap3FWFS8d9P0ZPDhwr8FBfGnU9Os9tuERENM7mDFdAISUiKD3t3xfGX+hOLStYm
9A0vZtWoq6Qhl2pPd7O7yi7Jw5OLSlNmoovClp78dyA82ECszYsEp32fw6nSbhmL
YKTZMYYcdGQO96NWUXvHjuimpCbcUeaDD8yad2TYkb57na3DJp+UNxdf+mvR2beY
RGkmsIn84UP9edmV2lPgx8rNQOGH8mxTMDtU4D0taQF+n/2W/awi+yMtsdjf811+
CwSipyVvo8Sb2zl3IHBcI2uD3gSpJ6pjMkExB6TnO+bE3o4iby+iBAmm9rREiO5l
y9WmGYsfAgMBAAGjgYgwgYUwDgYDVR0PAQH/BAQDAgeAMAkGA1UdEwQCMAAwEwYD
VR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0OBBYEFPealnfk4PmDut1rni1pUF5c7lPq
MB8GA1UdIwQYMBaAFPqAn5YOzFFakCDyAz5Gjxpuy1buMBMGA1UdEQQMMAqCCGRo
dF90ZW1wMA0GCSqGSIb3DQEBCwUAA4ICAQAFwWkFP/qrYamU7JCRsReW0BTtPxQD
qPYkdff7IO5mwXcbJZKK9HaueCtItMgl8l9SUMdiNdHETodOAuTRtjI9vaDm1bai
nnQdxNYUQHDZc0NHurTKzLr7gTlE61Hk84Y6Erd/AiwfyqT+832jCinjS3bpY37s
rWMxRbo1Abe+4V/+giV4Qqk5yYUHyevkO2zliyCk1FLpczRAGYBvQFBN+2Ggvimj
lcGhi6O5UCUgqbral3pgNgJ3W0ZPCZqd03B4aaauTvQ7QHk3d++kc/RYanHuWaD+
SEVgMVv13pG7ITggQxoRgKv51sNFcib3WZeJnisIQ4CnzILVaKTNbHKOg0K2YCk0
xnfcESJazQiaGHC0PFoVBqdO3NP/ISstr6vltJ1hHP6hUeOii0zJXbecD+I5rnsN
L6UapEfWvP+/Wt0Hv2ROp8Y2vPkjn9MXCgv5+MsbafnlpP98C8aifexgeygTXZGJ
pQCeqD39ZMvLwoMHjD9y+Qn6prJHrOAaH41S0mmYF7UirRjVVUp9J8BAnfTLhvgX
0CCWVipPChXM3r+w4j2+/Y7KuBuOtmPxLDVp6d/Tf96Bg33ZvD2GY7PetPeB7j5x
Ps+5+9X8cVfNUngzf8LlwTNDsUmECDXpLWri8rRfBBJiGT0CP4EqELvhTrle4uu3
8PHQZfCgDH9WJQ==
-----END CERTIFICATE-----

View File

@ -1,31 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,18E77130CD1EB69EB57399009D3AED8D
wEtOb6CifHIbPIXUnIWxUVkwyMWx0B4/y6JGEN//1v6zS0tvLKwKw0kUp6ZQlZEU
mHujXTIP4u/4X1Na6SacibDHeNi4GYP1T3Sp4rc1xKFTU4lQ4FlCXMmmGOKm05gZ
gFXyxqOjBlqYkqWYZnh+C2YEov6xX/OrAkZcSzQ6onjgwsrpbfQffiMxt1zDjCl9
OsDp3xn1TLmwH33oy1qpqxvn2TxETh+gF2HLWqQtnF4dugxun11E/PCiHCTT0QCP
E/xh4EJvUXtW7kwvqRW2kXFwnrRUzGTLnBfDGTEte9Dh1bJN+/tcmU7noU+WIw7j
0CzTfOMHv5tF1KcowLSU67Nofx7L3jWD2Ac6bwZv1uWlCJEltRO0G1WCcoDAw/Ha
SWCzk9CEf8x80IObAjgC3C3cdZfTYnfonMgdBC9yK1dS5zllq9Q4EbNPvhbjNz4L
UggiXEfu3N9DFvt0EZVGeqipqIThs7wJBiYp9WK7yruMeTRmSPbNlu1nITiwQEcy
bFC8nGU5QCt0mBymAxQ4YXeMdTmIbartuSoTivyNkgkzWOkGKjDP5oxb8F0ENCb8
a2Dbu4kXIgTJSVj4w1Hy/UiNiQSKEjlVNJwHm6WDEB7VC2GlfNeVKfhpfAxTAl4F
xF69A+aUalcT7pCOMtS5gPJCFHM+Up73fBnm5Ahh5psvNlIA0ZwjElVxkQCdrGDw
EUG0b7VurSe1+nnYoq+7LlUGMNAUb4VZkFofOG+3SszoKaK5CFwgLliWiQNByJSz
C0Wm8qDqUQNWAP5f0dKkNxCz7HP/lgmm6ZHwMIWzUWmgynHPre805ZM8zKkdA6eE
7WeUzdovl4skSG4DaSULXROXsHfnO4xySi+xc8pIYujBbmKOOqvwsN4trqz2kY9j
dSYrj12DGvvl1PCZQVCyUzVAsGGQLK4nRsf5viKLP5ghWa1MIA4/3Dlf5QxIIFPl
03+vRUjdOxtQssOZ1huyQA2Bvimw1nvRr2l4XJtgLbwkls7ikUot+rKMOn11QGCp
SVynTr2xL6XsvZy9pFt3TxcVmyuIu0DWsDx2Mc0I/vSMsXPmHLaBGNk8T8FLT3Y4
r1e2iPnwRuS4POsXr0VS4d+U0SbV51O3+OL2kD6iCS06UJE/XGJG1PhS1PgbNDPI
nmcr1ZRTTFDwmpgvdrQg+kAXW4OcsjCdFxeD6XnZaZRHpNjkNXIKSsd3N1j0DDJn
qFhHuWkJtRLCdssEQ8BNCHPfrSNID4NOnDJaP35hO5EulMqYleojKHoq2zPDpJiV
fl4HnuhQseiv5RxyF/XKfwZjG+nojI7IfQWEvQQ4Ny3jGzEmuXPYnh/wxgHSUhtq
B4wDfStM+YBixIXP6WKc+YpAgkxHoOpOtxX1RfrzcQr/4vciPIzvlMHWEl241Pq+
TPx9VT7FBsxf2CK0vfTWvOnInctg1FAJLO55rvC4Dk/ME0s/PSr6L+tIGADan38B
H3Xa1A72JhE3IKLdwjQud4kjIFhPVTaM14f3WbuRjb+/Xa7ATFAAlooY/d0KG4we
uB9qkU70SgXVCVxuE0almKQBEYoZFDO6tkZ/LGWo+uKd0wLpnmjRgCn/eMpAa5If
-----END RSA PRIVATE KEY-----

View File

@ -2,6 +2,7 @@ idf_component_register(
SRCS
"app_dht.c"
"app_mqtt.c"
"app_report_rb.c"
"app_wifi.c"
"main.c"
"aht10/aht10.c"

View File

@ -1,4 +1,4 @@
menu "Application Configuration"
menu "Application specific configuration"
config APP_I2C_SCL_PIN
int "I2C SCL IO number"
default 22
@ -21,29 +21,17 @@ menu "Application Configuration"
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the application to connect to.
SSID for the access point.
config APP_WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the application to use.
config APP_MAXIMUM_RETRY
int "Maximum retry"
default 5
help
Set the Maximum retry to avoid station reconnecting to the AP unlimited when the AP is really inexistent.
Password for the access point.
config APP_MQTT_BROKER_ADDR
string "MQTT broker connection string"
default "mqtt://127.0.0.1:1883"
help
Connection string for MQTT broker, use scheme://host:port format.
config APP_MQTT_TLS_CLIENT_PASSPHRASE
string "MQTT TLS Client Passphrase"
default "AAAAAAAAAAAAAAAA"
help
Passphrase to decrypt MQTT client private key.
endmenu

View File

@ -21,22 +21,21 @@ typedef aht10_ret_t (*aht10_i2c_xfer_t)(void *pdev, aht10_xfer_desc_t *xfer);
typedef aht10_ret_t (*aht10_delay_t)(void *pdev, uint32_t delay_msec);
typedef struct {
double temperature;
double humidity;
float temperature;
float humidity;
} aht10_result_t;
typedef struct {
aht10_i2c_xfer_t xfer;
aht10_delay_t delay;
aht10_delay_t delay;
} aht10_cb_t;
typedef struct {
aht10_cb_t cb;
void *user_data;
void *user_data;
} aht10_t;
aht10_ret_t aht10_init(aht10_t *aht);
aht10_ret_t aht10_measure(aht10_t *aht, aht10_result_t *result);
#endif

View File

@ -12,7 +12,7 @@
/* MQTT */
#include "app_mqtt.h"
/* AHT10 */
/* DHT sensor */
#include "aht10/aht10.h"
/* Log tag */
@ -25,29 +25,25 @@
#define APP_DHT_I2C_TIMEOUT 100
#define APP_DHT_AHT10_ADDR 0x38
#define INFLUX_TOPIC "iot/metric"
#define INFLUX_HOSTNAME "DHT_Temp"
#define INFLUX_FORMATTED_STRING \
"dht,hostname=" INFLUX_HOSTNAME \
" " \
"temperature=%.02lf," \
"humidity=%.02lf" \
" " \
"%llu"
static void app_dht_task(void *pvParameters);
static uint64_t app_get_nsec_timestamp(void);
static aht10_ret_t app_dht_impl_xfer(void *pdev, aht10_xfer_desc_t *xfer);
static aht10_ret_t app_dht_impl_delay(void *pdev, uint32_t delay_msec);
static aht10_t aht = {
.cb =
{
.xfer = app_dht_impl_xfer,
.delay = app_dht_impl_delay,
},
};
esp_err_t app_dht_init(void) {
i2c_config_t cfg = {
.mode = I2C_MODE_MASTER,
.sda_io_num = APP_DHT_I2C_SDA_IO,
.scl_io_num = APP_DHT_I2C_SCL_IO,
.sda_pullup_en = GPIO_PULLUP_DISABLE,
.scl_pullup_en = GPIO_PULLUP_DISABLE,
.master.clk_speed = 400000,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = 100000,
};
i2c_param_config(APP_DHT_I2C_INSTANCE, &cfg);
@ -56,46 +52,22 @@ esp_err_t app_dht_init(void) {
return ESP_FAIL;
}
if (xTaskCreate(app_dht_task, "DHT_TASK", 2048, NULL, 1U, NULL) != pdPASS) {
return ESP_FAIL;
}
aht10_init(&aht);
return ESP_OK;
}
static void app_dht_task(void *pvParameters) {
aht10_t aht = {
.cb =
{
.xfer = app_dht_impl_xfer,
.delay = app_dht_impl_delay,
},
};
aht10_init(&aht);
esp_err_t app_dht_read(float *temperature, float *humidity) {
esp_err_t ret = ESP_OK;
aht10_result_t result;
char report_buf[256];
uint64_t ns_ts;
for (;;) {
aht10_measure(&aht, &result);
ns_ts = app_get_nsec_timestamp();
/* Simple check to see if NTP is synchronized... */
if (ns_ts > (uint64_t)(1600000000L) * 1000000000) {
snprintf(report_buf, 256, INFLUX_FORMATTED_STRING, result.temperature, result.humidity, ns_ts);
app_mqtt_publish(INFLUX_TOPIC, report_buf);
}
vTaskDelay(pdMS_TO_TICKS(500));
if (aht10_measure(&aht, &result) != AHT10_OK) {
return -1;
}
}
static uint64_t app_get_nsec_timestamp(void) {
struct timeval tv_now;
gettimeofday(&tv_now, NULL);
int64_t time_ns = (int64_t)tv_now.tv_sec * 1000000000L + (int64_t)tv_now.tv_usec * 1000;
return time_ns;
*temperature = result.temperature;
*humidity = result.humidity;
return ret;
}
static aht10_ret_t app_dht_impl_xfer(void *pdev, aht10_xfer_desc_t *xfer) {
@ -122,4 +94,4 @@ static aht10_ret_t app_dht_impl_delay(void *pdev, uint32_t delay_msec) {
vTaskDelay(pdMS_TO_TICKS(delay_msec));
return AHT10_OK;
}
}

View File

@ -1,11 +1,12 @@
/* ESP drivers */
#include "esp_log.h"
#include "esp_partition.h"
#include "esp_system.h"
#include "esp_tls.h"
/* FreeRTOS */
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "freertos/task.h"
/* Cert bundle */
@ -14,87 +15,167 @@
/* MQTT client */
#include "mqtt_client.h"
#define APP_LOG_TAG "APP_MQTT"
#define LOG_TAG "APP_MQTT"
#define APP_MQTT_PART_TYPE ((esp_partition_type_t)0x40)
#define APP_MQTT_PART_CRT_NAME "tls_crt"
#define APP_MQTT_PART_KEY_NAME "tls_key"
#define APP_MQTT_PART_CRT_SUBTYPE 0x00
#define APP_MQTT_PART_KEY_SUBTYPE 0x01
#define APP_MQTT_PART_HEADER_VALID_SIGNATURE (0x66CCFFAA)
typedef struct {
char *topic;
char *payload;
} app_mqtt_queue_item_t;
uint32_t signature;
uint32_t length;
char data;
} app_mqtt_part_header_t;
extern const char mqtt_client_cert_start[] asm("_binary_client_crt_start");
extern const char mqtt_client_cert_end[] asm("_binary_client_crt_end");
extern const char mqtt_client_key_start[] asm("_binary_client_key_start");
extern const char mqtt_client_key_end[] asm("_binary_client_key_end");
static SemaphoreHandle_t s_mqtt_semaphore;
static esp_mqtt_client_handle_t s_mqtt_client;
static esp_partition_mmap_handle_t s_mqtt_crt_mmap_handle;
static esp_partition_mmap_handle_t s_mqtt_key_mmap_handle;
static void app_mqtt_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
static void app_mqtt_task(void *pvParameters);
static QueueHandle_t s_app_mqtt_publish_queue;
esp_err_t app_mqtt_init(uint32_t timeout_ms) {
esp_err_t ret = ESP_OK;
esp_err_t app_mqtt_init(void) {
s_app_mqtt_publish_queue = xQueueCreate(4, sizeof(app_mqtt_queue_item_t));
if(s_app_mqtt_publish_queue == NULL) {
return ESP_FAIL;
s_mqtt_semaphore = xSemaphoreCreateBinary();
if (s_mqtt_semaphore == NULL) {
ESP_LOGE(LOG_TAG, "Failed to create semaphore");
return ESP_ERR_NO_MEM;
}
if (xTaskCreate(app_mqtt_task, "MQ_TASK", 2048, NULL, 2U, NULL) != pdPASS) {
return ESP_FAIL;
const esp_partition_t *part_crt =
esp_partition_find_first(APP_MQTT_PART_TYPE, APP_MQTT_PART_CRT_SUBTYPE, APP_MQTT_PART_CRT_NAME);
const esp_partition_t *part_key =
esp_partition_find_first(APP_MQTT_PART_TYPE, APP_MQTT_PART_KEY_SUBTYPE, APP_MQTT_PART_KEY_NAME);
if (part_crt == NULL) {
ESP_LOGE(LOG_TAG, "Failed to find certificate partition.");
goto destroy_semaphore_exit;
}
ESP_LOGI(LOG_TAG, "Found certificate partition at 0x%08lx", part_crt->address);
if (part_key == NULL) {
ESP_LOGE(LOG_TAG, "Failed to find key partition.");
goto destroy_semaphore_exit;
}
ESP_LOGI(LOG_TAG, "Found key partition at 0x%08lx", part_key->address);
app_mqtt_part_header_t *ptr_crt;
app_mqtt_part_header_t *ptr_key;
ret = esp_partition_mmap(part_crt, 0, part_crt->size, ESP_PARTITION_MMAP_DATA, (const void **)(&ptr_crt),
&s_mqtt_crt_mmap_handle);
if (ret != ESP_OK) {
ESP_LOGE(LOG_TAG, "Failed to map certificate partition");
goto destroy_semaphore_exit;
}
ret = esp_partition_mmap(part_key, 0, part_key->size, ESP_PARTITION_MMAP_DATA, (const void **)(&ptr_key),
&s_mqtt_key_mmap_handle);
if (ret != ESP_OK) {
ESP_LOGE(LOG_TAG, "Failed to map key partition");
goto unmap_cert_exit;
}
if (ptr_crt->signature != APP_MQTT_PART_HEADER_VALID_SIGNATURE) {
ESP_LOGE(LOG_TAG, "Certificate partition content is invalid");
goto unmap_cert_exit;
}
ESP_LOGI(LOG_TAG, "Certificate length: %ld", ptr_crt->length);
if (ptr_key->signature != APP_MQTT_PART_HEADER_VALID_SIGNATURE) {
ESP_LOGE(LOG_TAG, "Key partition content is invalid");
goto unmap_cert_exit;
}
ESP_LOGI(LOG_TAG, "Key length: %ld", ptr_key->length);
const esp_mqtt_client_config_t mqtt_cfg = {
.broker =
{
.address.uri = CONFIG_APP_MQTT_BROKER_ADDR,
.verification.crt_bundle_attach = esp_crt_bundle_attach,
},
.credentials.authentication =
{
.certificate = &ptr_crt->data,
.key = &ptr_key->data,
},
};
s_mqtt_client = esp_mqtt_client_init(&mqtt_cfg);
if (s_mqtt_client == NULL) {
ret = ESP_ERR_NO_MEM;
goto unmap_cert_exit;
}
ret = esp_mqtt_client_register_event(s_mqtt_client, ESP_EVENT_ANY_ID, app_mqtt_event_handler, NULL);
if (ret != ESP_OK) {
ESP_LOGE(LOG_TAG, "Failed to register MQTT event.");
goto destroy_client_exit;
}
ret = esp_mqtt_client_start(s_mqtt_client);
if (ret != ESP_OK) {
ESP_LOGE(LOG_TAG, "Failed to start MQTT client.");
goto destroy_client_exit;
}
if (xSemaphoreTake(s_mqtt_semaphore, pdMS_TO_TICKS(timeout_ms)) != pdPASS) {
ESP_LOGE(LOG_TAG, "Failed to connect to broker in time.");
goto destroy_client_exit;
}
return ESP_OK;
destroy_client_exit:
esp_mqtt_client_destroy(s_mqtt_client);
unmap_cert_exit:
esp_partition_munmap(s_mqtt_crt_mmap_handle);
destroy_semaphore_exit:
vSemaphoreDelete(s_mqtt_semaphore);
return ret;
}
esp_err_t app_mqtt_deinit(void) {
esp_err_t ret;
esp_mqtt_client_stop(s_mqtt_client);
ret = esp_mqtt_client_destroy(s_mqtt_client);
if (ret != ESP_OK) {
return ret;
}
vSemaphoreDelete(s_mqtt_semaphore);
esp_partition_munmap(s_mqtt_crt_mmap_handle);
esp_partition_munmap(s_mqtt_key_mmap_handle);
return ESP_OK;
}
esp_err_t app_mqtt_publish(char *topic, char *payload) {
app_mqtt_queue_item_t item;
item.topic = malloc(strlen(topic) + 1);
if(item.topic == NULL) return ESP_FAIL;
item.payload = malloc(strlen(payload) + 1);
if(item.payload == NULL) {
free(item.topic);
return ESP_FAIL;
}
strcpy(item.topic, topic);
strcpy(item.payload, payload);
if(xQueueSend(s_app_mqtt_publish_queue, &item, portMAX_DELAY) != pdPASS) {
free(item.topic);
free(item.payload);
return ESP_FAIL;
}
return ESP_OK;
}
static void app_mqtt_task(void *pvParameters) {
const esp_mqtt_client_config_t mqtt_cfg = {
.uri = CONFIG_APP_MQTT_BROKER_ADDR,
.client_cert_pem = mqtt_client_cert_start,
.client_key_pem = mqtt_client_key_start,
.clientkey_password = CONFIG_APP_MQTT_TLS_CLIENT_PASSPHRASE,
.clientkey_password_len = strlen(CONFIG_APP_MQTT_TLS_CLIENT_PASSPHRASE),
.crt_bundle_attach = esp_crt_bundle_attach,
};
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, app_mqtt_event_handler, NULL);
esp_mqtt_client_start(client);
app_mqtt_queue_item_t item;
for (;;) {
if(xQueueReceive(s_app_mqtt_publish_queue, &item, portMAX_DELAY) == pdPASS) {
esp_mqtt_client_publish(client, item.topic, item.payload, strlen(item.payload), 0, 0);
/* This is alloc'ed by us. */
free(item.topic);
free(item.payload);
}
}
return esp_mqtt_client_publish(s_mqtt_client, topic, payload, (int)strlen(payload), 0, 0);
}
static void app_mqtt_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) {
/**/
switch ((esp_mqtt_event_id_t)event_id) {
case MQTT_EVENT_CONNECTED:
ESP_LOGI(LOG_TAG, "Connected to broker.");
xSemaphoreGive(s_mqtt_semaphore);
break;
default:
break;
}
}

107
main/app_report_rb.c Normal file
View File

@ -0,0 +1,107 @@
#include <string.h>
/* FreeRTOS */
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "freertos/task.h"
/* App */
#include "app_report_rb.h"
#define APP_REPORT_RB_SIZE 4800
static app_report_rb_t s_report_rb[APP_REPORT_RB_SIZE];
static volatile uint32_t s_report_rb_rptr = 0U;
static volatile uint32_t s_report_rb_wptr = 0U;
static SemaphoreHandle_t s_report_rb_semphr = NULL;
int app_report_rb_init(void) {
s_report_rb_semphr = xSemaphoreCreateMutex();
if (s_report_rb_semphr == NULL) {
return -1;
}
s_report_rb_rptr = 0U;
s_report_rb_wptr = 0U;
return 0;
}
void app_report_rb_append(app_report_rb_t *rpt) {
if (xSemaphoreTake(s_report_rb_semphr, portMAX_DELAY) != pdPASS) {
return;
}
memcpy(&s_report_rb[s_report_rb_wptr], rpt, sizeof(app_report_rb_t));
if (s_report_rb_wptr < APP_REPORT_RB_SIZE - 1) {
s_report_rb_wptr++;
} else {
s_report_rb_wptr = 0UL;
}
xSemaphoreGive(s_report_rb_semphr);
}
void app_report_rb_consume(app_report_rb_t *rpt) {
if (xSemaphoreTake(s_report_rb_semphr, portMAX_DELAY) != pdPASS) {
return;
}
memcpy(rpt, &s_report_rb[s_report_rb_rptr], sizeof(app_report_rb_t));
if (s_report_rb_rptr < APP_REPORT_RB_SIZE - 1) {
s_report_rb_rptr++;
} else {
s_report_rb_rptr = 0UL;
}
xSemaphoreGive(s_report_rb_semphr);
}
void app_report_rb_flush(void) {
if (xSemaphoreTake(s_report_rb_semphr, portMAX_DELAY) != pdPASS) {
return;
}
s_report_rb_wptr = 0U;
s_report_rb_rptr = 0U;
xSemaphoreGive(s_report_rb_semphr);
}
uint32_t app_report_rb_get_count(void) {
uint32_t ret = 0;
if (xSemaphoreTake(s_report_rb_semphr, portMAX_DELAY) != pdPASS) {
return ret;
}
if (s_report_rb_wptr >= s_report_rb_rptr) {
ret = s_report_rb_wptr - s_report_rb_rptr;
} else {
ret = (APP_REPORT_RB_SIZE - s_report_rb_rptr) + s_report_rb_wptr;
}
xSemaphoreGive(s_report_rb_semphr);
return ret;
}
uint32_t app_report_rb_get_total_size(void) {
return APP_REPORT_RB_SIZE;
}
void app_report_rb_discard(uint32_t num) {
if (num > app_report_rb_get_count()) {
return;
}
uint32_t tmp_ptr = s_report_rb_wptr + num;
if (tmp_ptr > APP_REPORT_RB_SIZE) {
tmp_ptr -= APP_REPORT_RB_SIZE;
}
s_report_rb_wptr = tmp_ptr;
}

View File

@ -14,21 +14,24 @@
#define APP_LOG_TAG "APP_WIFI"
EventGroupHandle_t g_app_wifi_event_group;
#define APP_WIFI_EVENT_GROUP_EVENT_CONNECTED (1 << 0U)
static uint8_t s_retries = 0U;
EventGroupHandle_t s_app_wifi_event_group;
static uint8_t s_retries = 0U;
static esp_netif_t *s_sta_netif;
static void app_wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
esp_err_t app_wifi_init(void) {
g_app_wifi_event_group = xEventGroupCreate();
if (g_app_wifi_event_group == NULL) {
s_app_wifi_event_group = xEventGroupCreate();
if (s_app_wifi_event_group == NULL) {
return ESP_FAIL;
}
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_sta();
s_sta_netif = esp_netif_create_default_wifi_sta();
wifi_init_config_t wifi_init_cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_cfg));
@ -55,11 +58,34 @@ esp_err_t app_wifi_init(void) {
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(APP_LOG_TAG, "WiFi initialized, heap free: %d.", esp_get_free_heap_size());
ESP_LOGI(APP_LOG_TAG, "WiFi initialized, heap free: %lu.", esp_get_free_heap_size());
return ESP_OK;
}
esp_err_t app_wifi_deinit(void) {
esp_wifi_stop();
esp_wifi_deinit();
esp_netif_destroy_default_wifi(s_sta_netif);
esp_event_loop_delete_default();
vEventGroupDelete(s_app_wifi_event_group);
return ESP_OK;
}
app_wifi_event_t app_wifi_wait_event(uint32_t max_timeout_ms) {
EventBits_t bits = xEventGroupWaitBits(s_app_wifi_event_group, APP_WIFI_EVENT_GROUP_EVENT_CONNECTED, pdFALSE,
pdFALSE, pdMS_TO_TICKS(max_timeout_ms));
if (bits & APP_WIFI_EVENT_GROUP_EVENT_CONNECTED) {
return APP_WIFI_EVENT_CONNECTED;
} else {
return APP_WIFI_EVENT_TIMEOUT;
}
}
static void app_wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) {
/* Event handler */
@ -69,25 +95,17 @@ static void app_wifi_event_handler(void *arg, esp_event_base_t event_base, int32
}
if (event_id == WIFI_EVENT_STA_DISCONNECTED) {
if (s_retries < CONFIG_APP_MAXIMUM_RETRY) {
esp_wifi_connect();
s_retries++;
ESP_LOGI(APP_LOG_TAG, "Connection lost, retrying #%d/%d...", s_retries, CONFIG_APP_MAXIMUM_RETRY);
} else {
xEventGroupSetBits(g_app_wifi_event_group, APP_WIFI_EVENT_GROUP_EVENT_FAILED);
ESP_LOGW(APP_LOG_TAG, "Connection lost, maximum retries reached.");
}
esp_wifi_connect();
ESP_LOGI(APP_LOG_TAG, "Disconnected");
}
} else if(event_base == IP_EVENT) {
if(event_id == IP_EVENT_STA_GOT_IP) {
xEventGroupSetBits(g_app_wifi_event_group, APP_WIFI_EVENT_GROUP_EVENT_CONNECTED);
} else if (event_base == IP_EVENT) {
if (event_id == IP_EVENT_STA_GOT_IP) {
xEventGroupSetBits(s_app_wifi_event_group, APP_WIFI_EVENT_GROUP_EVENT_CONNECTED);
s_retries = 0U;
ip_event_got_ip_t *event = event_data;
ESP_LOGI(APP_LOG_TAG, "Connected, IP address: "IPSTR, IP2STR(&event->ip_info.ip));
ESP_LOGI(APP_LOG_TAG, "Connected, IP address: " IPSTR, IP2STR(&event->ip_info.ip));
}
}
}

View File

@ -4,5 +4,6 @@
#include "esp_system.h"
esp_err_t app_dht_init(void);
esp_err_t app_dht_read(float *temperature, float *humidity);
#endif

View File

@ -3,7 +3,8 @@
#include "esp_system.h"
esp_err_t app_mqtt_init(void);
esp_err_t app_mqtt_init(uint32_t timeout_ms);
esp_err_t app_mqtt_deinit(void);
esp_err_t app_mqtt_publish(char *topic, char *payload);
#endif

View File

@ -0,0 +1,18 @@
#ifndef APP_REPORT_RB_H
#define APP_REPORT_RB_H
typedef struct {
uint64_t ts;
uint32_t voltage;
float temperature;
float humidity;
} app_report_rb_t;
int app_report_rb_init(void);
void app_report_rb_append(app_report_rb_t *rpt);
void app_report_rb_consume(app_report_rb_t *rpt);
uint32_t app_report_rb_get_count(void);
uint32_t app_report_rb_get_total_size(void);
void app_report_rb_flush(void);
#endif // APP_REPORT_RB_H

View File

@ -8,11 +8,13 @@
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#define APP_WIFI_EVENT_GROUP_EVENT_CONNECTED (1 << 0U)
#define APP_WIFI_EVENT_GROUP_EVENT_FAILED (1 << 1U)
extern EventGroupHandle_t g_app_wifi_event_group;
typedef enum {
APP_WIFI_EVENT_TIMEOUT,
APP_WIFI_EVENT_CONNECTED,
} app_wifi_event_t;
esp_err_t app_wifi_init(void);
esp_err_t app_wifi_deinit(void);
app_wifi_event_t app_wifi_wait_event(uint32_t max_timeout_ms);
#endif

View File

@ -4,10 +4,17 @@
* SPDX-License-Identifier: CC0-1.0
*/
#include <stdint.h>
#include <stdio.h>
#include <string.h>
/* ESP drivers */
#include "driver/gpio.h"
#include "esp_adc/adc_cali.h"
#include "esp_adc/adc_cali_scheme.h"
#include "esp_adc/adc_oneshot.h"
#include "esp_log.h"
#include "esp_sleep.h"
#include "esp_sntp.h"
/* FreeRTOS */
@ -18,43 +25,290 @@
#include "nvs_flash.h"
/* Config */
#include "app_dht.h"
#include "app_mqtt.h"
#include "app_wifi.h"
#include "sdkconfig.h"
#define APP_LOG_TAG "APP_MAIN"
/* App */
#include "app_dht.h"
#include "app_mqtt.h"
#include "app_report_rb.h"
#include "app_wifi.h"
#define LOG_TAG "APP_MAIN"
#define APP_WIFI_TIMEOUT_SECS 120
#define APP_MQTT_TIMEOUT_SECS 10
#define APP_SNTP_TIMEOUT_SECS 60
#define APP_SENSOR_INTERVAL_SECS 1
#define APP_SENSOR_REPORT_TRIGGER_POINTS 20 /* Count of the trigger points which triggers telemetry reporting */
#define APP_SENSOR_REPORT_WATERMARK_PERCENT 80 /* when the buffer reaches this watermark in each trigger point */
#define APP_SENSOR_REPORT_CRITICAL_PERCENT 95 /* Critical level, when this is reached, reports will be flushed */
/* Report interval: (RB Size / Nr. Trigger Points) * (Watermark / 100) * Interval secs */
#define APP_LED_PIN 16
#define APP_ADC_CH ADC_CHANNEL_6
static void app_report_task(void *pvParameters);
static uint64_t app_get_msec_timestamp(void);
static void app_led_init(void);
static void app_led_set(uint8_t on);
static void app_adc_init(void);
static uint32_t app_adc_read(void);
static volatile uint8_t s_report_task_running = 0;
static adc_oneshot_unit_handle_t s_adc_handle;
static adc_cali_handle_t s_adc_cal_handle = NULL;
void app_main(void) {
printf("Hello world!\n");
esp_err_t ret;
esp_err_t ret = nvs_flash_init();
ESP_LOGI(LOG_TAG, "Main application started.");
ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_LOGW(LOG_TAG, "NVS content appears to be corrupted or outdated, erase and recreate NVS structure.");
/* Erase NVS region and give it another try. */
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
ESP_LOGW(APP_LOG_TAG, "NVS content corrupted or outdated, cleared.");
}
/* NVS initialization reported failure, this should not happen. In this case, abort! */
ESP_ERROR_CHECK(ret);
ESP_ERROR_CHECK(app_wifi_init());
EventBits_t bits = xEventGroupWaitBits(g_app_wifi_event_group,
APP_WIFI_EVENT_GROUP_EVENT_CONNECTED | APP_WIFI_EVENT_GROUP_EVENT_FAILED,
pdFALSE, pdFALSE, portMAX_DELAY);
app_wifi_event_t a_wifi_evt = app_wifi_wait_event(APP_WIFI_TIMEOUT_SECS * 1000);
if (a_wifi_evt != APP_WIFI_EVENT_CONNECTED) {
ESP_LOGE(LOG_TAG, "WiFi failed to come up within time limit.");
if (bits & APP_WIFI_EVENT_GROUP_EVENT_FAILED) {
return;
esp_restart();
}
/* On first start, we need to know the actual start time for timestamp tracking in report */
sntp_setoperatingmode(SNTP_OPMODE_POLL);
sntp_setservername(0, CONFIG_APP_SNTP_POOL_ADDR);
sntp_init();
ESP_ERROR_CHECK(app_mqtt_init());
uint16_t sntp_trials = APP_SNTP_TIMEOUT_SECS;
/* If the NTP does not finish synchronization in 10 seconds... Required for initial boot up */
while (sntp_get_sync_status() != SNTP_SYNC_STATUS_COMPLETED) {
vTaskDelay(pdMS_TO_TICKS(1000));
sntp_trials--;
if (sntp_trials == 0U) {
ESP_LOGE(LOG_TAG, "Failed to synchronize NTP in-time.");
esp_restart();
}
}
sntp_stop();
ESP_ERROR_CHECK(app_mqtt_init(APP_MQTT_TIMEOUT_SECS * 1000));
ESP_ERROR_CHECK(app_mqtt_deinit());
/*
* We have acquired NTP time, de-init Wi-Fi.
* Something terribly wrong happens if this function is not completed successfully.
*/
ESP_ERROR_CHECK(app_wifi_deinit());
/* Some indication... */
app_led_init();
app_adc_init();
/* Initialize DHT sensors, abort if error occurs */
ESP_ERROR_CHECK(app_dht_init());
/* This task will be deleted if this function returns. */
if (app_report_rb_init() < 0) {
ESP_LOGE(LOG_TAG, "Failed to init RB");
esp_restart();
}
app_report_rb_t rpt;
for (;;) {
app_led_set(1);
ret = app_dht_read(&rpt.temperature, &rpt.humidity);
if (ret != ESP_OK) {
continue;
}
rpt.voltage = app_adc_read() * 2;
app_led_set(0);
rpt.ts = app_get_msec_timestamp();
app_report_rb_append(&rpt);
uint32_t current_count = app_report_rb_get_count();
uint32_t rb_size = app_report_rb_get_total_size();
if (current_count % 10 == 0) {
ESP_LOGI(LOG_TAG, "Last: %.2fC, %.2f%%", rpt.temperature, rpt.humidity);
ESP_LOGI(LOG_TAG, "RB level: %lu%%", current_count * 100 / rb_size);
ESP_LOGI(LOG_TAG, "Battery voltage: %lumV", rpt.voltage);
}
/**
* Trigger report task at each threshold point or above the last threshold point.
* If the last threshold trigger failed, the ring buffer will be cleared.
*/
uint32_t rb_trigger_level = rb_size / APP_SENSOR_REPORT_TRIGGER_POINTS;
uint32_t rb_trigger_watermark = rb_trigger_level * APP_SENSOR_REPORT_WATERMARK_PERCENT / 100;
uint32_t rb_critical_point = rb_size * APP_SENSOR_REPORT_CRITICAL_PERCENT / 100;
if (((current_count % rb_trigger_level) == rb_trigger_watermark) || (current_count > rb_critical_point)) {
if (!s_report_task_running) {
xTaskCreate(app_report_task, "RPT_TASK", 4096, NULL, 4, NULL);
s_report_task_running = 1U;
}
}
if (s_report_task_running) {
vTaskDelay(pdMS_TO_TICKS(1000));
} else {
esp_sleep_enable_timer_wakeup(APP_SENSOR_INTERVAL_SECS * 1000 * 1000);
esp_light_sleep_start();
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
}
}
}
static void app_report_task(void *pvParameters) {
app_report_rb_t rpt;
char *rpt_buffer;
ESP_ERROR_CHECK(app_wifi_init());
app_wifi_event_t a_wifi_evt = app_wifi_wait_event(APP_WIFI_TIMEOUT_SECS * 1000);
if (a_wifi_evt != APP_WIFI_EVENT_CONNECTED) {
ESP_LOGE(LOG_TAG, "WiFi failed to come up within time limit.");
goto drop_data_exit;
}
sntp_init();
uint16_t sntp_trials = APP_SNTP_TIMEOUT_SECS;
/* If the NTP does not finish synchronization in 10 seconds... Required for initial boot up */
while (sntp_get_sync_status() != SNTP_SYNC_STATUS_COMPLETED) {
vTaskDelay(pdMS_TO_TICKS(1000));
sntp_trials--;
if (sntp_trials == 0U) {
ESP_LOGE(LOG_TAG, "Failed to synchronize NTP in-time.");
goto stop_sntp_exit;
}
}
ESP_ERROR_CHECK(app_mqtt_init(APP_MQTT_TIMEOUT_SECS * 1000));
rpt_buffer = malloc(512);
while (app_report_rb_get_count() > 0) {
app_report_rb_consume(&rpt);
// TODO: Create new report
// app_mqtt_publish(INFLUX_TOPIC, rpt_buffer);
}
free(rpt_buffer);
ESP_ERROR_CHECK(app_mqtt_deinit());
sntp_stop();
ESP_ERROR_CHECK(app_wifi_deinit());
s_report_task_running = 0U;
vTaskDelete(NULL);
return;
stop_sntp_exit:
sntp_stop();
drop_data_exit:
ESP_ERROR_CHECK(app_wifi_deinit());
/* Flush ring buffer */
if (app_report_rb_get_count() > (app_report_rb_get_total_size() * APP_SENSOR_REPORT_CRITICAL_PERCENT / 100)) {
app_report_rb_flush();
}
s_report_task_running = 0U;
vTaskDelete(NULL);
}
static uint64_t app_get_msec_timestamp(void) {
struct timeval tv_now;
gettimeofday(&tv_now, NULL);
uint64_t time_ms = (int64_t)tv_now.tv_sec * 1000 + (int64_t)tv_now.tv_usec / 1000;
return time_ms;
}
static void app_adc_init(void) {
adc_oneshot_unit_init_cfg_t init_cfg = {
.unit_id = ADC_UNIT_1,
};
ESP_ERROR_CHECK(adc_oneshot_new_unit(&init_cfg, &s_adc_handle));
adc_oneshot_chan_cfg_t chan_cfg = {
.atten = ADC_ATTEN_DB_11,
.bitwidth = ADC_BITWIDTH_DEFAULT,
};
ESP_ERROR_CHECK(adc_oneshot_config_channel(s_adc_handle, APP_ADC_CH, &chan_cfg));
adc_cali_line_fitting_config_t cali_config = {
.unit_id = ADC_UNIT_1,
.atten = ADC_ATTEN_DB_11,
.bitwidth = ADC_BITWIDTH_DEFAULT,
};
ESP_ERROR_CHECK(adc_cali_create_scheme_line_fitting(&cali_config, &s_adc_cal_handle));
}
static uint32_t app_adc_read(void) {
int result;
int voltage;
ESP_ERROR_CHECK(adc_oneshot_read(s_adc_handle, APP_ADC_CH, &result));
ESP_ERROR_CHECK(adc_cali_raw_to_voltage(s_adc_cal_handle, result, &voltage));
return voltage;
}
static void app_led_init(void) {
gpio_config_t io_cfg = {
.mode = GPIO_MODE_OUTPUT_OD,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.pin_bit_mask = (1U << APP_LED_PIN),
.intr_type = GPIO_INTR_DISABLE,
};
gpio_config(&io_cfg);
gpio_set_level(APP_LED_PIN, 1);
}
static void app_led_set(uint8_t on) {
if (on) {
gpio_set_level(APP_LED_PIN, 0);
} else {
gpio_set_level(APP_LED_PIN, 1);
}
}

View File

@ -1,5 +1,9 @@
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x6000,
phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 3M,
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x00009000, 0x00004000,
otadata, data, ota, 0x0000d000, 0x00002000,
phy_init, data, phy, 0x0000f000, 0x00001000,
ota_0, app, ota_0, 0x00010000, 0x00180000,
ota_1, app, ota_1, 0x00190000, 0x00180000,
tls_crt, 0x40, 0x00, 0x00310000, 0x00008000,
tls_key, 0x40, 0x01, 0x00318000, 0x00008000,
1 # ESP-IDF Partition Table
2 # Name, Type, SubType, Offset, Size, Flags # Name, Type, SubType, Offset, Size, Flags
3 nvs, data, nvs, 0x9000, 0x6000, nvs, data, nvs, 0x00009000, 0x00004000,
4 phy_init, data, phy, 0xf000, 0x1000, otadata, data, ota, 0x0000d000, 0x00002000,
5 factory, app, factory, 0x10000, 3M, phy_init, data, phy, 0x0000f000, 0x00001000,
6 ota_0, app, ota_0, 0x00010000, 0x00180000,
7 ota_1, app, ota_1, 0x00190000, 0x00180000,
8 tls_crt, 0x40, 0x00, 0x00310000, 0x00008000,
9 tls_key, 0x40, 0x01, 0x00318000, 0x00008000,

View File

@ -1,22 +0,0 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
from typing import Callable
import pytest
from pytest_embedded_idf.dut import IdfDut
from pytest_embedded_qemu.dut import QemuDut
@pytest.mark.supported_targets
@pytest.mark.generic
def test_hello_world(dut: IdfDut, log_minimum_free_heap_size: Callable[..., None]) -> None:
dut.expect('Hello world!')
log_minimum_free_heap_size()
@pytest.mark.esp32 # we only support qemu on esp32 for now
@pytest.mark.host_test
@pytest.mark.qemu
def test_hello_world_host(dut: QemuDut) -> None:
dut.expect('Hello world!')

View File

View File

@ -1,11 +1,14 @@
# Minimum flash size set to 4MB
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
# Use custom partition table, 3MB application.
# Use custom partition table
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
# Custom CA bundle for mbedTLS
CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=16384
CONFIG_MBEDTLS_DYNAMIC_BUFFER=y
CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y
CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE=y
CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH="assets/ca"
CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH="assets/ca"

23
tools/gen_credentials.rb Normal file
View File

@ -0,0 +1,23 @@
if ARGV.length < 1 then
puts 'No parameter given'
exit 255
end
File.open(ARGV[0], 'r') do |f|
raw_size = f.size
puts "Credential file size: #{raw_size}"
hdr = [0xAA, 0xFF, 0xCC, 0x66]
hdr.push raw_size & 0xFF
hdr.push (raw_size >> 8) & 0xFF
hdr.push (raw_size >> 16) & 0xFF
hdr.push (raw_size >> 24) & 0xFF
File.open("#{ARGV[0]}.bin", 'w+') do |wf|
wf.write(hdr.pack('C*'))
wf.write(f.read)
wf.write([0].pack('C*'))
end
end