Skip to content

Commit 4d31c17

Browse files
committed
feat: mobile design and drinks functioning with memory
1 parent 9fb8817 commit 4d31c17

File tree

97 files changed

+11882
-3728
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+11882
-3728
lines changed

.github/workflows/firmware.yml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,7 @@ jobs:
3636
- name: Install Extra Libraries (Using Checkout for reliability)
3737
run: mkdir -p $HOME/Arduino/libraries
3838

39-
- name: Checkout BfButton
40-
uses: actions/checkout@v4
41-
with:
42-
repository: m-reilly/BfButton
43-
path: BfButton
39+
# BfButton is now included locally in server/firmware/libraries/
4440

4541
- name: Checkout ESPAsyncTCP
4642
uses: actions/checkout@v4
@@ -56,10 +52,13 @@ jobs:
5652

5753
- name: Setup Libraries
5854
run: |
59-
mv BfButton $HOME/Arduino/libraries/
55+
cp -r server/firmware/libraries/BfButton $HOME/Arduino/libraries/
6056
mv ESPAsyncTCP $HOME/Arduino/libraries/
6157
mv ESPAsyncWebServer $HOME/Arduino/libraries/
6258
59+
- name: Create secrets.h for compilation
60+
run: cp server/firmware/serverEspReact/secrets.h_example server/firmware/serverEspReact/secrets.h
61+
6362
- name: Compile Sketch
6463
run: |
6564
arduino-cli compile --fqbn esp8266:esp8266:nodemcuv2 ./server/firmware/serverEspReact/serverEspReact.ino

.github/workflows/frontend.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ jobs:
3232
run: npm install
3333

3434
- name: Lint and Type-check
35-
run: npm run build
35+
run: |
36+
npm run lint
37+
npm run build
3638
3739
- name: Run Unit Tests
3840
run: npm run test

README.md

Lines changed: 123 additions & 122 deletions
Large diffs are not rendered by default.

