Portafolio · Vending · Hardware + software

Milodón Vending

App Android + panel web para operar máquinas expendedoras.

Cliente
Milodón Vending
Tipo
App móvil
Año
2025
Estado
Publicada
Milodón Vending — Vending · Hardware + software

El encargo

Qué se resolvió.

Sistema completo para máquinas expendedoras: app Android nativa que controla el hardware (matriz de motores) y cobra con un POS Transbank integrado, más un panel web de control remoto con telemetría en vivo, ventas, inventario, alertas de hardware y cierre de caja diario.

Cómo funciona por dentro

Milodón Vending opera máquinas expendedoras físicas — la primera, instalada en un gimnasio de Sportlife — y necesitaba algo que un software de vending genérico no ofrece: hablar directo con su hardware (una placa controladora propia, un lector de pago cashless y un terminal Transbank) y dejar que el dueño la maneje desde el celular sin ir a destrabar un motor a mano.

La solución son dos piezas que comparten un mismo Firestore en tiempo real: una app Android nativa que vive dentro de la máquina y gobierna cada parte del ciclo de venta, y un panel web para el dueño con ventas, inventario, logs y una consola para mandarle comandos de vuelta al hardware.

Clienteen el gimnasio
App Androiddentro de la máquina
Firebase · Firestoretiempo real
Panel webel dueño
Bot de Telegramalertas

En simple: la máquina vende sola. Cada transacción, log y falla sube a Firestore al instante. Desde el panel el dueño ve todo en vivo y puede mandar comandos de vuelta — girar un motor, prender un LED — sin tocar la máquina. Si algo se rompe, Telegram avisa antes de que el cliente se queje.

Máquina expendedora Milodón instalada en el gimnasio Sportlife
La máquina, instalada en Sportlife
Técnico de Milodón cargando la máquina expendedora
Carga y mantención en terreno
01

La máquina y la app que la gobierna

Una tablet Android reemplaza al controlador de fábrica y gobierna cada parte del ciclo de venta: pantalla, cobro y motor.

  1. 1

    Pantalla de autoservicio en Java nativo

    Bienvenida → categorías → productos → detalle → pago → dispensado. Sin WebView ni Compose: vistas Android nativas corriendo sobre un panel táctil embebido.

  2. 2

    Cobro con POS Transbank antes de girar el motor

    El terminal IM30 se conecta por USB y cobra primero. Si el motor falla al girar, el sistema reversa el cobro — nunca se cobra por algo que no se entregó.

  3. 3

    Control directo del motor por puerto serie

    La app habla por serie con la placa controladora de la máquina para girar el motor exacto de la fila y columna que corresponde al producto comprado.

  4. 4

    Panel técnico oculto en la propia máquina

    Con PIN, para calibrar motores o reconectar el POS sin depender de un técnico remoto ni reiniciar el equipo.

02

Categorías fijas: un mosaico, dos pantallas

El mismo layout de categorías vive en dos lugares — el panel web las edita, la app las muestra — y ambos entienden la misma regla de armado.

Panel web · quién las edita
Editor de categorías en el panel de Milodón VMC, con el mosaico 1 ancha + 4 en pares + 1 ancha
  • 6 categorías fijas, no una lista abierta

    5 categorías de producto más "Todos los productos" — cada una es un documento en Firestore con nombre, imagen y orden.

  • El mosaico se arma solo

    La primera y la última ocupan el ancho completo; las cuatro del medio van de a pares. El dueño solo sube nombre e imagen, sin tocar una línea de código.

App en la máquina · quién las consume
Categoría 1
Bebidas
Snacks
Chocolates
Caramelos
Todos los productos
  • Grilla de 2 columnas sobre fondo negro

    Un RecyclerView con GridLayoutManager reproduce el mismo criterio: si el total de categorías es impar, la última ocupa las dos columnas.

  • Antes era una regla fija, ahora es una regla real

    El primer código dejaba el ancho completo pegado a las posiciones 0 y 5 a mano — con una cantidad distinta de categorías el layout se rompía. Se generalizó a "la última, si el total es impar".

  • Imágenes cacheadas antes que nada

    Carga primero desde caché offline y solo pide la red si no la encuentra — la grilla no depende de tener señal en ese instante.

Recreación fiel del layout de categorías de la app a partir de sus propios recursos (íconos y paleta), no una captura de pantalla del dispositivo.

Formulario de datos generales del producto
General
Carga de imagen del producto a Firebase Storage
Imagen
Ficha nutricional del producto
Nutrición
03

El sistema de carga de productos

