Omni Session Metrics¶
EmiliaVision's Omni Session Metrics module calculates 37 service quality metrics per dining session, combining video annotations, POS data, and real-time AI suggestions into a unified quality profile.
Architecture¶
flowchart TD
A["Shift Map Storage<br/>shift_map_storage"] --> B["Metrics Engine<br/>metrics.py"]
C["POS Sessions v1<br/>pos_sessions_storage"] --> B
D["POS Sessions v2<br/>pos_sessions_v2_storage"] --> B
E["EchoBase Events<br/>metadata.tables[].echobase_events"] --> B
B --> F["Enriched Shift<br/>version N+1"]
F --> G["ClickHouse<br/>shift_map_storage"] The enrichment CLI reads the latest shift version, calculates metrics for every session, and inserts a new version with session.metrics populated. A SHA-256 fingerprint prevents unnecessary writes when metrics haven't changed.
POS v1 and POS v2 Inputs¶
The metrics engine supports both POS generations:
- Legacy POS v1 uses
session.pos_correlation.pos_session_idto readechobasematrix_{env}_pos_sessions_storage. - POS Sessions v2 uses
session.pos_correlation.pos_uuidto read the latest non-deleted row forpos_session_uuidfromechobasematrix_{env}_pos_sessions_v2_storage.
POS v2 keeps two related but different item timelines. metadata.items is the final financial state used for ticket totals, revenue, and final item counts. metadata.order_events is the operational timeline used for first-order and service timing metrics when available. This distinction matters for printer-backed adapters such as SantoAncho Menew, where commandas can arrive well before the final bill.
When metadata.order_events is absent, POS v2 falls back to metadata.items for timing. When metadata.order_events[].items[] lacks categories, metrics inherits categories from categorized final items by normalized item name. Legacy POS v1 behavior is unchanged.
Category-dependent metrics read POS v2 final item categories and may apply them to operational order-event items at read time. If POS v2 item categories are backfilled or corrected, run enrichment again so affected sessions receive new metric fingerprints and updated shift versions.
Metric Catalog¶
All metrics live at metadata.tables[].sessions[].metrics in the shift_map_storage JSON metadata.
| ID | Field | Type | Source | Details |
|---|---|---|---|---|
| M-1 | manager_touch_count | int | Annotations | Annotation Metrics |
| M-2 | time_to_first_pos_order_seconds | int | null | Annotations + POS | POS Metrics |
| M-3 | time_from_session_start_to_drink_arrival_seconds | int | null | Annotations | Annotation Metrics |
| M-4 | waiter_touch_count | int | Annotations | Annotation Metrics |
| M-5 | hand_raise_count | int | Annotations | Annotation Metrics |
| M-6 | table_cleaned_time_seconds | int | null | Annotations | Annotation Metrics |
| M-7 | food_delivery_from_first_pos_item_seconds | int | null | Annotations + POS | POS Metrics |
| M-8 | first_waiter_contact_time_seconds | int | null | Annotations | Annotation Metrics |
| M-9 | drink_delivery_from_first_pos_item_seconds | int | null | Annotations + POS | POS Metrics |
| M-10 | drink_delivery_from_first_drink_order_seconds | int | null | Annotations + POS | POS Metrics |
| M-11 | food_delivery_from_first_main_dish_order_seconds | int | null | Annotations + POS | POS Metrics |
| M-12 | drink_delivery_from_order_taken_seconds | int | null | Annotations | Annotation Metrics |
| M-13 | food_delivery_from_order_taken_seconds | int | null | Annotations | Annotation Metrics |
| M-14 | bill_payment_to_end_session_seconds | int | null | Annotations | Annotation Metrics |
| M-25 | menu_delivery_time_seconds | int | null | Annotations | Annotation Metrics |
| M-26 | bill_closing_time_seconds | int | null | Annotations | Annotation Metrics |
| M-27 | courtesy_delivery_from_session_start_seconds | int | null | Annotations | Annotation Metrics |
| M-15 | drink_item_count | int | POS | POS Metrics |
| M-16 | main_dish_item_count | int | POS | POS Metrics |
| M-17 | dessert_item_count | int | POS | POS Metrics |
| M-18 | pos_ticket_subtotal | float | null | POS | POS Metrics |
| M-19 | pos_ticket_avg | float | null | POS | POS Metrics |
| M-20 | pos_drink_ticket_total | float | null | POS | POS Metrics |
| M-21 | pos_dessert_ticket_total | float | null | POS | POS Metrics |
| M-22 | pos_server_name_open | str | null | POS | POS Metrics |
| M-23 | pos_server_name_close | str | null | POS | POS Metrics |
| M-24 | pos_top_seller | str | null | POS | POS Metrics |
| — | drink_suggestion_count | int | EchoBase Events | Compliance |
| — | drink_suggestion_compliance_pct | float | null | EchoBase Events | Compliance |
| — | dessert_suggestion_count | int | EchoBase Events | Compliance |
| — | dessert_suggestion_compliance_pct | float | null | EchoBase Events | Compliance |
| — | dessert_compliance_conversion | bool | null | EchoBase + POS | Compliance |
| — | dessert_compliance_conversion_items | int | EchoBase + POS | Compliance |
| — | dessert_compliance_conversion_revenue | float | null | EchoBase + POS | Compliance |
| — | dessert_compliance_conversion_delta_seconds | int | null | EchoBase + POS | Compliance |
| — | drink_compliance_conversion | bool | null | EchoBase + POS | Compliance |
| — | drink_compliance_conversion_count | int | EchoBase + POS | Compliance |
| — | drink_compliance_compliant_clusters | int | EchoBase + POS | Compliance |
| — | drink_compliance_conversion_items | list[int] | EchoBase + POS | Compliance |
| — | drink_compliance_conversion_revenue | list[float | null] | EchoBase + POS | Compliance |
| — | drink_compliance_conversion_deltas | list[int] | EchoBase + POS | Compliance |
| — | delayed_food_items | list[str] | POS + Metrics | SLA Detection |
| — | delayed_drink_items | list[str] | POS + Metrics | SLA Detection |
Metadata Fields¶
Every enriched session also includes:
| Field | Type | Description |
|---|---|---|
omni_metrics_version | str | Version of the Omni Metrics module that calculated these metrics |
fingerprint | str | 8-char SHA-256 hash of all metrics + version — used to skip re-writes |
calculated_at | str | ISO 8601 timestamp of when metrics were calculated |
Null Convention¶
Duration metrics return null when their prerequisite annotations are missing:
- Metrics gated on
start-session: M-2, M-3, M-8, M-25, M-27 - Metrics gated on
end-session: M-6, M-14 - Metrics gated on
bill-dropped+bill-payment: M-26 - Metrics gated on
order-taken: M-12, M-13 - Metrics gated on confirmed POS +
video_start_utc: M-2, M-7, M-9, M-10, M-11
A null metric is not an error — it means the required data was not available for that session.
Count metrics (M-1, M-4, M-5, M-15, M-16, M-17) default to 0, never null.