GyverHub Documentation

repository·main·Indexed 18 days ago

https://github.com/gyverlibs/gyverhub

A platform for creating remote control panels for ESP8266, ESP32, and Arduino microcontrollers. It decouples UI logic defined in C++ firmware from UI rendering handled by web, PWA, Telegram, or native applications. Supports communication via MQTT, HTTP, WebSocket, Serial, and Bluetooth BLE. Includes a comprehensive Builder API for creating input and output widgets, system configuration via preprocessor macros, and tools for smart home integration.

Tokens
32.7K
Snippets
100
Records
139
Agent score
63%

What's inside GyverHub

  1. Overview of the GyverHub platform

    main

    GyverHub is a control panel platform for ESP8266, ESP32, and other Arduino-compatible microcontrollers. It consists of two main components:

    1. Device Library: A C++ library for the microcontroller that allows you to "build" a graphical interface in your firmware. This interface is then sent to the control application.
    2. Control Application: A JavaScript-based interface used to manage devices. It can be used in several ways:
      • Online: Via hub.gyver.ru (HTTP/HTTPS).
      • PWA (Offline Web App): Can be installed on Android, iOS, Linux, Windows, or Mac.
      • Telegram App: Via the @GyverHUB_bot.
      • Native Apps: Available for Android (Google Play/APK), iOS (App Store), and Desktop (Windows/Linux/Mac).
      • ESP Web Interface: An autonomous web interface hosted directly from the ESP8266/ESP32 Flash memory.

    Communication Interfaces

    Devices and the application exchange data using various protocols:

    • MQTT: Works over the Internet via a local or third-party broker (ideal for Smart Home integration like Alice or Home Assistant).
    • HTTP + WebSocket: Used for local WiFi networks.
    • Serial: Via USB or Bluetooth Serial.
    • Bluetooth: Via Bluetooth BLE.
    • Telegram: Via Telegram bots.
  2. Choose a GyverHub application variation

    main

    GyverHub is available in several forms depending on your connectivity needs and platform. It is fully autonomous and does not require registration or an internet connection to function.

    Available variations:

    • Online Web Version: Hosted at hub.gyver.ru (HTTP/HTTPS).
    • PWA (Progressive Web App): An offline-capable version that can be installed on Android, iOS, Linux, Windows, or Mac from the official website.
    • Telegram App: Accessible via the GyverHUB_bot.
    • Native Apps:
      • Android: Available on Google Play or via APK download.
      • iOS: Available on the App Store.
      • Desktop (Windows/Linux/Mac): Available via GitHub releases.
    • ESP Web Interface: A lightweight version hosted directly from the flash memory of an ESP8266 or ESP32 device.
  3. Understand the Canvas (холст) concept

    main

    The Canvas allows you to "draw" in the browser window using commands sent from your device via HTML Canvas. It acts as a wireless color touch display, enabling data visualization (graphs, maps, sensor readings) and user interaction (remote touchpad).

    Key characteristics:

    • Minimized Network Traffic: Uses short commands to minimize memory and bandwidth usage.
    • Processing API: Implements a subset of the Processing API for easier drawing compared to the native HTML Canvas API.
    • Proportional Scaling: The canvas is automatically scaled and fitted to its container (UI width or widget size). It also scales for high-density (Retina) displays.
    • Virtual vs. Real Size: You define a virtual size for programming convenience, but the actual pixel size on screen will differ to maintain clarity and proportions.
    • Coordinate System: The origin (0,0) is the top-left corner, with the Y-axis pointing downwards.
    • Negative Coordinates: When using Canvas functions (not custom JS), negative coordinates are subtracted from the width/height. For example, point(-1, -1) will place a point in the bottom-right corner.
  4. Layout the Control Panel (PU) with containers

    main

    GyverHub uses a grid-based layout where widgets are placed left-to-right and top-to-bottom. You cannot specify exact coordinates, but you can use nested containers to create complex layouts.

    Vertical Container

    The default container is vertical. Simply calling widgets one after another stacks them vertically.

    Horizontal Container (Rows)

    To place widgets side-by-side, use one of these three methods:

    1. beginRow() / endRow(): Manual start and end. Always remember to call endRow().
    2. gh::Row object: Uses RAII; the row starts when the object is created and closes when it goes out of scope.
    3. GH_ROW macro: A convenient wrapper for defining a row block.

    Vertical Container (Columns)

    To stack widgets vertically within a row, use beginCol() / endCol() or the gh::Col object/GH_COL macro.

    // Using gh::Row (RAII)
    void build(gh::Builder& b) {
        {
            gh::Row r(b);
            b.Button();
            b.Button();
        }
    }
    
    // Using GH_ROW macro
    void build(gh::Builder& b) {
        GH_ROW(b, 1,
            b.Button();
            b.Button();
        );
    }
  5. Configure widgets using personal and common parameters

    main

    Widgets are configured using a specific pattern: call the widget function, provide personal parameters in parentheses, and then chain common parameters using dot notation.

    Pattern: b.Widget(personal_params).common_param1(...).common_param2(...);

    void build(gh::Builder& b) {
        b.Widget();               // No parameters
        b.Widget(param);          // Personal parameters
        b.Widget(param).opt(val); // Personal + common parameters
    }
  6. Core concepts of GyverHub

    main

    Understanding the GyverHub ecosystem involves three main concepts:

    1. Device (Устройство): The microcontroller running the GyverHub library. The microcontroller acts as a server that clients connect to.
    2. Client (Клиент): A website or application that connects to the device.
    3. Network Name (Имя сети/префикс): A unique "client-device" name used by the client to discover the device. It essentially acts as a password; without it, the device cannot be discovered.
  7. Handle cross-platform code with GH_ESP_BUILD and GH_PLATFORM

    main

    GyverHub automatically detects the compilation platform. You can use these built-in macros to write cross-platform code that behaves differently on ESP boards versus standard Arduino boards.

    ESP-Specific Code

    Use the GH_ESP_BUILD flag to wrap code that requires networking or ESP-specific features. This flag is available after including <GyverHub.h>.

    Platform Identification

    The GH_PLATFORM macro contains the platform name as a string. Supported values include:

    • "ESP8266"
    • "ESP32"
    • "ESP32-S2"
    • "ESP32-S3"
    • "ESP32-C3"
    • "Arduino" (for all other platforms)
    #include <GyverHub.h>
    
    #ifdef GH_ESP_BUILD
      // This code will only compile for ESP8266/ESP32
    #endif
  8. Detect widget changes to save data

    main

    GyverHub does not automatically save widget values to non-volatile memory (EEPROM/Flash). To implement saving, use the b.changed() method within your build function. This method returns true if any widget value has been modified by the user. This is the ideal place to trigger a save operation, such as writing a data structure to EEPROM or a file via FileData.

    #include <Arduino.h>
    #include <FileData.h>
    #include <LittleFS.h>
    
    struct Data {
      uint8_t spinner;
      uint16_t slider;
      char str[20];
    };
    Data data;
    
    FileData dataFile(&LittleFS, "/data.dat", 'A', &data, sizeof(data));
    
    void build(gh::Builder& b) {
        b.Spinner(&data.spinner);
        b.Slider(&data.slider);
        b.Input(data.str);
    
        // If any widget changed, trigger the data update/save
        if (b.changed()) dataFile.update();
    }
    
    void setup() {
        // ... initialize filesystem ...
        dataFile.read();
    }
    
    void loop() {
        // File saving occurs based on the FileData timeout logic
        dataFile.tick();
    }
  9. Customize UI builds and widget interactions in gh::Builder

    main

    The gh::Builder allows you to inspect the context of a build request. You can determine if the request is for the UI, if it's a widget setting action, and identify the client making the request. This enables dynamic UIs where widgets are shown only to specific clients or via specific connection types.

    void build(gh::Builder& b) {
        // Check if this is a UI build request
        if (b.build.isUI()) {
            Serial.println("=== UI BUILD ===");
        }
    
        // Check if this is a widget setting action
        if (b.build.isSet()) {
            Serial.print("name: ");
            Serial.println(b.build.name);
            Serial.print("value: ");
            Serial.println(b.build.value);
        }
    
        // Access client information
        Serial.print("client from: ");
        Serial.println(gh::readConnection(b.build.client.connection()));
        Serial.print("ID: ");
        Serial.println(b.build.client.id);
    
        // Example: Show a specific input only to a specific client ID
        if (b.build.client.id == "abc123") b.Input();
    
        // Example: Intercept input values without binding a variable
        if (b.Input().click()) Serial.println(b.build.value);
    }
  10. Handle Canvas click and position events

    main

    GyverHub provides gh::Pos to capture mouse or touch coordinates relative to the canvas dimensions. You can handle clicks in two ways:

    1. Directly in the builder: Use b.BeginCanvas(..., &pos).click() to detect a click event immediately.
    2. Via position tracking: Use pos.changed() to detect when the position has updated. This is preferred for heavy logic to keep the build() function fast. If using this method, declare gh::Pos globally or in a scope accessible to loop().

    Geometry Detection: gh::Pos includes methods to check if a click occurred within specific shapes:

    • pos.inRect(x, y, width, height)
    • pos.inCircle(x, y, radius)
    // Method 1: Handling in loop (Recommended for heavy logic)
    gh::Pos pos;
    
    void build(gh::Builder& b) {
        b.Canvas_(F("cv"), 400, 600, nullptr, &pos);
    }
    
    void loop() {
      hub.tick();
      if (pos.changed()) {
        // Handle click at pos.x, pos.y
      }
    }
    
    // Method 2: Geometry detection
    if (pos.changed()) {
        if (pos.inRect(50, 50, 100, 100)) {
            // Clicked inside rectangle
        }
        if (pos.inCircle(200, 100, 30)) {
            // Clicked inside circle
        }
    }
  11. Use Serial and Bluetooth communication modes

    main

    Serial Mode

    Serial mode supports wired USB connections and Bluetooth modules that create a virtual COM port (e.g., HC-05, HC-06, JDY-21).

    To prevent device reboots caused by hardware Serial connections on certain boards, the application includes a timeout setting. This delays the request by a specified number of milliseconds to allow the device time to boot up.

    Bluetooth Mode

    In the GyverHub application, Bluetooth communication is specifically designed for BLE modules (e.g., HM-10, JDY-08, AT-09, CC41-A).

  12. Use the Canvas API for drawing

    main

    The Canvas class provides two distinct drawing APIs: a Processing-like API for high-level primitive drawing and an HTML Canvas API for low-level, direct control over the drawing context. You can use these to create custom visual interfaces or graphics on the GyverHub interface.

    Processing-like API

    Ideal for quick shapes and simple graphics. It uses high-level commands like circle(), rect(), and line().

    HTML Canvas API

    Provides fine-grained control similar to the web standard. It includes path manipulation (beginPath, moveTo, lineTo, closePath), transformations (scale, rotate, translate), and advanced styling (shadowBlur, globalCompositeOperation).

    State Management

    Both APIs support saving and restoring the drawing state to allow for complex nested transformations and styles:

    • Use push()/pop() in the Processing-like API.
    • Use save()/restore() in the HTML Canvas API.
    // Example of Processing-like drawing
    canvas.fill(0xFF0000);
    canvas.rect(10, 10, 50, 50);
    
    // Example of HTML Canvas API drawing
    canvas.save();
    canvas.translate(50, 50);
    canvas.rotate(0.5);
    canvas.drawRect(0, 0, 20, 20);
    canvas.restore();