h1. PharmaTablet — Pharmaceutical Tablet Plant
*Owner:* Tatsoft Engineering | *Updated:* March 2026 | *FrameworX:* fx-2020.1.3+
----
{info:title=Download}
[? Download PharmaTablet.dbsln|https://partners.tatsoft.com/dl/JV4rGHCGbRqF/PharmaTablet.dbsln_]
No hardware required — uses ValueSimulator to generate all process data.
{info}
----
h2. Overview
The *PharmaTablet* example demonstrates a complete pharmaceutical tablet manufacturing plant built in FrameworX, covering three production stages: *granulation*, *tablet compression*, and *film coating*. Simulated process data is collected in real time, historized to PostgreSQL, and synchronized to Snowflake every 10 seconds — showcasing a full OT/IT data pipeline with no custom middleware.
----
h2. Architecture
{noformat}
[ValueSimulator] --> [FrameworX Runtime] --> [Unified Namespace]
|
+---------------------------+---------------------------+
| | |
[HMI Display] [Historian] [Scripts]
| |
[PostgreSQL] (10s cycle)
PharmaDatabase |
PharmaTable [Snowflake DW]
{noformat}
----
h2. Unified Namespace (UNS)
All tags are organized under an ISA-95 compliant *Unified Namespace* — a single logical hierarchy that decouples data consumers (HMI, Historian, Scripts) from the underlying device layer. Replacing the simulator with a real PLC requires only a device binding change; nothing else in the solution needs to be updated.
|| UNS Path || Equipment || Key Variables ||
| {{TabletPlant/Granulation/Granulator_01}} | High-Shear Granulator | Temperature, Impeller Speed, Chopper Speed, Moisture, Phase, Batch ID |
| {{TabletPlant/Compression/Press_01}} | Tablet Press | Turret Speed, Compression Force, Tablet Weight, Thickness, Production Count, Reject Count |
| {{TabletPlant/Coating/CoatingPan_01}} | Film Coating Pan | Inlet/Outlet Temp, Pan Speed, Spray Rate, Atomization Pressure, Coat Weight Gain |
----
h2. Historian — PostgreSQL
All process variables are continuously historized via the FrameworX *Historian* module into a PostgreSQL database ({{PharmaDatabase}}, table {{PharmaTable}}). The Historian handles timestamping, compression, and deadband filtering automatically.
----
h2. Snowflake Synchronization
A server-side script ({{write_postgre_to_snowflake}}) runs on a *10-second cycle*, reading new rows from PostgreSQL and writing them incrementally to *Snowflake*. This creates a near-real-time bridge to the cloud data warehouse for analytics and reporting workloads.
|| Property || Value ||
| Sync interval | 10 seconds |
| Source | PostgreSQL · {{PharmaDatabase.PharmaTable}} |
| Destination | Snowflake (configurable) |
| Sync mode | Incremental — new rows only |
{warning:title=Configuration Required}
Snowflake credentials (account, warehouse, database, schema, user, password) must be set inside the script before starting the runtime.
{warning}
----
h2. HMI Overview
The *MainPage* display shows a plant-wide process overview in a single screen, organized left to right following the physical production flow.
|| Zone || Symbol || Gauges ||
| Granulator | Animated blower (impeller motion) | SemiCircle — Temperature; Linear — Moisture (color-ranged) |
| Tablet Press | Tacho — Turret Speed | CircularGauge — Compression Force; KPI boxes — Production / Rejects |
| Coating Pan | Tacho — Pan Speed | Dual vertical linear gauges — Inlet / Outlet Temperature |
Two live *TrendCharts* at the bottom track Press parameters (Compression Force, Weight, Thickness) and thermal data (Granulator Temperature, Coating Inlet/Outlet Temps) over a 5-minute rolling window.
----
h2. Requirements
|| Component || Required || Notes ||
| FrameworX | (/) | fx-2020.1.3 or later, Enterprise license |
| PostgreSQL | (/) | Version 12+. Create {{PharmaDatabase}} before first run. |
| Snowflake Account | (/) | Trial account sufficient for demo. |
| Physical PLC | (i) | Not required — ValueSimulator generates all data. |
----
h2. Getting Started
# *Download and open* {{PharmaTablet.dbsln}} in the FrameworX Designer.
# *Configure PostgreSQL* — update the historian connector connection string. The table {{PharmaTable}} is created automatically on first run.
# *Configure Snowflake* — open the {{write_postgre_to_snowflake}} script and set your account, warehouse, database, schema, username, and password at the top of the file.
# *Start the Runtime* (F5). The simulator starts immediately, historization begins, and the Snowflake sync script activates on its 10-second cycle.
# Open *MainPage* to view the live process overview.
{tip:title=Verify the pipeline}
Run {{SELECT COUNT(*) FROM PharmaTable}} in your Snowflake worksheet — the row count should increase every 10 seconds while the runtime is active.
{tip} |