-
Couldn't load subscription status.
- Fork 157
Support for OMOTE Hub #100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Stuckya
wants to merge
34
commits into
OMOTE-Community:main
Choose a base branch
from
Stuckya:hub-support
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 16 commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
2139673
feat: attempt to add hub support with backend abstraction.
Stuckya 99b2042
feat: adds commandType which indicates key press action like short of…
Stuckya 00fde23
chore: fix espnow serial prints to be more consistent.
Stuckya 82289f5
chore: update include_hal_esp32 import to match.
Stuckya ad9bed5
chore: update include_hal_windows_linux import to match.
Stuckya 246a4bc
chore: wrap espnowBackend include so it isn't included if disabled.
Stuckya 2be69f1
feat: add different key command modes to appleTV scene.
Stuckya 5c9cb71
chore: adds conditional to device_appleTV, so we don't try to registe…
Stuckya 9a4e96a
chore: restores settings.json.
Stuckya baa3f33
chore: moves naming consistency changes to another branch.
Stuckya 162ddc1
chore: reverts old mqtt restore.
Stuckya 714c200
feat: adds hub support to some other devices for testing.
Stuckya 8cc787b
chore: fixes formatting and adds helper.
Stuckya e85984f
chore: replaces mac address in secrets.
Stuckya 4334a05
chore: renames backend to transport to be consistent with hub domain.
Stuckya a1840c1
chore: fixes compiler bug when hub functionality is disabled.
Stuckya a879e08
chore: adds empty string back to executeCommandWithData.
Stuckya 84f15a8
feat: simplify hub build flag.
Stuckya 38fa0b8
chore: remove duplicate library include.
Stuckya 5e914be
chore: fix linux / macos builds.
Stuckya 5e3450f
chore: add stdlib to arduinoLayer.h in MacOS builds.
Stuckya 160ac45
Revert "chore: fix linux / macos builds."
Stuckya f37a860
chore: fixes compiler issues.
Stuckya 99a4e83
chore: merges main.
Stuckya c17f225
chore: remove unused code from merge.
Stuckya a0f8bbb
chore: remove non-critical changes for separate PRs
Stuckya 3c05a2b
fix: fixes build error.
Stuckya 6464579
chore: restores src/scenes/scene_appleTV.cpp to limit hub changes on …
Stuckya 1d0b19e
chore: restores src/guis/gui_irReceiver.h to limit hub changes on main.
Stuckya 2987b56
chore: restores src/devices/mediaPlayer/device_appleTV/gui_appleTV.cp…
Stuckya a56be74
chore: updates formatting for appleTV device.
Stuckya 5075b6c
chore: improves formatting of hub enablement in devices.
Stuckya af3ce37
chore: merges main and resolves conflicts.
Stuckya ca2d26d
fix: resolves break in hub functionality from merging main.
Stuckya File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,3 +5,4 @@ | |
| .vscode/launch.json | ||
| .vscode/ipch | ||
| src/secrets_override.h | ||
| **/.DS_Store | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| #include <esp_now.h> | ||
| #include <WiFi.h> | ||
| #include <string> | ||
| #include <sstream> | ||
| #include <nlohmann/json.hpp> | ||
| #include "espnow_hal_esp32.h" | ||
| #include <esp_wifi.h> | ||
| #include "secrets.h" | ||
|
|
||
| using json = nlohmann::json; | ||
|
|
||
| // Define the MAC address of the Raspberry Pi hub | ||
| // This should be defined in secrets.h as ESPNOW_HUB_MAC | ||
| // Example: #define ESPNOW_HUB_MAC {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC} | ||
| uint8_t hub_mac[6] = ESPNOW_HUB_MAC; | ||
| esp_now_peer_info_t hub_peer; | ||
|
|
||
| // Callback for ESP-NOW received data | ||
| tAnnounceEspNowMessage_cb thisAnnounceEspNowMessage_cb = NULL; | ||
| void onDataReceived(const uint8_t *mac_addr, const uint8_t *data, int data_len) { | ||
| if (thisAnnounceEspNowMessage_cb == NULL) return; | ||
|
|
||
| // Convert MAC to string for logging | ||
| char macStr[18]; | ||
| snprintf(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X", | ||
| mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); | ||
|
|
||
| // Serial.printf("ESP-NOW message received from %s\n", macStr); | ||
|
|
||
| try { | ||
| // Try to parse the received data as MessagePack | ||
| auto unpacked_json = json::from_msgpack(data, data + data_len); | ||
|
|
||
| // Forward to callback | ||
| thisAnnounceEspNowMessage_cb(unpacked_json); | ||
| } catch (const std::exception& e) { | ||
| Serial.printf("Error parsing ESP-NOW message: %s\n", e.what()); | ||
| } | ||
| } | ||
|
|
||
| void set_announceEspNowMessage_cb_HAL(tAnnounceEspNowMessage_cb pAnnounceEspNowMessage_cb) { | ||
| thisAnnounceEspNowMessage_cb = pAnnounceEspNowMessage_cb; | ||
| } | ||
|
|
||
| void init_espnow_HAL(void) { | ||
| Serial.println("Starting ESP-NOW"); | ||
| // Set WiFi mode to station (required for ESP-NOW) | ||
| WiFi.mode(WIFI_STA); | ||
| esp_wifi_set_channel(8, WIFI_SECOND_CHAN_NONE); | ||
|
|
||
| // Initialize ESP-NOW | ||
| if (esp_now_init() != ESP_OK) { | ||
| Serial.println("Error initializing ESP-NOW"); | ||
| return; | ||
| } | ||
|
|
||
| // Register callbacks | ||
| esp_now_register_recv_cb(onDataReceived); | ||
|
|
||
| // Register hub as peer | ||
| memcpy(hub_peer.peer_addr, hub_mac, 6); | ||
| // Setting channel0 defaults to existing channel setting | ||
| hub_peer.channel = 0; | ||
| hub_peer.encrypt = false; | ||
|
|
||
| // Add peer | ||
| if (esp_now_add_peer(&hub_peer) != ESP_OK) { | ||
| Serial.println("Failed to add hub peer"); | ||
| return; | ||
| } | ||
|
|
||
| Serial.println("ESP-NOW initialized successfully"); | ||
| } | ||
|
|
||
| void espnow_loop_HAL() { | ||
| // Nothing to do in the loop for ESP-NOW | ||
| // ESP-NOW callbacks are handled by the ESP32 in the background | ||
| } | ||
|
|
||
| bool publishEspNowMessage_HAL(json payload) { | ||
| // Pack the JSON into MessagePack format | ||
| std::vector<std::uint8_t> packed_json = json::to_msgpack(payload); | ||
|
|
||
| if (packed_json.size() > 250) { | ||
| Serial.println("Error: Message exceeds ESP-NOW maximum size"); | ||
| return false; | ||
| } | ||
|
|
||
| // Send the message | ||
| esp_err_t result = esp_now_send(hub_peer.peer_addr, packed_json.data(), packed_json.size()); | ||
|
|
||
| if (result == ESP_OK) { | ||
| // Serial.println("ESP-NOW sent message with success"); | ||
| return true; | ||
| } | ||
|
|
||
| Serial.println("ESP-NOW failed to send message"); | ||
| return false; | ||
| } | ||
|
|
||
| void espnow_shutdown_HAL() { | ||
| // Unregister peer | ||
| esp_now_del_peer(hub_peer.peer_addr); | ||
|
|
||
| // Deinitialize ESP-NOW | ||
| esp_now_deinit(); | ||
|
|
||
| Serial.println("ESP-NOW shutdown complete"); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| #pragma once | ||
|
|
||
| #include <string> | ||
| #include <nlohmann/json.hpp> | ||
|
|
||
| using json = nlohmann::json; | ||
|
|
||
| void init_espnow_HAL(void); | ||
| void espnow_loop_HAL(); | ||
| bool publishEspNowMessage_HAL(json payload); | ||
| void espnow_shutdown_HAL(); | ||
|
|
||
| typedef void (*tAnnounceEspNowMessage_cb)(json payload); | ||
| void set_announceEspNowMessage_cb_HAL(tAnnounceEspNowMessage_cb pAnnounceEspNowMessage_cb); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
Platformio/hardware/windows_linux/espnow_hal_windows_linux.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| #include "espnow_hal_windows_linux.h" | ||
|
|
||
| // Callback function pointer | ||
| static EspNowMessageCallback espNowMessageCallback = nullptr; | ||
|
|
||
| void set_announceEspNowMessage_cb_HAL(EspNowMessageCallback callback) { | ||
| espNowMessageCallback = callback; | ||
| printf("ESP-NOW callback registered (stub implementation)"); | ||
| } | ||
|
|
||
| void init_espnow_HAL() { | ||
| printf("ESP-NOW initialized (stub implementation)"); | ||
| } | ||
|
|
||
| void espnow_loop_HAL() { | ||
| // Nothing to do in the stub implementation | ||
| } | ||
|
|
||
| bool publishEspNowMessage_HAL(json payload) { | ||
| printf("ESP-NOW message published (stub implementation): %s", payload.dump().c_str()); | ||
| return true; // Always return success in the stub implementation | ||
| } | ||
|
|
||
| void espnow_shutdown_HAL() { | ||
| printf("ESP-NOW shutdown (stub implementation)"); | ||
| } | ||
14 changes: 14 additions & 0 deletions
14
Platformio/hardware/windows_linux/espnow_hal_windows_linux.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| #pragma once | ||
|
|
||
| #include <nlohmann/json.hpp> | ||
| using json = nlohmann::json; | ||
|
|
||
| // Callback type definition | ||
| typedef void (*EspNowMessageCallback)(json); | ||
|
|
||
| // Function declarations | ||
| void set_announceEspNowMessage_cb_HAL(EspNowMessageCallback callback); | ||
| void init_espnow_HAL(); | ||
| void espnow_loop_HAL(); | ||
| bool publishEspNowMessage_HAL(json payload); | ||
| void espnow_shutdown_HAL(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,7 @@ | |
| #include "guis/gui_irReceiver.h" | ||
| // show received BLE connection messages | ||
| #include "guis/gui_BLEpairing.h" | ||
| #include "hub/hubManager.h" | ||
|
|
||
| uint16_t COMMAND_UNKNOWN; | ||
|
|
||
|
|
@@ -175,7 +176,7 @@ std::string convertStringListToString(std::list<std::string> listOfStrings) { | |
| return result; | ||
| } | ||
|
|
||
| void executeCommandWithData(uint16_t command, commandData commandData, std::string additionalPayload = "") { | ||
| void executeCommandWithData(uint16_t command, commandData commandData, std::string additionalPayload) { | ||
| switch (commandData.commandHandler) { | ||
| case IR: { | ||
| omote_log_v(" generic IR, payloads %s\r\n", convertStringListToString(commandData.commandPayloads).c_str()); | ||
|
|
@@ -239,13 +240,76 @@ void executeCommandWithData(uint16_t command, commandData commandData, std::stri | |
| } | ||
| break; | ||
| } | ||
|
|
||
| #if (ENABLE_HUB_COMMUNICATION == 1) | ||
| case HUB: { | ||
| omote_log_w("HUB commands should be handled using the CommandExecutionParams struct\r\n"); | ||
| break; | ||
| } | ||
| #endif | ||
| } | ||
| } | ||
|
|
||
| void executeCommandWithData(const CommandExecutionParams& params, commandData commandData) { | ||
| #if (ENABLE_HUB_COMMUNICATION == 1) | ||
| if (commandData.commandHandler != HUB) { | ||
| // For non-HUB commands, pass through to the original function | ||
| omote_log_d("command: will execute command '%u'%s%s\r\n", | ||
| params.commandId, | ||
| params.additionalPayload.empty() ? "" : " with additionalPayload '", | ||
| params.additionalPayload.empty() ? "" : (params.additionalPayload + "'").c_str()); | ||
|
|
||
| executeCommandWithData(params.commandId, commandData, params.additionalPayload); | ||
| return; | ||
| } | ||
|
|
||
| auto current = commandData.commandPayloads.begin(); | ||
|
|
||
| // Extract device and command | ||
| std::string deviceName = *current; | ||
| current = std::next(current, 1); | ||
|
|
||
| std::string commandName = *current; | ||
| current = std::next(current, 1); | ||
|
|
||
| // Create JSON payload | ||
| json payload; | ||
| payload["device"] = deviceName; | ||
| payload["command"] = commandName; | ||
| payload["type"] = params.commandType; | ||
|
|
||
| // Create a data array if we have any additional data | ||
| json dataArray = json::array(); | ||
|
|
||
| // Add all remaining items from commandPayloads to the data array | ||
| while (current != commandData.commandPayloads.end()) { | ||
| dataArray.push_back(*current); | ||
| current = std::next(current, 1); | ||
| } | ||
|
|
||
| // If additionalPayload is provided, add it to the data array | ||
| if (!params.additionalPayload.empty()) { | ||
| dataArray.push_back(params.additionalPayload); | ||
| } | ||
|
|
||
| // Only add the data array if it has any content | ||
| if (!dataArray.empty()) { | ||
| payload["data"] = dataArray; | ||
| } | ||
|
|
||
| omote_log_d("execute: will send hub message for device '%s', command '%s'\r\n", | ||
| deviceName.c_str(), commandName.c_str()); | ||
|
|
||
| // Send using the hub manager | ||
| HubManager::getInstance().sendMessage(payload); | ||
| #endif | ||
| } | ||
|
|
||
| void executeCommand(uint16_t command, std::string additionalPayload) { | ||
| try { | ||
| if (commands.count(command) > 0) { | ||
| omote_log_d("command: will execute command '%u' with additionalPayload '%s'\r\n", command, additionalPayload.c_str()); | ||
| omote_log_d("command: will execute command '%u' with additionalPayload '%s'\r\n", | ||
| command, additionalPayload.c_str()); | ||
| executeCommandWithData(command, commands.at(command), additionalPayload); | ||
| } else { | ||
| omote_log_w("command: command '%u' not found\r\n", command); | ||
|
|
@@ -256,6 +320,22 @@ void executeCommand(uint16_t command, std::string additionalPayload) { | |
| } | ||
| } | ||
|
|
||
| void executeCommand(const CommandExecutionParams& params) { | ||
| try { | ||
| // Early return if command not found | ||
| if (commands.count(params.commandId) == 0) { | ||
| omote_log_w("command: command '%u' not found\r\n", params.commandId); | ||
| return; | ||
| } | ||
|
|
||
| commandData cmdData = commands.at(params.commandId); | ||
| executeCommandWithData(params, cmdData); | ||
| } | ||
| catch (const std::out_of_range& oor) { | ||
| omote_log_e("executeCommand: internal error, command not registered\r\n"); | ||
| } | ||
| } | ||
|
|
||
| void receiveNewIRmessage_cb(std::string message) { | ||
| showNewIRmessage(message); | ||
| } | ||
|
|
@@ -287,5 +367,24 @@ void receiveWiFiConnected_cb(bool connected) { | |
| void receiveMQTTmessage_cb(std::string topic, std::string payload) { | ||
| showMQTTmessage(topic, payload); | ||
| } | ||
| #endif | ||
|
|
||
| #if (ENABLE_ESPNOW == 1) | ||
| void receiveEspNowMessage_cb(json payload) { | ||
| // Extract device and command from the payload | ||
| std::string device, command, jsonStr; | ||
|
|
||
| if (payload.contains("device") && payload.contains("command")) { | ||
| device = payload["device"]; | ||
| command = payload["command"]; | ||
|
|
||
| // Serialize the payload to a string | ||
| std::string jsonStr = payload.dump(); | ||
|
|
||
| // Show the message in the UI | ||
| showEspNowMessage(jsonStr); | ||
|
|
||
| // TODO: Process the command based on device and command | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is more of a stub for 2-way communication with the hub |
||
| } | ||
| } | ||
| #endif | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.