README_es.md

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
# RobotCore - Ecosistema Modular IoT (ESP8266 / ESP32 + React)
2+
3+
🇺🇸 **[Read in English](README.md)** | 🇪🇸 **[Leer en Español](README_es.md)**
4+
5+
## 🌟 Descripción del Proyecto
6+
7+
Este proyecto es un **ecosistema multi-aplicación** que integra hardware y software para el control unificado de dispositivos IoT mediante una interfaz web moderna en **React**.
8+
9+
Desarrollado con una arquitectura híbrida, combina la eficiencia de los chips **ESP8266** (para los dispositivos de actuación) con la potencia del **ESP32** (para el Mando Físico), permitiendo gestionar **múltiples aplicaciones** independientes desde un mismo código base:
10+
11+
1. **Robot Car**: Vehículo teledirigido con telemetría.
12+
2. **Cocktail Machine**: Dispensador automático de bebidas.
13+
3. **Irrigation System**: Control de riego inteligente.
14+
15+
> **🌐 [Visita RobotCore](https://robot-core.vercel.app/)**
16+
17+
---
18+
19+
## 🎨 Interfaz Cyberpunk
20+
21+
El dashboard cuenta con un diseño **cyberpunk de alta calidad** con efectos de glassmorphism, neon glows y animaciones fluidas.
22+
23+
### 🤖 RobotCore Dashboard
24+
25+
![RobotCore](./client/public/car/screenshot.png?v=1)
26+
27+
Control completo del robot con:
28+
- **Neural Telemetry**: Visualización de giroscopio MPU en tiempo real
29+
- **RGB Module**: Selector de color con preview y efectos de glow
30+
- **Kinetic Control**: D-pad para control direccional con indicadores de estado
31+
- **Actuators**: Panel de control de pines y outputs
32+
33+
### 🌿 Sistema de Riego
34+
35+
![Sistema de Riego](./client/public/plant/screenshot.png?v=1)
36+
37+
Automatización de riego inteligente:
38+
- **Status Actual**: Temperatura y hora ESP en tiempo real
39+
- **Programación**: Gestión de tareas por días y horarios
40+
- **Configuración**: Selector de días y hora para nuevas tareas
41+
- **Control Manual**: Ajustes directos de bombas
42+
43+
### �🍹 Cocktail Mixer 3000
44+
45+
![Cocktail Machine](./client/public/drinks/screenshot.png)
46+
47+
Sistema automatizado de mezcla de bebidas:
48+
- **Grid de bebidas**: Selección rápida con efectos visuales premium
49+
- **Configuración de bombas**: Control PWM y calibración de tiempo
50+
- **Control manual**: D-pad para activación individual de bombas
51+
52+
---
53+
54+
## 🛠️ Tecnologías Utilizadas
55+
56+
### Frontend
57+
- **React (v19+)**: Interfaz dinámica y reactiva.
58+
- **Vite**: Sistema de construcción ultra rápido (Sustituyendo a CRA).
59+
- **TypeScript**: Robustez y tipado estático con alias `@/`.
60+
- **Material UI (MUI)**: Sistema de diseño moderno.
61+
- **WebSocket**: Comunicación en tiempo real de baja latencia.
62+
- **Clean Code Architecture**: Separación en Models, Hooks y Components.
63+
64+
### Backend / Firmware
65+
- **ESP8266 Core for Arduino**: Firmware optimizado para el chip ESP8266.
66+
- **AsyncWebServer**: Servidor HTTP asíncrono para ESP8266.
67+
- **Node.js (Mock Server)**: Para desarrollo local sin necesidad del chip físico.
68+
69+
---
70+
71+
## 🏗️ Estructura del Proyecto
72+
73+
El repositorio está organizado de forma modular para facilitar el mantenimiento y escalabilidad:
74+
75+
- `/client`: Aplicación frontend en React + Vite (Cyberpunk Dashboard).
76+
- `/remote-control`: Firmware para el **Mando Físico (ESP32)** con soporte para joystick, giroscopio y telemetría directa.
77+
- `/server/firmware`: Código fuente modular para el **Robot (ESP8266/ESP32)**.
78+
- `/apps/robot car`: Lógica de control de motores y giroscopio interno.
79+
- `/apps/drinks machine`: Gestión de bombas, recetas y pantalla OLED.
80+
- `/apps/irrigation`: Programación horaria y tareas de riego.
81+
- `/utils`: Componentes compartidos y Hub de comunicación.
82+
83+
---
84+
85+
## ⚙️ Configuración Modular (AppConfig)
86+
87+
El firmware del ESP8266 (`/server/firmware/serverEspReact`) es modular por diseño. Puedes elegir qué "personalidad" quieres cargar en el robot editando un solo archivo.
88+
89+
Esto evita conflictos de librerías (ej: usar librerías de riego cuando solo quieres la máquina de bebidas) y ahorra memoria.
90+
91+
### Cómo activar/desactivar módulos
92+
93+
1. Abre el archivo `server/firmware/serverEspReact/AppConfig.h`.
94+
2. Descomenta (`//`) solo el módulo que quieras compilar.
95+
96+
Ejemplo para activar **solo la Máquina de Bebidas**:
97+
98+
```cpp
99+
#define ENABLE_DRINKS_MACHINE
100+
// #define ENABLE_IRRIGATION_SYSTEM
101+
// #define ENABLE_ROBOT_CAR
102+
```
103+
104+
**⚠️ Nota Importante**: Si intentas activar todos los módulos a la vez, podrías tener errores de compilación debido a conflictos de versiones de librerías (especialmente ArduinoJson). Se recomienda compilar y subir **un solo módulo activo** cada vez.
105+
106+
## 🎮 Arquitectura de Red y Control Multi-Dispositivo
107+
108+
Este sistema no se conecta a un solo servidor, sino que orquesta una red de dispositivos distribuidos, combinando tecnologías según la naturaleza de los datos:
109+
110+
### 📡 WebSockets vs HTTP (Endpoints)
111+
112+
El Frontend de React utiliza una arquitectura híbrida:
113+
114+
1. **WebSockets (Telemetría en Tiempo Real)**
115+
* **¿Por qué?** Para datos de flujo continuo y crítico como el **Giroscopio (Joystick/Robot)**.
116+
* **Funcionamiento**: Se abre un "tubo" permanente. El ESP32 "empuja" miles de datos por segundo sin que el navegador tenga que pedirlo.
117+
* **Latencia**: Mínima (<10ms), permitiendo ver gráficos fluidos que reaccionan al milisegundo.
118+
* **Implementación**: `RemoteControlContext` mantiene una conexión global para que el mando físico funcione en cualquier pantalla.
119+
120+
2. **HTTP/REST (Comandos)**
121+
* **¿Por qué?** Para acciones puntuales y confirmadas como **"Encender Bomba"**, **"Cambiar Color"** o **"Guardar Configuración"**.
122+
* **Funcionamiento**: El navegador hace una petición puntual (GET/POST) y espera confirmación ("OK").
123+
* **Seguridad**: Asegura que una orden (ej: regar) se ha recibido y procesado correctamente.
124+
125+
### 🔗 Mapa de Conexiones
126+
127+
El sistema gestiona 4 IPs simultáneas, permitiendo que cada módulo tenga su propio cerebro pero opere bajo una misma interfaz unificada:
128+
129+
| Dispositivo | Variable `.env` | Hostname mDNS | Función Principal | Protocolo |
130+
| :--- | :--- | :--- | :--- | :--- |
131+
| **Robot Car** | `VITE_ROBOT_IP` | `robot-car.local` | Movimiento, Motores, Luces | HTTP + WebSocket |
132+
| **Mando Remoto** | `VITE_REMOTE_IP` | `remote-control.local` | Joystick Físico, Giroscopio externo | WebSocket Global |
133+
| **Máquina Bebidas**| `VITE_DRINKS_IP`| `drinks-machine.local` | Bombas peristálticas, Pantalla OLED | HTTP + WebSocket |
134+
| **Sistema Riego** | `VITE_IRRIGATION_IP`| `irrigation-system.local` | Gestión hídrica, Calendario | HTTP |
135+
136+
### 📶 Comunicación Híbrida (ESP-NOW)
137+
Además del WiFi, el **Mando Remoto** habla directamente con el **Robot** usando **ESP-NOW** (protocolo de radio directo de Espressif). Esto permite controlar el robot en exteriores sin necesidad de Router ni WiFi, mientras que si hay WiFi disponible, ambos dispositivos reportan sus datos a la web simultáneamente.
138+
139+
---
140+
141+
## 🚀 Instalación y Ejecución
142+
143+
### Opción Rápida (Scripts de un solo clic)
144+
He creado scripts para facilitar el inicio del proyecto (instala dependencias y lanza los servidores):
145+
146+
- **Mac/Linux:**
147+
```bash
148+
./run-mac.sh
149+
```
150+
- **Windows:**
151+
Doble clic en `run-windows.bat` o `run-windows.bat` desde la terminal.
152+
153+
---
154+
155+
4. **Modo Simulación (Mock)**:
156+
- Si no tienes el robot físico contigo, puedes activar el modo simulación para ver la UI funcionando con datos falsos.
157+
- En el archivo `client/.env`, cambia `VITE_MOCK_SERVER=true`.
158+
- Esto también se activa automáticamente si despliegas en Vercel (HTTPS) para evitar errores de conexión segurida.
159+
160+
1. Abre el archivo en `/server/firmware` (Robot) o `/remote-control/firmware` (Mando).
161+
> **Nota para ESP32**: Si usas una placa ESP32, asegúrate de tener esta URL en *Arduino IDE -> Preferences -> Additional Board Manager URLs*:
162+
> `https://espressif.github.io/arduino-esp32/package_esp32_index.json`
163+
>
164+
> ⚠️ **Solución de problemas**: Si la instalación de la versión más reciente falla (error `DEADLINE_EXCEEDED` o similar), intenta instalar la versión **2.0.17** desde el Gestor de Tarjetas.
165+
166+
1. Abre el archivo en `/server/firmware` (Robot) o `/remote-control/firmware` (Mando).
167+
2. **Configuración de Secretos**:
168+
- Este proyecto requiere **dos** archivos `secrets.h` (uno para el mando, otro para el robot).
169+
- En cada carpeta de firmware (`server/firmware/serverEspReact/` y `remote-control/firmware/remote-control/`), encontrarás un `secrets_example.h`.
170+
- Renómbralos a `secrets.h` y rellena tus credenciales WiFi y MACs.
171+
3. Carga el sketch a tus dispositivos.
172+
173+
### ⚠️ Importante: Problemas de Conexión WiFi
174+
Si el frontend no conecta con el ESP32 (error `ws: connection failed` o `No route to host`) y usas mDNS (`remote-control.local`), verifica esto:
175+
176+
1. **Navegador y Mixed Content (Error comunes en Vercel/HTTPS)**:
177+
* **Problema**: Si despliegas esta web en Vercel (`https://...`), el navegador bloqueará la conexión al ESP32 (`ws://...`) por seguridad ("Mixed Content"). Verás un mensaje de error rojo en la aplicación.
178+
* **Solución Recomendada**: Ejecuta el cliente **localmente** (`npm run dev`) en tu ordenador. Desde `http://localhost`, la conexión al robot funciona perfectamente.
179+
* **Solución Alternativa (Difícil)**: Configurar Chrome para permitir contenido inseguro (`chrome://flags/#block-insecure-private-network-requests`), aunque esto no siempre funciona para WebSockets desde dominios públicos HTTPS.
180+
2. **mDNS en Windows/Android**: `.local` funciona nativamente en Apple (Mac/iPhone). En Windows necesitas tener instalado Bonjour (viene con iTunes) o usar la IP directa en lugar de `remote-control.local`.
181+
3. **Firewall**: A veces el firewall del ordenador bloquea las conexiones entrantes/salientes al puerto 80 del ESP32.
182+
183+
---
184+
185+
## 📋 Características Implementadas
186+
187+
### Dashboard & Mando Físico
188+
- Control inalámbrico de largo alcance (ESP-NOW)
189+
- Telemetría directa desde el mando a la Web (WebSocket `/ws/remote`)
190+
- Visualización 3D del giroscopio del mando en tiempo real
191+
- Control híbrido Web/Físico sin interrupciones
192+
193+
### Módulo Robot Car
194+
- Control de motores de alta frecuencia
195+
- Telemetría interna de inclinación (Pitch/Roll)
196+
- Efectos de iluminación RGB sincronizados
197+
- Comunicación directa con Mando Remoto (ESP-NOW)
198+
199+
### Cocktail Mixer & Drinks
200+
- Interfaz física en pantalla OLED (Menú autónomo)
201+
- Selección de bebidas desde el mando (Joystick Up/Down/Accept)
202+
- API de control remoto y visualización en dashboard
203+
204+
### Sistema de Riego Inteligente
205+
- Control manual de bombas de agua (ON/OFF)
206+
- Programación de tareas de riego por días y horas
207+
- Telemetría de humedad y temperatura DHT22 simulada/real
208+
- Sincronización horaria automática (NTP)
209+

client/.env

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
VITE_REMOTE_IP=http://192.168.1.96
2-
VITE_ROBOT_IP=http://192.168.1.97
3-
VITE_DRINKS_IP=http://192.168.1.83
4-
VITE_IRRIGATION_IP=http://192.168.1.145
1+
VITE_REMOTE_IP=http://remote-control.local
2+
VITE_ROBOT_IP=http://robot-car.local
3+
VITE_DRINKS_IP=http://drinks-machine.local
4+
VITE_IRRIGATION_IP=http://irrigation-system.local
55
WDS_SOCKET_PORT=0
66
VITE_MOCK_SERVER=false

client/.eslintrc.cjs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
module.exports = {
2+
root: true,
3+
env: { browser: true, es2020: true },
4+
extends: [
5+
'eslint:recommended',
6+
'plugin:@typescript-eslint/recommended',
7+
'plugin:react/recommended',
8+
'plugin:react/jsx-runtime',
9+
'plugin:react-hooks/recommended',
10+
],
11+
ignorePatterns: ['dist', '.eslintrc.cjs'],
12+
parser: '@typescript-eslint/parser',
13+
plugins: ['react', 'react-refresh', 'unused-imports'],
14+
rules: {
15+
'react-refresh/only-export-components': [
16+
'warn',
17+
{ allowConstantExport: true },
18+
],
19+
"no-unused-vars": "off",
20+
"@typescript-eslint/no-unused-vars": "off",
21+
"unused-imports/no-unused-imports": "error",
22+
"unused-imports/no-unused-vars": [
23+
"warn",
24+
{ "vars": "all", "varsIgnorePattern": "^_", "args": "after-used", "argsIgnorePattern": "^_" }
25+
],
26+
"@typescript-eslint/no-explicit-any": "warn",
27+
"@typescript-eslint/no-empty-interface": "warn",
28+
"@typescript-eslint/no-inferrable-types": "warn",
29+
"prefer-const": "warn",
30+
"@typescript-eslint/ban-ts-comment": "warn",
31+
"@typescript-eslint/no-require-imports": "warn",
32+
"react/prop-types": "off",
33+
"react/no-unescaped-entities": "warn",
34+
"react/no-unknown-property": "warn"
35+
},
36+
settings: {
37+
react: {
38+
version: 'detect'
39+
}
40+
}
41+
}

0 commit comments

Comments
 (0)