Initial commit

main
Jerry Aldrich 2 days ago
commit b42e66e495
  1. 5
      README.md
  2. BIN
      app.png
  3. 18
      application.fam
  4. 272
      lazylight.c

@ -0,0 +1,5 @@
## Lazy Light
Simple Flipper App for controlling lights/fans in my apartment.
Plz do not judge the C code, it was written quickly and without desire for beauty.

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 B

@ -0,0 +1,18 @@
App(
appid="lazylight",
name="Lazy Light",
apptype=FlipperAppType.EXTERNAL,
entry_point="lazylight_main",
stack_size=4 * 1024,
requires=[
"subghz",
"gui",
],
order=10,
fap_icon="app.png",
fap_category="Sub-GHz",
fap_icon_assets="assets",
fap_description="Control lights/fans in Jerry's apartment",
fap_author="@jerryaldrichiii",
fap_version="0.1",
)

@ -0,0 +1,272 @@
#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;
}
Loading…
Cancel
Save