Skip to content

Commit

Permalink
Merge pull request #22 from SeedLabs-it/7-rendering-apps-based-on-mqt…
Browse files Browse the repository at this point in the history
…t-data
  • Loading branch information
carlhampuswall authored Jan 17, 2024
2 parents 5b32ee0 + a9697f3 commit 55a964e
Show file tree
Hide file tree
Showing 14 changed files with 346 additions and 217 deletions.
3 changes: 2 additions & 1 deletion firmware/src/app_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,13 @@ struct AppState
ConnectivityState connectivity_state;
ProximityState proximiti_state;
ScreenState screen_state;
cJSON *apps;
};

struct EntityStateUpdate
{
std::string app_id;
char state[128] = "";
char state[256] = "";
char app_slug[48] = "";
bool changed = false;
bool sent = false;
Expand Down
21 changes: 21 additions & 0 deletions firmware/src/app_task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ AppTask::AppTask(
assert(display_task != nullptr);
#endif

app_sync_queue_ = xQueueCreate(2, sizeof(cJSON *));
assert(app_sync_queue_ != NULL);

log_queue_ = xQueueCreate(10, sizeof(std::string *));
assert(log_queue_ != NULL);

Expand Down Expand Up @@ -189,6 +192,19 @@ void AppTask::run()
app_state.connectivity_state = latest_connectivity_state_;
}

if (xQueueReceive(app_sync_queue_, &apps_, 0) == pdTRUE)
{
ESP_LOGD("app_task", "App sync requested!");
#if SK_NETWORKING // Should this be here??
apps->reload(networking_task_->getApps());

// SHOULD BE RELEASE LATER WHEN RELOAD IS DONE
networking_task_->unlock();
#endif

// cJSON_Delete(apps_);
}

if (xQueueReceive(knob_state_queue_, &latest_state_, 0) == pdTRUE)
{

Expand Down Expand Up @@ -416,6 +432,11 @@ QueueHandle_t AppTask::getSensorsStateQueue()
return sensors_status_queue_;
}

QueueHandle_t AppTask::getAppSyncQueue()
{
return app_sync_queue_;
}

void AppTask::addListener(QueueHandle_t queue)
{
listeners_.push_back(queue);
Expand Down
6 changes: 6 additions & 0 deletions firmware/src/app_task.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
class AppTask : public Task<AppTask>,
public Logger
{

friend class Task<AppTask>; // Allow base Task to invoke protected run()

public:
Expand All @@ -33,6 +34,7 @@ class AppTask : public Task<AppTask>,

QueueHandle_t getConnectivityStateQueue();
QueueHandle_t getSensorsStateQueue();
QueueHandle_t getAppSyncQueue();

protected:
void run();
Expand Down Expand Up @@ -72,12 +74,16 @@ class AppTask : public Task<AppTask>,
ConnectivityState latest_connectivity_state_ = {};
SensorsState latest_sensors_state_ = {};

cJSON *apps_ = NULL;

QueueHandle_t log_queue_;
QueueHandle_t knob_state_queue_;

QueueHandle_t connectivity_status_queue_;
QueueHandle_t sensors_status_queue_;

QueueHandle_t app_sync_queue_;

SerialProtocolPlaintext plaintext_protocol_;
SerialProtocolProtobuf proto_protocol_;

Expand Down
53 changes: 41 additions & 12 deletions firmware/src/apps/apps.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once
#include "apps.h"
#include "menu.h"
#include "settings.h"

#include <typeinfo>
#include <iterator>
Expand Down Expand Up @@ -103,6 +104,34 @@ void Apps::setActive(uint8_t id)
}
}

void Apps::reload(cJSON *apps_)
{
clear();

uint16_t app_position = 1;

cJSON *json_app = NULL;
cJSON_ArrayForEach(json_app, apps_)
{
cJSON *json_app_slug = cJSON_GetObjectItemCaseSensitive(json_app, "app_slug");
cJSON *json_app_id = cJSON_GetObjectItemCaseSensitive(json_app, "app_id");
cJSON *json_friendly_name = cJSON_GetObjectItemCaseSensitive(json_app, "friendly_name");

// ESP_LOGD("apps.cpp", "%s", json_app_id->valuestring);

loadApp(app_position, std::string(json_app_slug->valuestring), json_app_id->valuestring, json_friendly_name->valuestring);

app_position++;
}

SettingsApp *settings_app = new SettingsApp(this->spr_);
add(app_position, settings_app);

updateMenu();
setActive(0);
cJSON_Delete(apps_);
}

void Apps::updateMenu()
{
// re - generate new menu based on loaded apps
Expand Down Expand Up @@ -133,56 +162,56 @@ void Apps::updateMenu()
}

// settings and menu apps kept aside for a reason. We will add them manually later
void Apps::loadApp(uint8_t position, std::string app_slug, std::string app_id, char entity_name[32])
void Apps::loadApp(uint8_t position, std::string app_slug, std::string app_id, std::string friendly_name)
{
if (position < 1)
{
ESP_LOGE("apps.cpp", "can't load app at %d %s %s %s", position, app_slug.c_str(), app_id.c_str(), entity_name);
ESP_LOGE("apps.cpp", "can't load app at %d %s %s %s", position, app_slug.c_str(), app_id.c_str(), friendly_name);
return;
}

ESP_LOGD("apps.cpp", "loading app %d %s %s %s", position, app_slug.c_str(), app_id.c_str(), entity_name);
ESP_LOGD("apps.cpp", "loading app %d %s %s %s", position, app_slug.c_str(), app_id.c_str(), friendly_name);
if (app_slug.compare(APP_SLUG_CLIMATE) == 0)
{
ClimateApp *app = new ClimateApp(this->spr_, app_id);
add(position, app);
ESP_LOGD("apps.cpp", "added app %d %s %s %s", position, app_slug.c_str(), app_id.c_str(), entity_name);
ESP_LOGD("apps.cpp", "added app %d %s %s %s", position, app_slug.c_str(), app_id.c_str(), friendly_name);
}
else if (app_slug.compare(APP_SLUG_3D_PRINTER) == 0)
{
PrinterChamberApp *app = new PrinterChamberApp(this->spr_, app_id);
add(position, app);
ESP_LOGD("apps.cpp", "added app %d %s %s %s", position, app_slug.c_str(), app_id.c_str(), entity_name);
ESP_LOGD("apps.cpp", "added app %d %s %s %s", position, app_slug.c_str(), app_id.c_str(), friendly_name);
}
else if (app_slug.compare(APP_SLUG_BLINDS) == 0)
{
BlindsApp *app = new BlindsApp(this->spr_, app_id);
add(position, app);
ESP_LOGD("apps.cpp", "added app %d %s %s %s", position, app_slug.c_str(), app_id.c_str(), entity_name);
ESP_LOGD("apps.cpp", "added app %d %s %s %s", position, app_slug.c_str(), app_id.c_str(), friendly_name);
}
else if (app_slug.compare(APP_SLUG_LIGHT_DIMMER) == 0)
{
LightDimmerApp *app = new LightDimmerApp(this->spr_, app_id);
LightDimmerApp *app = new LightDimmerApp(this->spr_, app_id, friendly_name);
add(position, app);
ESP_LOGD("apps.cpp", "added app %d %s %s %s", position, app_slug.c_str(), app_id.c_str(), entity_name);
ESP_LOGD("apps.cpp", "added app %d %s %s %s", position, app_slug.c_str(), app_id.c_str(), friendly_name);
}
else if (app_slug.compare(APP_SLUG_LIGHT_SWITCH) == 0)
{
LightSwitchApp *app = new LightSwitchApp(this->spr_, app_id);
LightSwitchApp *app = new LightSwitchApp(this->spr_, app_id, friendly_name);
add(position, app);
ESP_LOGD("apps.cpp", "added app %d %s %s %s", position, app_slug.c_str(), app_id.c_str(), entity_name);
ESP_LOGD("apps.cpp", "added app %d %s %s %s", position, app_slug.c_str(), app_id.c_str(), friendly_name);
}
else if (app_slug.compare(APP_SLUG_MUSIC) == 0)
{
MusicApp *app = new MusicApp(this->spr_, app_id);
add(position, app);
ESP_LOGD("apps.cpp", "added app %d %s %s %s", position, app_slug.c_str(), app_id.c_str(), entity_name);
ESP_LOGD("apps.cpp", "added app %d %s %s %s", position, app_slug.c_str(), app_id.c_str(), friendly_name);
}
else if (app_slug.compare(APP_SLUG_STOPWATCH) == 0)
{
StopwatchApp *app = new StopwatchApp(this->spr_, app_id);
add(position, app);
ESP_LOGD("apps.cpp", "added app %d %s %s %s", position, app_slug.c_str(), app_id.c_str(), entity_name);
ESP_LOGD("apps.cpp", "added app %d %s %s %s", position, app_slug.c_str(), app_id.c_str(), friendly_name);
}
else
{
Expand Down
43 changes: 22 additions & 21 deletions firmware/src/apps/apps.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,31 @@
class Apps
{
public:
Apps();
void add(uint8_t id, App *app);
void clear();
EntityStateUpdate update(AppState state);
TFT_eSprite *renderActive();
void setActive(uint8_t id);
uint8_t navigationNext();
PB_SmartKnobConfig getActiveMotorConfig();
void setSprite(TFT_eSprite *spr_);
void loadApp(uint8_t position, std::string app_slug, std::string app_id, char entity_name[32]);
void updateMenu();
Apps();
void add(uint8_t id, App *app);
void clear();
EntityStateUpdate update(AppState state);
TFT_eSprite *renderActive();
void setActive(uint8_t id);
uint8_t navigationNext();
PB_SmartKnobConfig getActiveMotorConfig();
void setSprite(TFT_eSprite *spr_);
void loadApp(uint8_t position, std::string app_slug, std::string app_id, std::string friendly_name);
void updateMenu();
void reload(cJSON *apps_);

private:
QueueHandle_t mutex;
std::map<std::string, std::shared_ptr<App>> apps;
// std::vector<std::unique_ptr<App>> apps;
uint8_t active_id = 0;
QueueHandle_t mutex;
std::map<std::string, std::shared_ptr<App>> apps;
// std::vector<std::unique_ptr<App>> apps;
uint8_t active_id = 0;

TFT_eSprite *spr_ = nullptr;
std::shared_ptr<App> active_app = nullptr;
TFT_eSprite *spr_ = nullptr;
std::shared_ptr<App> active_app = nullptr;

TFT_eSprite *rendered_spr_;
TFT_eSprite *rendered_spr_;

// App *find(uint8_t id);
void lock();
void unlock();
// App *find(uint8_t id);
void lock();
void unlock();
};
37 changes: 18 additions & 19 deletions firmware/src/apps/light_dimmer.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#include "light_dimmer.h"
#include "cJSON.h"

LightDimmerApp::LightDimmerApp(TFT_eSprite *spr_, std::string entity_name) : App(spr_)
LightDimmerApp::LightDimmerApp(TFT_eSprite *spr_, std::string app_id, std::string friendly_name) : App(spr_)
{
// sprintf(author, "%s", "Beethoven");
// sprintf(track, "%s", "Moonlight Sonata");
this->entity_name = entity_name;
this->app_id = app_id;
this->friendly_name = friendly_name;

motor_config = PB_SmartKnobConfig{
0,
Expand All @@ -28,7 +29,6 @@ LightDimmerApp::LightDimmerApp(TFT_eSprite *spr_, std::string entity_name) : App

big_icon = light_top_80;
small_icon = light_top_40;
friendly_name = "Lights";
}

uint8_t LightDimmerApp::navigationNext()
Expand Down Expand Up @@ -58,23 +58,22 @@ EntityStateUpdate LightDimmerApp::updateStateFromKnob(PB_SmartKnobState state)

EntityStateUpdate new_state;

new_state.app_id = "light_switch-light.virtual_light_1";
cJSON *json = cJSON_CreateObject();
cJSON_AddNumberToObject(json, "brightness", int(current_position * 2.55));
cJSON_AddNumberToObject(json, "color_temp", 0);
cJSON *rgb_array = cJSON_CreateArray();
cJSON_AddItemToArray(rgb_array, cJSON_CreateNumber(255));
cJSON_AddItemToArray(rgb_array, cJSON_CreateNumber(255));
cJSON_AddItemToArray(rgb_array, cJSON_CreateNumber(255));
cJSON_AddItemToObject(json, "rgb_color", rgb_array);
if (last_position != current_position)
{
new_state.app_id = app_id;
cJSON *json = cJSON_CreateObject();
cJSON_AddNumberToObject(json, "brightness", int(current_position * 2.55));
cJSON_AddNumberToObject(json, "color_temp", 0);
cJSON *rgb_array = cJSON_CreateArray();
cJSON_AddItemToArray(rgb_array, cJSON_CreateNumber(255));
cJSON_AddItemToArray(rgb_array, cJSON_CreateNumber(255));
cJSON_AddItemToArray(rgb_array, cJSON_CreateNumber(255));
cJSON_AddItemToObject(json, "rgb_color", rgb_array);

sprintf(new_state.state, "%s", cJSON_PrintUnformatted(json));
sprintf(new_state.state, "%s", cJSON_PrintUnformatted(json));

// PREVENTS MEMORY LEAK???
cJSON_Delete(json);
cJSON_Delete(json);

if (last_position != current_position)
{
last_position = current_position;
new_state.changed = true;
sprintf(new_state.app_slug, "%s", APP_SLUG_LIGHT_DIMMER);
Expand Down Expand Up @@ -137,7 +136,7 @@ TFT_eSprite *LightDimmerApp::render()
spr_->drawBitmap(center_h - icon_size / 2, center_v - icon_size / 2 - offset_vertical, lamp_regular, icon_size, icon_size, off_lamp_color, off_background);
spr_->setTextColor(off_lamp_color);
spr_->setFreeFont(&Roboto_Thin_24);
spr_->drawString("Workbench", center_h, center_v + icon_size / 2 + 30 - offset_vertical, 1);
spr_->drawString(friendly_name.c_str(), center_h, center_v + icon_size / 2 + 30 - offset_vertical, 1);
spr_->drawString("off", center_h, center_v + icon_size / 2 + 60 - offset_vertical, 1);

// draw dot movong path
Expand All @@ -152,7 +151,7 @@ TFT_eSprite *LightDimmerApp::render()
spr_->drawBitmap(center_h - icon_size / 2, center_v - icon_size / 2 - offset_vertical, lamp_solid, icon_size, icon_size, on_lamp_color, on_background);
spr_->setTextColor(on_lamp_color);
spr_->setFreeFont(&Roboto_Thin_24);
spr_->drawString("Workbench", center_h, center_v + icon_size / 2 + 30 - offset_vertical, 1);
spr_->drawString(friendly_name.c_str(), center_h, center_v + icon_size / 2 + 30 - offset_vertical, 1);
spr_->drawString(buf_, center_h, center_v + icon_size / 2 + 60 - offset_vertical, 1);

// draw dot movong path
Expand Down
5 changes: 3 additions & 2 deletions firmware/src/apps/light_dimmer.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
class LightDimmerApp : public App
{
public:
LightDimmerApp(TFT_eSprite *spr_, std::string entity_name);
LightDimmerApp(TFT_eSprite *spr_, std::string app_id, std::string friendly_name);
TFT_eSprite *render();
EntityStateUpdate updateStateFromKnob(PB_SmartKnobState state);
void updateStateFromSystem(AppState state);
Expand All @@ -17,7 +17,8 @@ class LightDimmerApp : public App
uint16_t current_position = 0;
uint16_t last_position = 0;
uint8_t num_positions = 0;
std::string entity_name;
std::string app_id;
std::string friendly_name;
// needed for UI
float sub_position_unit = 0;
float adjusted_sub_position = 0;
Expand Down
Loading

0 comments on commit 55a964e

Please sign in to comment.