Skip to content

DankJugal/ESP32RedisClient

Repository files navigation

ESP32 Redis Client Library

A comprehensive Redis client library for ESP32 that supports both local storage using ESP32's preferences memory (NVS) and TCP communication with remote Redis servers using the Redis Serialization Protocol (RESP). Additionally, it can act as a Redis-compatible server that receives RESP commands and stores them locally. This library provides a Redis-compatible API for persistent data storage and network communication on ESP32 microcontrollers.

Features

  • Triple Mode Operation: Local storage (NVS), TCP Redis client, and TCP Redis server
  • Redis Serialization Protocol (RESP): Full RESP protocol implementation for Redis communication
  • Redis Server Mode: ESP32 can act as a Redis-compatible server
  • Redis-compatible API: Familiar Redis commands and data structures
  • Persistent Storage: Uses ESP32 Preferences (NVS) for non-volatile local storage
  • WiFi Support: Built-in WiFi connectivity for TCP Redis communication
  • Multiple Data Types: Strings, Lists, and Hashes
  • Key Management: Expiration, renaming, and existence checking
  • Memory Efficient: Optimized for ESP32's limited memory
  • Easy Integration: Simple Arduino-style API
  • Keep-Alive: Automatic connection maintenance for TCP connections
  • Client Management: Handles multiple client connections

Operating Modes

Local Storage Mode (NVS)

  • Stores data in ESP32's non-volatile storage
  • Data persists across reboots
  • No network required
  • Limited by ESP32's NVS space

TCP Redis Client Mode

  • Connects to remote Redis servers via TCP
  • Uses Redis Serialization Protocol (RESP)
  • Full Redis server compatibility
  • Requires WiFi connection

TCP Redis Server Mode

  • ESP32 acts as a Redis-compatible server
  • Receives RESP commands from clients
  • Stores data locally in NVS
  • Handles multiple client connections
  • Perfect for IoT device communication

Supported Data Types

Strings

  • SET, GET, APPEND, STRLEN, SUBSTR

Lists

  • LPUSH, RPUSH, LPOP, RPOP, LINDEX, LLEN, LRANGE

Hashes

  • HSET, HGET, HDEL, HEXISTS, HKEYS, HGETALL, HLEN

Key Management

  • EXISTS, DEL, RENAME, EXPIRE, TTL, KEYS

Database Operations

  • FLUSHDB, DBSIZE, INFO

TCP-Specific Commands

  • PING, ECHO, AUTH, SELECT, QUIT

Installation

  1. Download the library files:

    • ESP32RedisClient.h
    • ESP32RedisClient.cpp
  2. Place them in your Arduino project directory or create a library folder.

  3. Include the header in your Arduino sketch:

    #include "ESP32RedisClient.h"

Quick Start

Local Storage Mode

#include <Arduino.h>
#include "ESP32RedisClient.h"

ESP32RedisClient redis;

void setup() {
    Serial.begin(115200);
    
    // Connect to local storage
    if (redis.connect()) {
        Serial.println("Connected to local Redis storage");
    }
    
    // Basic operations
    redis.set("name", "ESP32");
    String value = redis.get("name");
    Serial.println("Name: " + value);
    
    // List operations
    redis.lpush("items", "apple");
    redis.lpush("items", "banana");
    
    // Hash operations
    redis.hset("user", "name", "John");
    redis.hset("user", "age", "30");
}

void loop() {
    // Your main code here
}

TCP Redis Server Mode

#include <Arduino.h>
#include "ESP32RedisClient.h"

ESP32RedisClient redis;

void setup() {
    Serial.begin(115200);
    
    // Connect to WiFi
    if (redis.connect("YOUR_WIFI_SSID", "YOUR_WIFI_PASSWORD")) {
        Serial.println("WiFi connected");
        
        // Connect to Redis server
        if (redis.connectTCP("192.168.1.100", 6379)) {
            Serial.println("Connected to Redis server");
            
            // Test connection
            String response = redis.ping();
            Serial.println("PING response: " + response);
            
            // Basic operations via TCP
            redis.set("name", "ESP32", true); // use_tcp = true
            String value = redis.get("name", true);
            Serial.println("Name: " + value);
            
            // Send raw RESP commands
            String set_response = redis.sendCommand("SET", "key", "value");
            String get_response = redis.sendCommand("GET", "key");
            Serial.println("SET response: " + set_response);
            Serial.println("GET response: " + get_response);
        }
    }
}

