Back-office access
MQTT broker settings
Online
6/6
CT #457 · Morton demo
Firmware
v1.0.4
All sensors current
ODN Gateway APs
Galgus API not connected
MQTT broker
broker.optified.io
Presence now
Waiting for MQTT
Sensor profiles & keyword tags
Enrich each sensor with structured tags. Tags work like web metadata backlinks — brand:dyson on multiple sensors means querying that tag instantly gives you Dyson’s total exposure across every store and aisle.
Sensor identity
MAC address
Status
Alias
Location
Department
Aisle / zone code
Range profile
Keyword tags
namespace:value — like web metadata
Available namespaces
brand: zone: dept: campaign: aisle: sku-group: category: dooh: traffic:
Tag query — find sensors by keyword
Query any tag across your entire fleet. One tag, instant results. Like a web search but for physical sensor locations.
Quick queries
Fleet tag directory
Brand exposure at scale
Aggregate presence analytics across all sensors sharing a brand tag. One brand tag = instant cross-fleet exposure report across all stores, zones, and campaigns.
Select a sensor from the sidebar to inspect and configure it.
Data insights
Zone tallies, dwell time, engagement, and trend analysis per sensor and store
73,807
Total customers
+12.4% vs prev period
41,440
Engaged customers
+8.1%
56.1%
Engagement rate
+2.3pp
66.4%
Quick exit rate
-1.2pp better
2.3m
Avg quick exit time
+0.2m
8.8m
Avg engaged time
+1.1m
Busiest hour
14:00–15:00
180 avg customers/hr
+6% vs last month
Busiest day
Saturday
2,100 avg customers
+9% vs last month
Busiest zone
CTC457-Media-CashFront-159
8,381 traffic · 60.5% eng
+4% engagement
Avg dwell (engaged)
14.2 min
across all sensors
+1.1m improvement
Customer time-in-store distribution — total vs engaged
Zone tally per hour of day — average customers detected
Zone tally by day of week
Monthly customer trend — 12 months
Engaged vs quick exit customers per sensor
Sources detailed view
Filter zone:
Source Traffic Engaged Eng. rate Avg dwell Quick exits QE rate
Sensor
Latest · 1.0.4
v 1.0.4 Retail New Target Dwell for MOR
https://github.com/josegardo/esp32-ota/raw/refs/heads/main/apollo_1_0_4.bin
Per-zone dwell filter (20/30/45/60s) · MQTT cloud control · NVS persistence · Meerby integration · broker.optified.io
Previous · 1.0.3
Retail Ready — Dwell 4× 5s ODN presence
https://github.com/josegardo/esp32-ota/raw/refs/heads/main/apollo_1_0_3.bin
Retail dwell / aisle analytics · Meerby trigger-ready · broker.optified.io
Stable · 1.0.2
ODN Presence Full — security use case
https://github.com/josegardo/esp32-ota/raw/refs/heads/main/apollo_1_0_2.bin
Per-unit firmware status
Join Digital primary network · OpenWiFi OW Gateway · Multi-protocol edge
Join Qi AP7 (WiFi 7) · ODN SSID: OPT1F13dD@t@ · WPA2-PSK auto-provisions all mmWave sensors · OpenWiFi Controller manages Conf/Events via WebSocket · Galgus shown as legacy below.
joindigital.com →
OPTiFied Architecture 5.0 — OpenWiFi + Multi-protocol gateway layer
OPTiFi Cloud layer
OW Controller Plumbing + sensor config mgmt
OW Gateway WebSocket · OpenWiFi conf/events
Event Engine MOR conf/events · sensor conf/events
MQTT Broker broker.optified.io:1883
Webhook endpoint MOR application · WebSocket
Public API api.optifi.io · Private API endpoint
Multi-protocol gateway
DHCP Server Auto IP on venue LAN
APNOS AP network OS · CHT cognitive wifi
WebSocket Real-time event stream
Webhook Inbound + outbound event triggers
FSK Decode Event creation from RF signals
Protocols BT · WiFi 5GHz · HaLow 900MHz · Thread · Zigbee
OPTiFied Edge Booster
Hardware Intel NUC · DHCP · DNS 8.8.8.8/8.8.4.4
WebSocket Green status real-time agent
MQTT Agent High-volume data processing
ODN SSID OPT1F13dD@t@ · WPA2-PSK
Connected devices Macro mmWave · Door · RFID · Motion · Call buttons
Roadmap Wi-Fi HaLow 802.11ah · Morse Micro · Edgecore
ODN sensor device types on multi-protocol gateway
MQTT Macro
Location Sensor
Shelf Product
Sensor
MQTT Door
Contact Sensor
UHF RFID
Tag Sensor
MQTT Micro
Motion Sensor
MQTT Customer
Call Button
Join Digital access points — CT #457 Kanata site
Galgus GEN3 — legacy / migration
Being replaced by JoinGalgus manager
ODN session view — mmWave sensors on Join network
Sensors auto-provision to Join APs via ODN SSID. Station MAC matches sensor MAC — confirming link between WiFi session and MQTT data stream.
StatusStation MAC (sensor)AP MACSiteSSID RSSISignalChannelfw versionConnected
Campaigns
Create and manage sensor-linked campaigns with locations, days, activations, and audience results. Powered by api.optifi.io/ws/:wsId/campaigns
Active campaigns
3
CT #457 workspace
Campaign locations
8
across 3 campaigns
Total activations
14
this period
Avg engagement
58.4%
across locations
Configure external API endpoints per account or sensor group. Toggle, edit endpoints and API keys — no firmware redeployment required.
Trigger log
Manage accounts, sensor groups, and cross-account sharing. Group admins approve share requests.
Active sensor shares
Global alert routing
OPTiFi operations (always CC)
uptime@OPTiFi.ca
Always active
Account admin — 1st line
Per account
Group alert email
Per group
MSP escalation
MSP only
Alert rules
Notification intervals
First offline alert
Repeat reminder
Low RSSI threshold
-80dBm
Recent alerts
AWS RDS PostgreSQL — OPTiFi data architecture
Multi-tenant schema · sensor telemetry · presence analytics · user IAM · MQTT bridge · Meerby event log
Region: ca-central-1 (Canada) · db.t3.medium → db.r6g.large for production · Multi-AZ recommended
Data flow — MQTT → AWS → PostgreSQL
mmWave sensors
Apollo R-PRO-1
Join ODN WiFi
MQTT QoS 1
broker.optified.io
MQTT broker
AWS EC2 / ECS
Mosquitto / EMQX
pg-bridge Lambda
JSON → SQL INSERT
RDS PostgreSQL
ca-central-1
Multi-AZ + S3 backup
accountsmulti-tenant root
id UUID PK
name TEXT NOT NULL
type account_type ENUM
admin_email TEXT
alert_email TEXT
store_code TEXTMeerby
parent_id UUID FK → accounts
created_at TIMESTAMPTZ
active BOOLEAN DEFAULT true
ENUM account_type: retail | msp | brand | platform
sensor_groupsCT #457, zones
id UUID PK
account_id UUID FK → accounts
name TEXT NOT NULL
site_code TEXTCTC457
location TEXT
is_shared BOOLEAN DEFAULT false
created_at TIMESTAMPTZ
sensorsdevice registry
id UUID PK
mac_address MACADDR UNIQUE NOT NULL
group_id UUID FK → sensor_groups
account_id UUID FK → accounts
alias TEXTCTC457-Media-Furniture-1
firmware_version TEXT
capture_profile TEXTxsmall–xlarge
zone_config JSONBLD2450 zones
gate_config JSONBLD2412 thresholds
join_ap_mac MACADDRFK to AP
status sensor_status ENUM
last_seen TIMESTAMPTZ
provisioned_at TIMESTAMPTZ
ENUM sensor_status: online | warn | offline | staging
sensor_telemetryTimescaleDB / partitioned
id BIGSERIAL PK
sensor_id UUID FK → sensors
ts TIMESTAMPTZ NOT NULLpartition key
rssi SMALLINT
heap_free INTEGER
uptime_s INTEGER
mqtt_connected BOOLEAN
wifi_ssid TEXT
battery_mv SMALLINT
Partition: RANGE(ts) monthly · Retention: 90 days hot → S3 Glacier
presence_eventscore analytics table
id BIGSERIAL PK
sensor_id UUID FK → sensors
account_id UUID FK → accounts
event_ts TIMESTAMPTZ NOT NULL
event_type presence_event_type ENUM
targets_count SMALLINT
zone_id SMALLINT1–3
dwell_seconds INTEGER
is_engaged BOOLEANdwell ≥ threshold
quick_exit BOOLEAN
raw_payload JSONB
ENUM: presence_start | presence_end | zone_enter | zone_exit | target_move
zone_analytics_hourlymaterialized view
bucket TIMESTAMPTZtime_bucket 1h
sensor_id UUID FK → sensors
account_id UUID FK → accounts
zone_id SMALLINT
total_count INTEGER
engaged_count INTEGER
quick_exit_count INTEGER
avg_dwell_s NUMERIC
max_targets SMALLINT
Refreshed every 15 min via pg_cron · powers Insights dashboard
usersIAM
id UUID PK DEFAULT gen_random_uuid()
account_id UUID FK → accounts
email TEXT UNIQUE NOT NULL
name TEXT NOT NULL
role user_role ENUM
password_hash TEXTbcrypt
mfa_secret TEXTTOTP
permissions JSONBfeature overrides
active BOOLEAN DEFAULT true
last_login TIMESTAMPTZ
invited_by UUID FK → users
created_at TIMESTAMPTZ
ENUM user_role: superadmin | msp_admin | retail_admin | insights_only | brand_viewer
sensor_sharescross-account access
id UUID PK
group_id UUID FK → sensor_groups
from_account_id UUID FK → accounts
to_account_id UUID FK → accounts
access_level share_access ENUM
status share_status ENUM
approved_by UUID FK → users
created_at TIMESTAMPTZ
expires_at TIMESTAMPTZoptional
access_level: data_only | data_uptime | full_read  |  status: pending | approved | denied
alert_rulesnotification config
id UUID PK
account_id UUID FK → accounts
rule_type TEXToffline | low_rssi | ota_needed
scope TEXT
threshold_value TEXT
notify_emails TEXT[]always + uptime@OPTiFi.ca
first_alert_min SMALLINT DEFAULT 5
repeat_interval_min SMALLINT DEFAULT 60
active BOOLEAN DEFAULT true
api_endpointsMeerby / webhooks
id UUID PK
account_id UUID FK → accounts
name TEXT
base_url TEXT
endpoint_path TEXT
api_key_enc TEXTAES-256 encrypted
trigger_event TEXT
payload_template TEXT
enabled BOOLEAN DEFAULT true
last_triggered TIMESTAMPTZ
join_access_pointsJoin Digital APs
id UUID PK
account_id UUID FK → accounts
mac_address MACADDR UNIQUE
alias TEXT
model TEXTJoin Qi AP7
site TEXT
firmware_version TEXT
ip_address INET
status TEXT
health_pct SMALLINT
last_contact TIMESTAMPTZ
meerby_eventstrigger audit log
id BIGSERIAL PK
sensor_id UUID FK → sensors
account_id UUID FK → accounts
triggered_at TIMESTAMPTZ NOT NULL
beacon_id TEXT
store_code TEXT
http_status SMALLINT
response_ms INTEGER
lifecycle_status TEXTcreated→complete
AWS infrastructure setup
RDS PostgreSQL
Engine PostgreSQL 16 + TimescaleDB ext
Instance db.t3.medium (dev) → db.r6g.large
Storage 100GB gp3 · auto-scaling to 1TB
Multi-AZ Yes — standby in ca-central-1b
Backups 7-day automated → S3 Glacier 90d
Encryption AES-256 at rest · TLS in transit
Access VPC private subnet only
MQTT → DB bridge
Runtime Node.js 20 Lambda
Trigger MQTT broker → SQS → Lambda
Topics data/# · status/#
Batch 100 msgs/invocation
Pool RDS Proxy (pgBouncer)
Dead letter SQS DLQ → CloudWatch alarm
Deploy Terraform / AWS CDK
Security
Secrets AWS Secrets Manager
Roles Row-level security (RLS)
API keys AES-256 in api_endpoints table
Passwords bcrypt rounds=12
Sessions JWT · RS256 · 8h expiry
MFA TOTP (Authenticator app)
Audit CloudTrail + pg audit log
Key SQL — copy-ready for your RDS instance
-- OPTiFi PostgreSQL schema (AWS RDS ca-central-1) -- Run as: psql -h your-rds-endpoint.ca-central-1.rds.amazonaws.com -U optifi_admin -d optifi CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; CREATE EXTENSION IF NOT EXISTS timescaledb; -- ENUMS CREATE TYPE account_type AS ENUM ('retail','msp','brand','platform'); CREATE TYPE user_role AS ENUM ('superadmin','msp_admin','retail_admin','insights_only','brand_viewer'); CREATE TYPE sensor_status AS ENUM ('online','warn','offline','staging'); CREATE TYPE presence_event_type AS ENUM ('presence_start','presence_end','zone_enter','zone_exit','target_move'); CREATE TYPE share_access AS ENUM ('data_only','data_uptime','full_read'); CREATE TYPE share_status AS ENUM ('pending','approved','denied'); -- accounts (multi-tenant root) CREATE TABLE accounts ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name TEXT NOT NULL, type account_type NOT NULL, admin_email TEXT, alert_email TEXT, store_code TEXT, parent_id UUID REFERENCES accounts(id), active BOOLEAN DEFAULT true, created_at TIMESTAMPTZ DEFAULT now() ); -- sensor_groups CREATE TABLE sensor_groups ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), account_id UUID NOT NULL REFERENCES accounts(id) ON DELETE CASCADE, name TEXT NOT NULL, site_code TEXT, location TEXT, is_shared BOOLEAN DEFAULT false, created_at TIMESTAMPTZ DEFAULT now() ); -- sensors CREATE TABLE sensors ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), mac_address MACADDR UNIQUE NOT NULL, group_id UUID REFERENCES sensor_groups(id), account_id UUID NOT NULL REFERENCES accounts(id), alias TEXT, firmware_version TEXT, capture_profile TEXT DEFAULT 'medium', zone_config JSONB, gate_config JSONB, join_ap_mac MACADDR, status sensor_status DEFAULT 'staging', last_seen TIMESTAMPTZ, provisioned_at TIMESTAMPTZ DEFAULT now() ); -- sensor_telemetry (time-series, partitioned) CREATE TABLE sensor_telemetry ( id BIGSERIAL, sensor_id UUID NOT NULL REFERENCES sensors(id), ts TIMESTAMPTZ NOT NULL DEFAULT now(), rssi SMALLINT, heap_free INTEGER, uptime_s INTEGER, mqtt_connected BOOLEAN, wifi_ssid TEXT, battery_mv SMALLINT, PRIMARY KEY (id, ts) ); SELECT create_hypertable('sensor_telemetry','ts', chunk_time_interval => INTERVAL '1 day'); -- presence_events (core analytics) CREATE TABLE presence_events ( id BIGSERIAL, sensor_id UUID NOT NULL REFERENCES sensors(id), account_id UUID NOT NULL REFERENCES accounts(id), event_ts TIMESTAMPTZ NOT NULL DEFAULT now(), event_type presence_event_type NOT NULL, targets_count SMALLINT DEFAULT 0, zone_id SMALLINT, dwell_seconds INTEGER, is_engaged BOOLEAN, quick_exit BOOLEAN, raw_payload JSONB, PRIMARY KEY (id, event_ts) ); SELECT create_hypertable('presence_events','event_ts', chunk_time_interval => INTERVAL '1 day'); CREATE INDEX ON presence_events (sensor_id, event_ts DESC); CREATE INDEX ON presence_events (account_id, event_ts DESC); -- zone_analytics_hourly (materialized, refreshed by pg_cron) CREATE MATERIALIZED VIEW zone_analytics_hourly AS SELECT time_bucket('1 hour', event_ts) AS bucket, sensor_id, account_id, zone_id, COUNT(*) AS total_count, COUNT(*) FILTER (WHERE is_engaged) AS engaged_count, COUNT(*) FILTER (WHERE quick_exit) AS quick_exit_count, AVG(dwell_seconds)::NUMERIC(8,1) AS avg_dwell_s, MAX(targets_count) AS max_targets FROM presence_events GROUP BY 1,2,3,4; CREATE UNIQUE INDEX ON zone_analytics_hourly (bucket, sensor_id, zone_id); -- Refresh: SELECT cron.schedule('refresh-zone-analytics','*/15 * * * *',$$REFRESH MATERIALIZED VIEW CONCURRENTLY zone_analytics_hourly$$); -- users CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), account_id UUID NOT NULL REFERENCES accounts(id), email TEXT UNIQUE NOT NULL, name TEXT NOT NULL, role user_role NOT NULL DEFAULT 'insights_only', password_hash TEXT, mfa_secret TEXT, permissions JSONB DEFAULT '{}', active BOOLEAN DEFAULT true, last_login TIMESTAMPTZ, invited_by UUID REFERENCES users(id), created_at TIMESTAMPTZ DEFAULT now() ); -- Row-level security: users only see their own account's data ALTER TABLE sensors ENABLE ROW LEVEL SECURITY; ALTER TABLE presence_events ENABLE ROW LEVEL SECURITY; ALTER TABLE sensor_telemetry ENABLE ROW LEVEL SECURITY; CREATE POLICY tenant_isolation ON sensors USING (account_id = current_setting('app.current_account_id')::UUID); CREATE POLICY tenant_isolation ON presence_events USING (account_id = current_setting('app.current_account_id')::UUID); -- sensor_shares (cross-account) CREATE TABLE sensor_shares ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), group_id UUID NOT NULL REFERENCES sensor_groups(id), from_account_id UUID NOT NULL REFERENCES accounts(id), to_account_id UUID NOT NULL REFERENCES accounts(id), access_level share_access NOT NULL DEFAULT 'data_only', status share_status NOT NULL DEFAULT 'pending', approved_by UUID REFERENCES users(id), created_at TIMESTAMPTZ DEFAULT now(), expires_at TIMESTAMPTZ, UNIQUE (group_id, to_account_id) ); -- alert_rules CREATE TABLE alert_rules ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), account_id UUID NOT NULL REFERENCES accounts(id), rule_type TEXT NOT NULL, scope TEXT, threshold_value TEXT, notify_emails TEXT[] DEFAULT ARRAY['uptime@OPTiFi.ca'], first_alert_min SMALLINT DEFAULT 5, repeat_interval_min SMALLINT DEFAULT 60, active BOOLEAN DEFAULT true ); -- api_endpoints (Meerby, webhooks) CREATE TABLE api_endpoints ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), account_id UUID NOT NULL REFERENCES accounts(id), name TEXT, base_url TEXT, endpoint_path TEXT, api_key_enc TEXT, trigger_event TEXT, payload_template TEXT, enabled BOOLEAN DEFAULT true, last_triggered TIMESTAMPTZ ); -- join_access_points CREATE TABLE join_access_points ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), account_id UUID NOT NULL REFERENCES accounts(id), mac_address MACADDR UNIQUE, alias TEXT, model TEXT, site TEXT, firmware_version TEXT, ip_address INET, status TEXT, health_pct SMALLINT, last_contact TIMESTAMPTZ ); -- meerby_events (trigger audit) CREATE TABLE meerby_events ( id BIGSERIAL PRIMARY KEY, sensor_id UUID REFERENCES sensors(id), account_id UUID REFERENCES accounts(id), triggered_at TIMESTAMPTZ NOT NULL DEFAULT now(), beacon_id TEXT, store_code TEXT, http_status SMALLINT, response_ms INTEGER, lifecycle_status TEXT );
Connection string (Node.js):
postgresql://optifi_app:<secret>@your-rds-proxy.ca-central-1.rds.amazonaws.com:5432/optifi?sslmode=require

OPTiFi API (Next.js): https://api.optifi.io


Secrets Manager key: optifi/prod/rds-credentials  ·  IAM role: optifi-lambda-rds-role
All firmware, ESPHome configs, and platform code. Reference these URLs in OTA pushes and YAML generation.
Users & access control
Manage user roles, feature permissions, and cross-account access. Role changes take effect immediately.
Role permission matrix — what each role can access
Feature Super adminMSP adminRetail adminInsights viewerBrand viewer
Data insights & zone analytics
Sensor fleet view (own account)
Sensor configuration & range profiles
Firmware OTA push
Network / Join AP management
ESPHome YAML generator
API router configuration
Account management & sensor sharing
Alert & notification settings
User & access management
Campaigns — create & manage
GitHub & firmware repos
Cross-account data (all orgs)
Full access Partial / scoped No access
Users (6)
Select a user to edit permissions