14 Commits

Author SHA1 Message Date
b123bc553d Cleanup and fix for message 2022-03-24 22:56:59 +01:00
80a775322a Added toggle, removed logging 2022-03-24 22:18:33 +01:00
983f26e70a Hupe config 2022-03-24 21:33:40 +01:00
8a28084a0a Fixed ota name 2022-02-18 22:35:13 +01:00
63e466c926 Fixed config 2022-02-18 22:34:43 +01:00
6e9fc74361 Fixed bullshit 2022-02-18 22:16:21 +01:00
49b575251c Added ifttt support 2021-12-29 21:46:26 +01:00
d5ebbcdd24 Added logging 2021-12-29 06:19:16 +01:00
351c40fce7 Name too long 2021-12-29 05:47:53 +01:00
3f0baddcb1 added nvs config library 2021-12-29 05:41:53 +01:00
16b81ee300 fix building 2021-12-29 05:13:28 +01:00
65a77fee44 Added logging 2021-12-29 04:46:31 +01:00
f48bf8b6b6 Removed die komische CI 2021-12-29 01:35:18 +01:00
1ce42674d3 relay board 2021-12-29 01:03:23 +01:00
12 changed files with 2018 additions and 192 deletions

View File

@ -1,89 +0,0 @@
name: Analysis
on:
push:
release:
types:
- created
# pull_request:
# types: [opened, synchronize, reopened]
jobs:
build:
runs-on: ubuntu-latest
env:
SONAR_SCANNER_VERSION: 4.4.0.2170
SONAR_SERVER_URL: "https://sonarcloud.io"
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
SONAR_CACHE_DIR: sonar_cache
environment: Analysis
strategy:
fail-fast: false
matrix:
node: [allfeatures]
name: ${{ matrix.node }}
steps:
- name: Checkout (without submodules)
uses: actions/checkout@v2
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up JDK 11 (for Sonar)
uses: actions/setup-java@v1
with:
java-version: 11
- name: Download and set up sonar-scanner
env:
SONAR_SCANNER_DOWNLOAD_URL: https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${{ env.SONAR_SCANNER_VERSION }}-linux.zip
run: |
mkdir -p $HOME/.sonar
curl -sSLo $HOME/.sonar/sonar-scanner.zip ${{ env.SONAR_SCANNER_DOWNLOAD_URL }}
unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
echo "$HOME/.sonar/sonar-scanner-${{ env.SONAR_SCANNER_VERSION }}-linux/bin" >> $GITHUB_PATH
- name: Download and set up build-wrapper (for Sonar)
env:
BUILD_WRAPPER_DOWNLOAD_URL: ${{ env.SONAR_SERVER_URL }}/static/cpp/build-wrapper-linux-x86.zip
run: |
curl -sSLo $HOME/.sonar/build-wrapper-linux-x86.zip ${{ env.BUILD_WRAPPER_DOWNLOAD_URL }}
unzip -o $HOME/.sonar/build-wrapper-linux-x86.zip -d $HOME/.sonar/
echo "$HOME/.sonar/build-wrapper-linux-x86" >> $GITHUB_PATH
- name: Checkout and install esp-idf
uses: 0xFEEDC0DE64/checkout_install_esp_idf@main
- name: Fast Submodule Checkout components/arduino-esp32
uses: 0xFEEDC0DE64/fast_submodule_checkout@main
with:
submodule: components/arduino-esp32
- name: Checkout remaining submodules
run: git submodule update --init --recursive $(git submodule | awk '{ if ($2 != "esp-idf" && $2 != "components/arduino-esp32") print $2 }')
- name: Setup ccache
uses: 0xFEEDC0DE64/setup_ccache@main
with:
key: ${{ runner.os }}-ccache-${{ matrix.node }}
- name: Build firmware
run: |
export CCACHE_MAXSIZE=400M CCACHE_BASEDIR="$(pwd)"
. export.sh
./switchconf.sh ${{ matrix.node }}
build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} idf.py --ccache build
ccache -s
- name: Cache sonar
uses: 0xFEEDC0DE64/cache-with-update@update-cache-on-cachehit
with:
path: ${{ env.SONAR_SERVER_URL }}
key: ${{ runner.os }}-sonar-${{ matrix.node }}
- name: Run sonar-scanner
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: |
sonar-scanner --define sonar.host.url="${{ env.SONAR_SERVER_URL }}" --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" --define sonar.cfamily.cache.path="${{ env.SONAR_CACHE_DIR }}"