void loop() {
    // Your main code here
}

TCP Redis Server Mode

#include <Arduino.h>
#include "ESP32RedisClient.h"

ESP32RedisClient redis;

void setup() {
    Serial.begin(115200);
    
    // Connect to WiFi
    if (redis.connect("YOUR_WIFI_SSID", "YOUR_WIFI_PASSWORD")) {
        Serial.println("WiFi connected");
        
        // Start Redis server
        if (redis.startServer(6379)) {
            Serial.println("Redis server started on " + redis.getServerIP());
            Serial.println("Port: " + String(redis.getServerPort()));
            
            // Add some initial data
            redis.set("server_name", "ESP32 Redis Server");
            redis.hset("server_info", "version", "1.0.0");
            redis.lpush("activity_log", "SERVER_STARTED");
        }
    }
}

void loop() {
    // Handle incoming client connections
    redis.handleServer();
    delay(10);
}

API Reference

Connection Management

ESP32RedisClient(namespace_name)

Constructor. Creates a Redis client instance.

  • namespace_name (optional): Namespace for preferences storage (default: "redis")

bool connect()

Connects to local Redis storage and initializes preferences storage.

  • Returns: true if connection successful, false otherwise

bool connect(String ssid, String password)

Connects to WiFi network.

  • Parameters:
    • ssid: WiFi network name
    • password: WiFi password
  • Returns: true if WiFi connection successful, false otherwise

bool connectTCP(String host, int port)

Connects to a remote Redis server via TCP.

  • Parameters:
    • host: Redis server IP address or hostname
    • port: Redis server port (default: 6379)
  • Returns: true if TCP connection successful, false otherwise

bool disconnect()

Disconnects from local Redis storage and closes preferences storage.

  • Returns: true if disconnection successful, false otherwise

bool disconnectTCP()

Disconnects from TCP Redis server.

  • Returns: true if disconnection successful, false otherwise

bool isConnected()

Checks if the Redis client is connected (local or TCP).

  • Returns: true if connected, false otherwise

bool isTCPMode()

Checks if the client is in TCP mode.

  • Returns: true if in TCP mode, false otherwise

TCP Server Methods

bool startServer(int port)

Starts the ESP32 as a Redis-compatible server.

  • Parameters: port: Server port (default: 6379)
  • Returns: true if server started successfully, false otherwise

bool stopServer()

Stops the Redis server.

  • Returns: true if server stopped successfully, false otherwise

void handleServer()

Handles incoming client connections and processes RESP commands.

  • Note: Call this method in the main loop to process client requests

bool isServerMode()

Checks if the ESP32 is in server mode.

  • Returns: true if in server mode, false otherwise

bool isServerRunning()

Checks if the Redis server is currently running.

  • Returns: true if server is running, false otherwise

String getServerIP()

Gets the IP address of the Redis server.

  • Returns: Server IP address as String

int getServerPort()

Gets the port number of the Redis server.

  • Returns: Server port number

RESP Protocol Methods

String sendCommand(vector<String> command)

Sends a RESP command to Redis server.

  • Parameters: command: Vector of command arguments
  • Returns: Parsed response from Redis server

String sendCommand(String command)

Sends a single-argument RESP command.

  • Parameters: command: Command name
  • Returns: Parsed response from Redis server

String sendCommand(String cmd1, String cmd2)

Sends a two-argument RESP command.

  • Parameters:
    • cmd1: First argument
    • cmd2: Second argument
  • Returns: Parsed response from Redis server

String sendCommand(String cmd1, String cmd2, String cmd3)

Sends a three-argument RESP command.

  • Parameters:
    • cmd1: First argument
    • cmd2: Second argument
    • cmd3: Third argument
  • Returns: Parsed response from Redis server

String sendCommand(String cmd1, String cmd2, String cmd3, String cmd4)

Sends a four-argument RESP command.

  • Parameters:
    • cmd1: First argument
    • cmd2: Second argument
    • cmd3: Third argument
    • cmd4: Fourth argument
  • Returns: Parsed response from Redis server

TCP-Specific Redis Operations

String ping()

Sends PING command to Redis server.

  • Returns: "PONG" if server is responsive

String echo(String message)

