You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
272 lines
8.5 KiB
272 lines
8.5 KiB
#include <gui/gui.h>
|
|
#include <gui/view_dispatcher.h>
|
|
#include <gui/modules/submenu.h>
|
|
|
|
#include <devices/cc1101_int/cc1101_int_interconnect.h>
|
|
#include <devices/devices.h>
|
|
#include <flipper_format_i.h>
|
|
#include <lib/subghz/transmitter.h>
|
|
#include <subghz_protocol_registry.h>
|
|
|
|
/* ===================== Views ===================== */
|
|
|
|
typedef enum {
|
|
ViewIndexMainMenu,
|
|
ViewIndexMasterBedroom,
|
|
ViewIndexGuestBedroom,
|
|
ViewIndexOffice,
|
|
ViewIndexCount,
|
|
} ViewIndex;
|
|
|
|
/* ===================== Menu Indexes ===================== */
|
|
|
|
typedef enum {
|
|
MainMenuMasterBedroom,
|
|
MainMenuGuestBedroom,
|
|
MainMenuOffice,
|
|
} MainMenuIndex;
|
|
|
|
typedef enum {
|
|
RoomActionToggleLight,
|
|
RoomActionFanOff,
|
|
RoomActionFanLow,
|
|
RoomActionFanMedium,
|
|
RoomActionFanHigh,
|
|
} RoomActionIndex;
|
|
|
|
/* ===================== App Struct ===================== */
|
|
|
|
typedef struct {
|
|
ViewDispatcher* view_dispatcher;
|
|
Submenu* main_menu;
|
|
Submenu* master_menu;
|
|
Submenu* guest_menu;
|
|
Submenu* office_menu;
|
|
ViewIndex current_view;
|
|
} LazyLightApp;
|
|
|
|
/* ===================== RF Transmit Helper ===================== */
|
|
|
|
static void lazylight_tx(uint32_t key) {
|
|
char* protocol = "CAME";
|
|
|
|
SubGhzEnvironment* env = subghz_environment_alloc();
|
|
subghz_environment_set_protocol_registry(
|
|
env, (void*)&subghz_protocol_registry);
|
|
|
|
SubGhzTransmitter* tx = subghz_transmitter_alloc_init(env, protocol);
|
|
|
|
FlipperFormat* ff = flipper_format_string_alloc();
|
|
|
|
uint32_t bits = 12;
|
|
|
|
uint8_t data[8] = {0};
|
|
|
|
data[7] = (uint8_t)(key & 0xFFU);
|
|
data[6] = (uint8_t)((key >> 8) & 0x0FU);
|
|
|
|
flipper_format_insert_or_update_string_cstr(ff, "Protocol", "CAME");
|
|
flipper_format_insert_or_update_uint32(ff, "Bit", &bits, 1);
|
|
flipper_format_insert_or_update_hex(ff, "Key", data, COUNT_OF(data));
|
|
flipper_format_rewind(ff);
|
|
|
|
furi_check(
|
|
subghz_transmitter_deserialize(tx, ff) ==
|
|
SubGhzProtocolStatusOk);
|
|
|
|
subghz_devices_init();
|
|
const SubGhzDevice* dev =
|
|
subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
|
|
|
|
subghz_devices_begin(dev);
|
|
subghz_devices_reset(dev);
|
|
subghz_devices_load_preset(
|
|
dev, FuriHalSubGhzPresetOok650Async, NULL);
|
|
subghz_devices_set_frequency(dev, 303900000);
|
|
|
|
furi_hal_power_suppress_charge_enter();
|
|
|
|
if(subghz_devices_start_async_tx(
|
|
dev, subghz_transmitter_yield, tx)) {
|
|
while(!subghz_devices_is_async_complete_tx(dev)) {
|
|
furi_delay_ms(50);
|
|
}
|
|
subghz_devices_stop_async_tx(dev);
|
|
}
|
|
|
|
furi_hal_power_suppress_charge_exit();
|
|
|
|
subghz_devices_sleep(dev);
|
|
subghz_devices_end(dev);
|
|
subghz_devices_deinit();
|
|
|
|
flipper_format_free(ff);
|
|
subghz_transmitter_free(tx);
|
|
subghz_environment_free(env);
|
|
}
|
|
|
|
/* ===================== Navigation ===================== */
|
|
|
|
static bool navigation_callback(void* ctx) {
|
|
furi_check(ctx);
|
|
|
|
LazyLightApp* app = ctx;
|
|
|
|
if(app->current_view == ViewIndexMainMenu) {
|
|
view_dispatcher_stop(app->view_dispatcher);
|
|
} else {
|
|
app->current_view = ViewIndexMainMenu;
|
|
view_dispatcher_switch_to_view(
|
|
app->view_dispatcher, ViewIndexMainMenu);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/* ===================== Menu Callbacks ===================== */
|
|
|
|
static void main_menu_cb(void* ctx, uint32_t index) {
|
|
LazyLightApp* app = ctx;
|
|
app->current_view = index + 1;
|
|
view_dispatcher_switch_to_view(
|
|
app->view_dispatcher, app->current_view);
|
|
}
|
|
|
|
static void master_cb(void* ctx, uint32_t index) {
|
|
UNUSED(ctx);
|
|
if(index == RoomActionToggleLight) lazylight_tx(0x1F6);
|
|
if(index == RoomActionFanOff) lazylight_tx(0x1F5);
|
|
if(index == RoomActionFanLow) lazylight_tx(0x1FD);
|
|
if(index == RoomActionFanMedium) lazylight_tx(0x1FB);
|
|
if(index == RoomActionFanHigh) lazylight_tx(0x1F7);
|
|
}
|
|
|
|
static void guest_cb(void* ctx, uint32_t index) {
|
|
UNUSED(ctx);
|
|
if(index == RoomActionToggleLight) lazylight_tx(0x66);
|
|
if(index == RoomActionFanOff) lazylight_tx(0x65);
|
|
if(index == RoomActionFanLow) lazylight_tx(0x6D);
|
|
if(index == RoomActionFanMedium) lazylight_tx(0x6B);
|
|
if(index == RoomActionFanHigh) lazylight_tx(0x67);
|
|
}
|
|
|
|
static void office_cb(void* ctx, uint32_t index) {
|
|
UNUSED(ctx);
|
|
if(index == RoomActionToggleLight) lazylight_tx(0xE6);
|
|
if(index == RoomActionFanOff) lazylight_tx(0xE5);
|
|
if(index == RoomActionFanLow) lazylight_tx(0xED);
|
|
if(index == RoomActionFanMedium) lazylight_tx(0xEB);
|
|
if(index == RoomActionFanHigh) lazylight_tx(0xE7);
|
|
}
|
|
|
|
/* ===================== App Setup ===================== */
|
|
|
|
static LazyLightApp* app_alloc() {
|
|
LazyLightApp* app = malloc(sizeof(LazyLightApp));
|
|
Gui* gui = furi_record_open(RECORD_GUI);
|
|
|
|
app->view_dispatcher = view_dispatcher_alloc();
|
|
view_dispatcher_attach_to_gui(
|
|
app->view_dispatcher, gui, ViewDispatcherTypeFullscreen);
|
|
view_dispatcher_set_navigation_event_callback(
|
|
app->view_dispatcher, navigation_callback);
|
|
view_dispatcher_set_event_callback_context(
|
|
app->view_dispatcher, app);
|
|
|
|
/* Main Menu */
|
|
app->main_menu = submenu_alloc();
|
|
submenu_add_item(app->main_menu, "Master Bedroom",
|
|
MainMenuMasterBedroom, main_menu_cb, app);
|
|
submenu_add_item(app->main_menu, "Guest Bedroom",
|
|
MainMenuGuestBedroom, main_menu_cb, app);
|
|
submenu_add_item(app->main_menu, "Office",
|
|
MainMenuOffice, main_menu_cb, app);
|
|
|
|
/* Master Bedroom */
|
|
app->master_menu = submenu_alloc();
|
|
submenu_add_item(app->master_menu, "Toggle Light",
|
|
RoomActionToggleLight, master_cb, app);
|
|
submenu_add_item(app->master_menu, "Turn Fan Off",
|
|
RoomActionFanOff, master_cb, app);
|
|
submenu_add_item(app->master_menu, "Set Fan Low",
|
|
RoomActionFanLow, master_cb, app);
|
|
submenu_add_item(app->master_menu, "Set Fan Medium",
|
|
RoomActionFanMedium, master_cb, app);
|
|
submenu_add_item(app->master_menu, "Set Fan High",
|
|
RoomActionFanHigh, master_cb, app);
|
|
|
|
/* Guest Bedroom */
|
|
app->guest_menu = submenu_alloc();
|
|
submenu_add_item(app->guest_menu, "Toggle Light",
|
|
RoomActionToggleLight, guest_cb, app);
|
|
submenu_add_item(app->guest_menu, "Turn Fan Off",
|
|
RoomActionFanOff, guest_cb, app);
|
|
submenu_add_item(app->guest_menu, "Set Fan Low",
|
|
RoomActionFanLow, guest_cb, app);
|
|
submenu_add_item(app->guest_menu, "Set Fan Medium",
|
|
RoomActionFanMedium, guest_cb, app);
|
|
submenu_add_item(app->guest_menu, "Set Fan High",
|
|
RoomActionFanHigh, guest_cb, app);
|
|
|
|
/* Office */
|
|
app->office_menu = submenu_alloc();
|
|
submenu_add_item(app->office_menu, "Toggle Light",
|
|
RoomActionToggleLight, office_cb, app);
|
|
submenu_add_item(app->office_menu, "Turn Fan Off",
|
|
RoomActionFanOff, office_cb, app);
|
|
submenu_add_item(app->office_menu, "Set Fan Low",
|
|
RoomActionFanLow, office_cb, app);
|
|
submenu_add_item(app->office_menu, "Set Fan Medium",
|
|
RoomActionFanMedium, office_cb, app);
|
|
submenu_add_item(app->office_menu, "Set Fan High",
|
|
RoomActionFanHigh, office_cb, app);
|
|
|
|
view_dispatcher_add_view(
|
|
app->view_dispatcher,
|
|
ViewIndexMainMenu,
|
|
submenu_get_view(app->main_menu));
|
|
view_dispatcher_add_view(
|
|
app->view_dispatcher,
|
|
ViewIndexMasterBedroom,
|
|
submenu_get_view(app->master_menu));
|
|
view_dispatcher_add_view(
|
|
app->view_dispatcher,
|
|
ViewIndexGuestBedroom,
|
|
submenu_get_view(app->guest_menu));
|
|
view_dispatcher_add_view(
|
|
app->view_dispatcher,
|
|
ViewIndexOffice,
|
|
submenu_get_view(app->office_menu));
|
|
|
|
app->current_view = ViewIndexMainMenu;
|
|
return app;
|
|
}
|
|
|
|
static void app_free(LazyLightApp* app) {
|
|
view_dispatcher_remove_view(app->view_dispatcher, ViewIndexMainMenu);
|
|
view_dispatcher_remove_view(app->view_dispatcher, ViewIndexMasterBedroom);
|
|
view_dispatcher_remove_view(app->view_dispatcher, ViewIndexGuestBedroom);
|
|
view_dispatcher_remove_view(app->view_dispatcher, ViewIndexOffice);
|
|
|
|
view_dispatcher_free(app->view_dispatcher);
|
|
submenu_free(app->main_menu);
|
|
submenu_free(app->master_menu);
|
|
submenu_free(app->guest_menu);
|
|
submenu_free(app->office_menu);
|
|
furi_record_close(RECORD_GUI);
|
|
free(app);
|
|
}
|
|
|
|
/* ===================== Entry ===================== */
|
|
|
|
int32_t lazylight_main(void* arg) {
|
|
UNUSED(arg);
|
|
|
|
LazyLightApp* app = app_alloc();
|
|
view_dispatcher_switch_to_view(
|
|
app->view_dispatcher, ViewIndexMainMenu);
|
|
view_dispatcher_run(app->view_dispatcher);
|
|
app_free(app);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|