View File

@ -1,67 +0,0 @@
name: Build
on:
push:
release:
types:
- created
jobs:
build:
runs-on: ubuntu-latest
environment: Userconfigs
strategy:
fail-fast: false
matrix:
node: [feedc0de, comred, peter, mick, nofeatures] # allfeatures not used here
name: ${{ matrix.node }}
steps:
- name: Checkout (without submodules)
uses: actions/checkout@v2
- name: Checkout and install esp-idf
uses: 0xFEEDC0DE64/checkout_install_esp_idf@main
- name: Fast Submodule Checkout components/arduino-esp32
uses: 0xFEEDC0DE64/fast_submodule_checkout@main
with:
submodule: components/arduino-esp32
- name: Checkout remaining submodules
run: git submodule update --init --recursive $(git submodule | awk '{ if ($2 != "esp-idf" && $2 != "components/arduino-esp32") print $2 }')
- name: Setup ccache
uses: 0xFEEDC0DE64/setup_ccache@main
with:
key: ${{ runner.os }}-ccache-${{ matrix.node }}
- name: Unpack ignore folder
env:
GPG_KEY: ${{ secrets.GPG_KEY }}
run: |
tools/bobby-decrypt
- name: Build firmware
run: |
export CCACHE_MAXSIZE=400M CCACHE_BASEDIR="$(pwd)"
. export.sh
./switchconf.sh ${{ matrix.node }}
idf.py --ccache build
ccache -s
- name: Set outputs
id: vars
run: |
echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
- name: Upload Build Artifact
uses: actions/upload-artifact@v2.2.4
with:
name: bobbyquad_${{ matrix.node }}
path: |
build_${{ matrix.node }}/bobbyquad_${{ matrix.node }}.bin
build_${{ matrix.node }}/bobbyquad_${{ matrix.node }}.elf
build_${{ matrix.node }}/bootloader/bootloader.bin
build_${{ matrix.node }}/bootloader/bootloader.elf
build_${{ matrix.node }}/partition_table/partition-table.bin

85
config_relay.cmake Normal file
View File

@ -0,0 +1,85 @@
set(BOBBY_APP_NAME bobby_relay)
add_definitions(
-DUSER_SETUP_LOADED=1
-DLOAD_GLCD=1
-DLOAD_FONT2=1
-DLOAD_FONT4=1
-DLOAD_FONT7=1
-DILI9341_DRIVER=1
-DTFT_MOSI=13
-DTFT_SCLK=15
-DTFT_CS=5
-DTFT_DC=12
-DTFT_RST=2
-DSPI_FREQUENCY=40000000
)
set(BOBBYCAR_BUILDFLAGS
-DFEATURE_ADC_IN
-DPINS_GAS=34
-DPINS_BREMS=35
-DDEFAULT_SWAPSCREENBYTES=false
#-DFEATURE_CAN
# -DFEATURE_SERIAL
# -DPINS_RX1=4
# -DPINS_TX1=5
# -DPINS_RX2=22
# -DPINS_TX2=23
-DDEFAULT_INVERTFRONTLEFT=false
-DDEFAULT_INVERTFRONTRIGHT=true
-DDEFAULT_INVERTBACKLEFT=false
-DDEFAULT_INVERTBACKRIGHT=true
-DDEFAULT_WHEELDIAMETER=200
# -DFEATURE_MOSFETS
# -DPINS_MOSFET0=18
# -DPINS_MOSFET1=19
# -DPINS_MOSFET2=21
-DDEFAULT_IMOTMAX=28
-DDEFAULT_IDCMAX=30
-DDEFAULT_NMOTMAX=2000
-DDEFAULT_FIELDWEAKMAX=7
-DDEFAULT_FIELDADVMAX=40
-DDEVICE_PREFIX=bobby_relay
-DAP_PASSWORD=Passwort_123
-DFEATURE_WEBSERVER
#-DFEATURE_OTA
-DOTA_USERNAME="relay"
# -DDPAD_5WIRESW_DEBUG
-DDEFAULT_GASMIN=842
-DDEFAULT_GASMAX=2480
-DDEFAULT_BREMSMIN=826
-DDEFAULT_BREMSMAX=2502
#-DFEATURE_BLE
# -DFEATURE_BLUETOOTH
# -DFEATURE_BMS
# -DFEATURE_GAMETRAK
# -DPINS_GAMETRAKX=34
# -DPINS_GAMETRAKY=39
# -DPINS_GAMETRAKDIST=36
# -DDEFAULT_GAMETRAKXMIN=0
# -DDEFAULT_GAMETRAKXMAX=4095
# -DDEFAULT_GAMETRAKYMIN=0
# -DDEFAULT_GAMETRAKYMAX=4095
# -DDEFAULT_GAMETRAKDISTMIN=0
# -DDEFAULT_GAMETRAKDISTMAX=4095
# -DFEATURE_POWERSUPPLY
# -DFEATURE_CLOUD
-DFEATURE_UDPCLOUD
-DFEATURE_LEDBACKLIGHT
-DPINS_LEDBACKLIGHT=23
-DLEDBACKLIGHT_INVERTED
-DFEATURE_GARAGE
-DFEATURE_NTP
-DFEATURE_WIRELESS_CONFIG
-DFEATURE_LEDSTRIP
-DPINS_LEDSTRIP=33
-DLEDSTRIP_LENGTH=288
# -DLEDSTRIP_WRONG_DIRECTION
-DLEDSTRIP_ANIMATION_DEFAULT=2
-DLEDS_PER_METER=144
-DOLD_NVS
-DFEATURE_DNS_NS
-DFEATURE_ESPNOW
-DFEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET
)