Sends ECHO command to Redis server.

  • Parameters: message: Message to echo
  • Returns: Echoed message from server

String auth(String password)

Authenticates with Redis server.

  • Parameters: password: Redis server password
  • Returns: Authentication result

String select(int database)

Selects Redis database.

  • Parameters: database: Database number (0-15)
  • Returns: Selection result

String quit()

Closes connection to Redis server.

  • Returns: Quit confirmation

Enhanced Operations (Dual Mode)

bool set(String key, String value, bool use_tcp)

Sets a key-value pair in local storage or TCP Redis server.

  • Parameters:
    • key: The key name
    • value: The value to store
    • use_tcp: true for TCP mode, false for local storage
  • Returns: true if successful, false otherwise

String get(String key, bool use_tcp)

Gets the value for a key from local storage or TCP Redis server.

  • Parameters:
    • key: The key name
    • use_tcp: true for TCP mode, false for local storage
  • Returns: The value as String, empty string if key doesn't exist

bool del(String key, bool use_tcp)

Deletes a key from local storage or TCP Redis server.

  • Parameters:
    • key: The key name
    • use_tcp: true for TCP mode, false for local storage
  • Returns: true if key was deleted, false if key didn't exist

bool exists(String key, bool use_tcp)

Checks if a key exists in local storage or TCP Redis server.

  • Parameters:
    • key: The key name
    • use_tcp: true for TCP mode, false for local storage
  • Returns: true if key exists, false otherwise

String Operations

bool set(String key, String value)

Sets a key-value pair.

  • Parameters:
    • key: The key name
    • value: The value to store
  • Returns: true if successful, false otherwise

String get(String key)

Gets the value for a key.

  • Parameters: key: The key name
  • Returns: The value as String, empty string if key doesn't exist

bool append(String key, String value)

Appends a value to an existing string.

  • Parameters:
    • key: The key name
    • value: Value to append
  • Returns: true if successful, false otherwise

int strlen(String key)

Gets the length of a string value.

  • Parameters: key: The key name
  • Returns: Length of the string, 0 if key doesn't exist

String substr(String key, int start, int end)

Gets a substring of a string value.

  • Parameters:
    • key: The key name
    • start: Start position
    • end: End position (-1 for end of string)
  • Returns: The substring

List Operations

int lpush(String key, String value)

Pushes a value to the left (beginning) of a list.

  • Parameters:
    • key: The list key
    • value: Value to push
  • Returns: New length of the list

int rpush(String key, String value)

Pushes a value to the right (end) of a list.

  • Parameters:
    • key: The list key
    • value: Value to push
  • Returns: New length of the list

String lpop(String key)

Pops a value from the left (beginning) of a list.

  • Parameters: key: The list key
  • Returns: The popped value, empty string if list is empty

String rpop(String key)

Pops a value from the right (end) of a list.

  • Parameters: key: The list key
  • Returns: The popped value, empty string if list is empty

String lindex(String key, int index)

Gets the value at a specific index in a list.

  • Parameters:
    • key: The list key
    • index: Index position (negative for reverse indexing)
  • Returns: The value at the index, empty string if index out of range

int llen(String key)

Gets the length of a list.

  • Parameters: key: The list key
  • Returns: Length of the list

vector<String> lrange(String key, int start, int end)

Gets a range of values from a list.

  • Parameters:
    • key: The list key
    • start: Start index
    • end: End index (-1 for end of list)
  • Returns: Vector of strings in the range

Hash Operations

bool hset(String key, String field, String value)

Sets a field-value pair in a hash.

  • Parameters:
    • key: The hash key
    • field: The field name
    • value: The value to store
  • Returns: true if successful, false otherwise

String hget(String key, String field)

Gets the value of a field in a hash.

  • Parameters:
    • key: The hash key
    • field: The field name
  • Returns: The field value, empty string if field doesn't exist

bool hdel(String key, String field)

Deletes a field from a hash.

  • Parameters:
    • key: The hash key
    • field: The field name
  • Returns: true if field was deleted, false if field didn't exist

bool hexists(String key, String field)

Checks if a field exists in a hash.

  • Parameters:
    • key: The hash key
    • field: The field name
  • Returns: true if field exists, false otherwise

vector<String> hkeys(String key)

Gets all field names in a hash.

  • Parameters: key: The hash key
  • Returns: Vector of field names