La pieza más particular del panel: el SKU de cada producto es la dirección física de un motor, no un código inventado.

  1. 1

    El SKU es de solo lectura, a propósito

    Es el mismo número que identifica al motor (110, 120, 230…). No se puede escribir un SKU que no exista físicamente en la máquina.

  2. 2

    Imagen por archivo o por URL

    Se sube un archivo directo a Firebase Storage o se pega una URL — la vista previa se actualiza al instante, sin recargar la página.

  3. 3

    Ficha nutricional, no solo nombre y precio

    Proteína, calorías, cafeína, carbohidratos, azúcar y taurina por producto — pensado para bebidas energéticas y suplementos, el catálogo real de la máquina.

  4. 4

    La categoría se lee en vivo desde Firestore

    El selector no es una lista fija en el código: cada vez que se abre el formulario, trae las categorías que existen ese día.

Dashboard del panel de Milodón VMC con estado de la máquina, ingresos del día y transacciones recientes
04

Ventas y estado de la máquina, en vivo

El dueño ve la operación sin ir a la máquina: estado, ingresos y comportamiento del negocio calculados en el momento, no en un reporte del día siguiente.

  1. 1

    Estado ONLINE / STANDBY / OFFLINE

    Calculado según la última transmisión de la máquina, con un banner de alerta visual si hay una falla de hardware activa (motor, POS o placa).

  2. 2

    Ingresos, ventas y producto top del día

    Sumados en vivo desde Firestore cada vez que se carga el panel — sin batch ni reporte que llega horas después.

  3. 3

    Panel de ventas con gráficos por período

    Históricos de día/semana/mes/año y distribución de transacciones aprobadas, fallidas y pendientes, con Chart.js sobre los mismos datos.

Panel de inventario de Milodón VMC mostrando la matriz de motores por fila y columna
05

Inventario mapeado a la matriz física

Cada casillero del panel corresponde 1 a 1 a un motor real dentro de la máquina — fila y columna, no un número inventado.

  1. 1

    La grilla del panel es la grilla de la máquina

    Filas de 6 y de 9 motores, con los mismos códigos (110, 120…) que la placa controladora usa para dirigir el giro.

  2. 2

    Semáforo de stock por motor

    Verde con stock normal, ámbar en ≤3 unidades, rojo en cero — de un vistazo, sin abrir cada ficha.

  3. 3

    Más vendido y menos vendido, sin planilla aparte

    Calculado sobre el mismo inventario que ve la app, para decidir qué reponer antes de ir a cargar la máquina.

Consola de comandos remotos del panel de Milodón VMC con tramas ASCII hacia la placa controladora
06

Una consola para hablarle directo al hardware

La herramienta más cruda del panel: mandarle comandos a la placa controladora desde el navegador, sin ir a la máquina.

  1. 1

    Los mismos comandos ASCII que corren por el puerto serie

    (POLL) para el latido de la placa, (LED1)/(LED0), giro de motor por SKU o una trama cruda — la sintaxis exacta que la placa entiende.

  2. 2

    Girar un motor sin ir a la máquina

    Para destrabar un producto atascado o probar un motor nuevo desde el escritorio, en vez de abrir la máquina en el local.

  3. 3

    Historial en vivo, con la respuesta del hardware

    Cada comando emitido queda registrado con su estado y lo que contestó la placa, escuchando la colección en Firestore en tiempo real.

Consola de logs en tiempo real del panel de Milodón VMC
07

Logs, alertas y cierre de caja solo

Cuando algo falla, no hay que estar mirando la máquina para enterarse — y al final del día, nadie tiene que cerrar la caja a mano.

  1. 1

    Consola de logs en vivo

    Eventos de hardware, comunicación serie y respuestas de la app, con filtro por nivel (error/warn/info) y búsqueda de texto.

  2. 2

    Alertas a Telegram sin exponer el token

    Una Cloud Function separada escucha nuevas alertas en Firestore y le avisa al equipo — la app nunca tiene las credenciales del bot.

  3. 3

    Cierre de caja automático a las 04:00

    Todos los días el sistema cierra el lote de ventas solo, sin que nadie tenga que hacerlo a mano al final del turno.

Integraciones

Con qué habla el sistema.

Transbank · POS IM30

Cobro con tarjeta por USB con el protocolo de "POS Autoservicio" reimplementado a mano — no hay SDK oficial para este flujo.

Firebase · Firestore, Auth y Storage

El sistema nervioso: transacciones, logs, comandos remotos y catálogo, compartidos en tiempo real entre la máquina y el panel.

Telegram Bot API

Alertas al equipo despachadas por una Cloud Function aparte, para que el token del bot nunca viaje dentro de la app.

Placa controladora + lector cashless

Motores y bus de pago por puerto serie, con un protocolo de tramas ASCII propio para cada instrucción de hardware.

2sistemas, un solo Firestore
6categorías fijas, editables sin tocar código
3pestañas por producto: general, imagen, nutrición
04:00cierre de caja automático cada día

¿Tienes un proyecto parecido?

Cuéntanos qué necesitas. Te respondemos con un plan concreto para tu caso, no con una plantilla genérica.