View File

@ -13,16 +13,7 @@ using namespace espgui;
GarageMenu::GarageMenu()
{
for (uint8_t index = 0; index < stringSettings.wirelessDoors.size(); index++)
{
const auto &wirelessDoor = stringSettings.wirelessDoors[index];
if (wirelessDoor.doorId.empty() || wirelessDoor.doorToken.empty())
continue;
auto &menuitem = constructMenuItem<makeComponentArgs<MenuItem, garagenmenu::SendEspNowMessageAction, ChangeableText>>(index);
menuitem.setTitle(wirelessDoor.doorId);
}
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void GarageMenu::back()

View File

@ -18,11 +18,7 @@ public:
SendEspNowMessageAction(uint8_t index) : m_index{index} {}
void triggered() override
{
if (const auto error = espnow::send_espnow_message(fmt::format("BOBBYOPEN:{}:{}", stringSettings.wirelessDoors[m_index].doorId, stringSettings.wirelessDoors[m_index].doorToken)); error != ESP_OK)
{
ESP_LOGE("BOBBY", "send_espnow_message() failed with: %s", esp_err_to_name(error));
return;
}
}
private:
uint8_t m_index;

View File

@ -7,30 +7,172 @@
#include <esp_log.h>
#include <numberparsing.h>
#include <espwifistack.h>
#include <asynchttprequest.h>
#include <delayedconstruction.h>
#include <cleanuphelper.h>
#include "globals.h"
#include "utils.h"
#include "time_bobbycar.h"
#define PIN_RELAY_HUPE 14
#define PIN_RELAY_COMPRESSOR 27
using namespace std::chrono_literals;
namespace espnow {
namespace {
constexpr const char * const TAG = "BOBBY_ESP_NOW";
} // namespace
std::optional<espchrono::millis_clock::time_point> relayHupeTimer;
std::optional<espchrono::millis_clock::time_point> last_send_ms;
uint16_t lastYear; // Used for esp-now timesync
std::deque<esp_now_message_t> message_queue{};
std::vector<esp_now_peer_info_t> peers{};
uint8_t initialized{0};
bool compressor_is_an{false};
bool hupe_state{false};
bool receiveTimeStamp{true};
bool receiveTsFromOtherBobbycars{true};
namespace ifttt {
namespace {
extern "C" void onReceive(const uint8_t *mac_addr, const uint8_t *data, int data_len)
cpputils::DelayedConstruction<AsyncHttpRequest> http_request;
}
void setup_request()
{
ESP_LOGD(TAG, "Received data");
const std::string_view data_str{(const char *)data, size_t(data_len)};
if (!http_request.constructed())
{
http_request.construct("qr_request", espcpputils::CoreAffinity::Core0);
}
}
tl::expected<void, std::string> start_qr_request(std::string event)
{
if (!http_request.constructed())
{
return tl::make_unexpected("request im oarsch");
}
if (const auto res = http_request->start(fmt::format("http://maker.ifttt.com/trigger/{}/with/key/{}", event, stringSettings.ifttt_key)); !res)
{
return res;
}
return{};
}
tl::expected<std::string, std::string> check_request()
{
if (!http_request.constructed())
{
return tl::make_unexpected("request im oarsch");
}
if (!http_request->finished())
{
return tl::make_unexpected("request has not finished");
}
const auto helper = cpputils::makeCleanupHelper([](){ http_request->clearFinished(); });
if (const auto result = http_request->result(); !result)
{
return tl::make_unexpected(result.error());
}
else
{
ESP_LOGI(TAG, "%.*s", http_request->buffer().size(), http_request->buffer().data());
return http_request->takeBuffer();
}
}
bool get_request_running()
{
if (!http_request.constructed())
{
return false;
}
return http_request->finished();
}
} // namespace
namespace {
extern "C" void onReceive(const uint8_t *mac_addr, const uint8_t *data, int len)
{
const std::string message(data, data + len);
// ESP_LOGI(TAG, "Received data (%s)", message.c_str());
// ESP_LOGI(TAG, "ID: %s - Token: %s", stringSettings.esp_now_door_id.c_str(), stringSettings.esp_now_door_token.c_str());
// Parse the message (msg format: "msg_type:msg_value:msg_token") via find and npos
const size_t pos = message.find(":");
if (pos == std::string::npos) {
// ESP_LOGW(TAG, "Invalid message format");
return;
}
const size_t pos2 = message.find(":", pos + 1);
if (pos2 == std::string::npos) {
// ESP_LOGW(TAG, "Invalid message format");
return;
}
const std::string msg_type = message.substr(0, pos);
const std::string msg_value = message.substr(pos + 1, pos2 - pos - 1);
if (msg_type == "BOBBYHUPE_AN" || msg_type == "BOBBYHUP_AN")
{
ESP_LOGI(TAG, "Activating hupe");
hupe_state = true;
relayHupeTimer = espchrono::millis_clock::now();
return;
}
else if (msg_type == "BOBBYHUPE_AUS")
{
ESP_LOGI(TAG, "Deactivating hupe");
hupe_state = false;
relayHupeTimer = std::nullopt;
return;
}
else if (msg_type == "COMPRESSOR_AN")
{
ESP_LOGI(TAG, "Activating compressor");
compressor_is_an = true;
return;
}
else if (msg_type == "COMPRESSOR_AUS")
{
ESP_LOGI(TAG, "Deactivating compressor");
compressor_is_an = false;
return;
}
else if (msg_type == "COMPRESSOR_TOGGLE")
{
ESP_LOGI(TAG, "Toggling compressor");
compressor_is_an = !compressor_is_an;
return;
}
ESP_LOGI(TAG, "Received message: %s, Type: %s, Value: %s", message.c_str(), msg_type.c_str(), msg_value.c_str());
std::string msg_token{};
if (pos2 + 1 < message.size()) {
msg_token = message.substr(pos2 + 1);
}
if (msg_token.empty()) {
ESP_LOGW(TAG, "No token was send");
return;
}
if (msg_token != stringSettings.esp_now_door_token) {
ESP_LOGW(TAG, "Invalid token (%s)", msg_token.c_str());
return;
}
/*const std::string_view data_str{(const char *)data, size_t(data_len)};
size_t sep_pos = data_str.find(":");
if (std::string_view::npos != sep_pos)
@ -47,12 +189,17 @@ extern "C" void onReceive(const uint8_t *mac_addr, const uint8_t *data, int data
else
{
ESP_LOGW(TAG, "Invalid message: Could not find ':' (%.*s)", data_str.size(), data_str.data());
}
}*/
}
} // namespace
void initESPNow()
{
pinMode(PIN_RELAY_COMPRESSOR, OUTPUT);
pinMode(PIN_RELAY_HUPE, OUTPUT);
digitalWrite(PIN_RELAY_COMPRESSOR, HIGH);
digitalWrite(PIN_RELAY_HUPE, HIGH);
ESP_LOGI(TAG, "Initializing esp-now...");
if (initialized < 1)
@ -120,6 +267,27 @@ void initESPNow()
void handle()
{
digitalWrite(PIN_RELAY_COMPRESSOR, !compressor_is_an);
digitalWrite(PIN_RELAY_HUPE, !hupe_state);
if (relayHupeTimer && espchrono::ago(*relayHupeTimer) > 3s)
{
hupe_state = false;
relayHupeTimer = std::nullopt;
}
else if (relayHupeTimer && espchrono::ago(*relayHupeTimer) <= 3s)
{
hupe_state = true;
}
/*
if (!last_send_ms || espchrono::ago(*last_send_ms) > 1s) {
const auto message = fmt::format("T:{}", espchrono::utc_clock::now().time_since_epoch().count());
send_espnow_message(message);
last_send_ms = espchrono::millis_clock::now();
}
*/
if (initialized < 255 && !(!settings.wifiSettings.wifiApEnabled && (!settings.wifiSettings.wifiStaEnabled && wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::NO_SHIELD) || (wifi_stack::get_wifi_mode() != wifi_mode_t::WIFI_MODE_STA && wifi_stack::get_wifi_mode() != wifi_mode_t::WIFI_MODE_AP && wifi_stack::get_wifi_mode() != wifi_mode_t::WIFI_MODE_APSTA)))
{
initESPNow();
@ -280,7 +448,7 @@ esp_err_t send_espnow_message(std::string_view message)
else
{
const auto timeAfter = espchrono::millis_clock::now();
ESP_LOGI(TAG, "Successfully executed esp_now_send(): Took %lldms", std::chrono::milliseconds{timeAfter-timeBefore}.count());
ESP_LOGI(TAG, "Successfully executed esp_now_send() with message %.*s (Took %lldms)", message.size(), message.data(), std::chrono::milliseconds{timeAfter-timeBefore}.count());
}
}
return ESP_OK;

View File

@ -6,6 +6,7 @@
#include <string_view>
#include <vector>
#include <esp_now.h>
#include <tl/expected.hpp>
namespace espnow {
extern uint16_t lastYear;
@ -26,5 +27,11 @@ void initESPNow();
void handle();
void onRecvTs(uint64_t millis, bool isFromBobbycar = false);
esp_err_t send_espnow_message(std::string_view message);
namespace ifttt {
void setup_request();
tl::expected<void, std::string> start_qr_request(std::string event);
tl::expected<std::string, std::string> check_request();
bool get_request_running();
} // namespace ifttt
} // namespace espnow
#endif

View File

@ -61,6 +61,12 @@ StringSettings makeDefaultStringSettings()
.otaServerBranch = {},
#endif
.webserver_password = {},
#ifdef FEATURE_ESPNOW
.esp_now_door_id = {},
.esp_now_door_token = {},
#endif
.ifttt_key = {},
.esp_now_ifttt_door_id = {},
};
}
} // namespace presets

View File

@ -58,13 +58,11 @@ struct StringSettings
std::string webserver_password;
#ifdef FEATURE_ESPNOW
struct ConfiguredWirelessDoors {
std::string doorId;
std::string doorToken;
};
std::array<ConfiguredWirelessDoors, 5> wirelessDoors;
std::string esp_now_door_id;
std::string esp_now_door_token;
#endif
std::string ifttt_key;
std::string esp_now_ifttt_door_id;
};
template<typename T>
@ -141,17 +139,11 @@ void StringSettings::executeForEveryCommonSetting(T &&callable)
callable("webpw", webserver_password);
#ifdef FEATURE_ESPNOW
callable("doorId0", wirelessDoors[0].doorId);
callable("doorToken0", wirelessDoors[0].doorToken);
callable("doorId1", wirelessDoors[1].doorId);
callable("doorToken1", wirelessDoors[1].doorToken);
callable("doorId2", wirelessDoors[2].doorId);
callable("doorToken2", wirelessDoors[2].doorToken);
callable("doorId3", wirelessDoors[3].doorId);
callable("doorToken3", wirelessDoors[3].doorToken);
callable("doorId4", wirelessDoors[4].doorId);
callable("doorToken4", wirelessDoors[4].doorToken);
callable("espnow_doorId", esp_now_door_id);
callable("espnow_doorTo", esp_now_door_token);
#endif
callable("iftttkey", ifttt_key);
callable("espnowiftt", esp_now_ifttt_door_id);
}
template<typename T>

View File

@ -1,4 +1,4 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x10000, 0x5000,
otadata, data, ota, 0x15000, 0x2000,
app0, app, ota_0, 0x20000, 0x1F0000,
app0, app, ota_0, 0x20000, 0x3E0000,

1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x10000 0x5000
3 otadata data ota 0x15000 0x2000
4 app0 app ota_0 0x20000 0x1F0000 0x3E0000

1736
sdkconfig_relay Normal file

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,7 @@ VALID_CONFIGS=(
"greyhash"
"nofeatures"
"allfeatures"
"relay"
)
print_usage() {