map<String, String> hgetall(String key)

Gets all field-value pairs in a hash.

  • Parameters: key: The hash key
  • Returns: Map of field-value pairs

int hlen(String key)

Gets the number of fields in a hash.

  • Parameters: key: The hash key
  • Returns: Number of fields

Key Management

bool exists(String key)

Checks if a key exists.

  • Parameters: key: The key name
  • Returns: true if key exists, false otherwise

bool del(String key)

Deletes a key.

  • Parameters: key: The key name
  • Returns: true if key was deleted, false if key didn't exist

bool rename(String old_key, String new_key)

Renames a key.

  • Parameters:
    • old_key: Current key name
    • new_key: New key name
  • Returns: true if successful, false otherwise

int expire(String key, int seconds)

Sets expiration time for a key.

  • Parameters:
    • key: The key name
    • seconds: Expiration time in seconds
  • Returns: 1 if expiration was set, 0 if key doesn't exist

int ttl(String key)

Gets the time to live for a key.

  • Parameters: key: The key name
  • Returns: TTL in seconds, -1 if no expiration, -2 if key doesn't exist

vector<String> keys(String pattern)

Gets all keys matching a pattern.

  • Parameters: pattern: Pattern to match (default: "*")
  • Returns: Vector of matching keys

Database Operations

bool flushdb()

Removes all keys from the database.

  • Returns: true if successful, false otherwise

int dbsize()

Gets the number of keys in the database.

  • Returns: Number of keys

String info()

Gets information about the Redis client and database.

  • Returns: Information string

Utility Methods

void printKeys()

Prints all keys in the database to Serial.

void printAllData()

Prints all data in the database to Serial.

size_t getUsedSpace()

Gets the approximate used space in bytes.

  • Returns: Used space in bytes

size_t getFreeSpace()

Gets the approximate free space in bytes.

  • Returns: Free space in bytes

Examples

Basic Usage

ESP32RedisClient redis;

void setup() {
    redis.connect();
    
    // Store data
    redis.set("sensor_temp", "25.5");
    redis.set("sensor_humidity", "60");
    
    // Retrieve data
    String temp = redis.get("sensor_temp");
    String humidity = redis.get("sensor_humidity");
    
    Serial.println("Temperature: " + temp + "°C");
    Serial.println("Humidity: " + humidity + "%");
}

List Operations

// Store sensor readings as a list
redis.rpush("readings", "25.5");
redis.rpush("readings", "26.1");
redis.rpush("readings", "24.8");

// Get all readings
std::vector<String> readings = redis.lrange("readings", 0, -1);
for (const String& reading : readings) {
    Serial.println("Reading: " + reading);
}

// Get latest reading
String latest = redis.rpop("readings");
Serial.println("Latest: " + latest);

Hash Operations

// Store user profile
redis.hset("user:123", "name", "John Doe");
redis.hset("user:123", "email", "john@example.com");
redis.hset("user:123", "age", "30");

// Get user info
String name = redis.hget("user:123", "name");
String email = redis.hget("user:123", "email");

// Get all user data
std::map<String, String> user_data = redis.hgetall("user:123");
for (auto& pair : user_data) {
    Serial.println(pair.first + ": " + pair.second);
}

Key Expiration

// Set a temporary value
redis.set("temp_data", "important_data");
redis.expire("temp_data", 60); // Expires in 60 seconds

// Check TTL
int ttl = redis.ttl("temp_data");
Serial.println("TTL: " + String(ttl) + " seconds");

TCP Redis Communication

// Connect to WiFi and Redis server
redis.connect("WiFi_SSID", "WiFi_Password");
redis.connectTCP("192.168.1.100", 6379);

// Test connection
String pong = redis.ping();
Serial.println("Server response: " + pong);

// Send raw RESP commands
String set_result = redis.sendCommand("SET", "sensor_data", "25.5");
String get_result = redis.sendCommand("GET", "sensor_data");

// Use enhanced operations with TCP
redis.set("temperature", "25.5", true); // TCP mode
String temp = redis.get("temperature", true);

// List operations via TCP
redis.sendCommand("LPUSH", "readings", "25.5");
redis.sendCommand("LPUSH", "readings", "26.1");
String readings = redis.sendCommand("LRANGE", "readings", "0", "-1");

// Hash operations via TCP
redis.sendCommand("HSET", "device", "name", "ESP32");
redis.sendCommand("HSET", "device", "location", "Room1");
String device_name = redis.sendCommand("HGET", "device", "name");

RESP Protocol Examples

// Manual RESP command construction
std::vector<String> command = {"SET", "key", "value"};
String resp_command = redis.encodeRESPCommand(command);
Serial.println("RESP: " + resp_command);
// Output: *3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n

// Send complex commands
String result = redis.sendCommand("MSET", "key1", "value1", "key2", "value2");
String info = redis.sendCommand("INFO", "server");

// Database operations
redis.select(1); // Switch to database 1
redis.set("db1_key", "db1_value", true);
redis.select(0); // Switch back to database 0

ESP32 as Redis Server

// Start ESP32 as Redis server
redis.connect("WiFi_SSID", "WiFi_Password");
redis.startServer(6379);

// In main loop, handle client connections
void loop() {
    redis.handleServer();
    delay(10);
}

// Clients can now connect to ESP32 using:
// redis-cli -h ESP32_IP -p 6379
// Or another ESP32 with the client library

Multi-ESP32 Communication

// ESP32 Server (Device 1)
ESP32RedisClient server_redis;
server_redis.connect("WiFi_SSID", "WiFi_Password");
server_redis.startServer(6379);

// ESP32 Client (Device 2)
ESP32RedisClient client_redis;
client_redis.connect("WiFi_SSID", "WiFi_Password");
client_redis.connectTCP("192.168.1.100", 6379); // ESP32 Server IP

// Send data from client to server
client_redis.set("sensor_data", "25.5", true);
client_redis.sendCommand("HSET", "device_info", "location", "Room1");

// Server automatically stores data locally

Limitations

Local Storage Mode

  1. Memory Constraints: ESP32 has limited NVS space (typically 1-2MB)
  2. TTL Implementation: TTL is approximate and requires periodic checking
  3. Key Length: Keys are limited to reasonable lengths for memory efficiency
  4. Value Size: Large values may impact performance

TCP Redis Client Mode

  1. Network Dependency: Requires stable WiFi connection
  2. Server Availability: Redis server must be running and accessible
  3. Memory Usage: TCP buffers consume additional RAM
  4. Latency: Network operations are slower than local storage
  5. Connection Management: TCP connections may timeout or drop
  6. RESP Parsing: Complex responses may require additional parsing

TCP Redis Server Mode

  1. Single Client: Handles one client connection at a time
  2. Memory Constraints: Limited by ESP32's RAM for client buffers
  3. Command Processing: Sequential command processing (no pipelining)
  4. Network Dependency: Requires stable WiFi connection
  5. No Persistence: Data stored in NVS, not traditional Redis persistence
  6. Limited Commands: Not all Redis commands are implemented

Memory Management

Local Storage Mode

  • The library uses ESP32 Preferences (NVS) for persistent storage
  • Data persists across reboots
  • Keys are stored with prefixes to avoid conflicts
  • Metadata is stored separately for type information

TCP Redis Server Mode

  • Uses WiFiServer for TCP server functionality
  • Client connections handled sequentially
  • RESP protocol parsing and response generation
  • Data stored locally in NVS using existing storage methods
  • Client buffers managed by WiFiClient library

Error Handling

  • All methods return appropriate success/failure indicators
  • Invalid keys or values are rejected
  • Connection status is checked before operations
  • Memory constraints are handled gracefully

Performance Considerations

  • String operations are fastest
  • List operations require parsing and rebuilding
  • Hash operations are most memory-intensive
  • Consider data size and frequency of operations

Example Files

The library includes several example files to demonstrate different features:

example.ino

Comprehensive example showing all local storage features including strings, lists, hashes, and key management operations.

tcp_example.ino

Complete example demonstrating TCP Redis communication with RESP protocol, including WiFi connection, Redis server communication, and both local and remote operations.

server_example.ino

Example showing ESP32 as a Redis-compatible server that receives RESP commands and stores them locally.

client_to_server_example.ino

Example demonstrating how to connect to an ESP32 Redis server from another ESP32 client.

server_client_demo.ino

Comprehensive demo showing both server and client functionality on the same ESP32.

resp_demo.ino

Educational example showing RESP protocol encoding and decoding without requiring a Redis server connection.

test.ino

Test suite to verify library functionality with automated tests for all major features.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors