How do you integrate a SCADA with a MES using .NET and OPC UA?
The correct architecture requires a decoupling layer (the middleware) that handles tag mapping, buffering during disconnection, data validation, and retry logic. The MES is never connected directly to the SCADA: the two systems have very different lifecycles, availability requirements, and data models.
Those who can build this integration in C# solve one of the most concrete problems in Italian manufacturing: production data that exists but cannot communicate.

The line is producing. The data exists. But they do not talk to each other.
Picture this scene: the production manager opens the MES at 8 in the morning and sees that batch 4872 is "In progress." But nobody tells him whether the machine is actually running, whether the temperature is within specification, or whether there have been any rejects in the last two hours. That information exists. It is in the SCADA, recorded in real time, updated every second. But nobody connected it to the MES.
The result? The operator calls the line supervisor. The line supervisor looks at the SCADA monitor. He writes the figures down on a piece of paper. The paper ends up in a spreadsheet. The spreadsheet is uploaded into the MES the following day. Yesterday's data is twenty-four hours old. Wrong decisions based on wrong data, every day, on every line.
This is the real cost of a missing SCADA-MES integration. It is not a theoretical problem discussed at Industry 4.0 conferences: it is the operational reality of hundreds of Italian manufacturing companies in 2026, from small businesses with a single production line to large groups with multiple plants.
The problem has a precise technical solution: connecting the SCADA to the MES through OPC UA, the standard protocol for integration between industrial systems, using a middleware written in C# that handles data mapping, buffering, and business logic.
Those who know how to build this integration in .NET are among the most sought-after professionals in Italian manufacturing. That is not an exaggeration: it is a market fact. System integration companies specializing in Industry 4.0 struggle to find developers who know both the .NET world and OT protocols. The combination is rare, and the market pays accordingly.
This guide explains how SCADA-MES integration works, what the correct architecture looks like, how to implement an OPC UA client in C#, and what it means to build a system like this that holds up in production 24 hours a day, 365 days a year.
If you already have experience with C# and .NET, you are halfway there. Let us build the rest together.
What is a MES and where does it fit in the ISA-95 production pyramid alongside SCADA
To understand why integrating SCADA and MES matters so much, you first need to understand that the two systems live at different levels of the same pyramid. The international standard that describes this structure is called ISA-95, and it is the shared reference used by all industrial system vendors to define which information flows between which levels.
The ISA-95 pyramid has five levels, numbered from 0 at the bottom to 4 at the top:
Levels 0 and 1 (field and control): physical sensors, motors, valves, actuators, PLCs. This is the physical world of the plant. PLCs execute control logic in millisecond cycles.
Level 2 (supervisory): the SCADA. It collects data from PLCs, displays it to operators, and allows control commands to be sent. Its time unit ranges from seconds to minutes.
Level 3 (manufacturing execution): the MES. It manages production orders, batches, process recipes, material traceability, quality checks, and KPIs. Its time unit ranges from minutes to shifts.
Level 4 (enterprise management): the ERP (SAP, Oracle, Microsoft Dynamics). It plans production, manages purchasing, sales, and accounting. Its time unit ranges from shifts to months.
The MES is the translator between the physical world and the management world. It receives planned production orders from the ERP (what to produce, how many units, by when) and converts them into operational instructions for the lines. Downward, it communicates with the SCADA to send process parameters (the recipe, the production target, the batch identifier). Upward, it returns actual results to the ERP: how many units were actually produced, how much raw material was consumed, and which non-conformities occurred.
What does a MES concretely do? The main functions, defined by the MESA International standard, include: batch traceability, recipe management (process instructions for each product), quality data collection and analysis, OEE calculation (Overall Equipment Effectiveness, the primary production KPI), maintenance and downtime management, and material and work-in-progress consumption control.
In the Italian market you find MES solutions such as Aveva MES (formerly Wonderware), Siemens Opcenter, Aveva PI System, and custom solutions developed internally or by local software houses. In the pharmaceutical sector, GMP compliance (Good Manufacturing Practice) adds even more stringent traceability and audit trail requirements.
The key question is: if the MES knows the production orders and the SCADA knows the physical reality of the plant, how do we make them talk reliably, securely, and in real time?
The SCADA-MES integration problem: duplicate data, manual errors and delayed decisions
Before talking about technical solutions, it is worth quantifying the problem. The lack of SCADA-MES integration is not just an operational inefficiency: it has a measurable economic impact that in more structured companies ends up in board reports.
The typical scenario without integration works like this: the SCADA records production counters, temperatures, pressures, and rejects in real time. At the end of the shift, the operator reads these figures from the monitor and writes them on the shop floor paper form. The paper form is collected by the shift supervisor, who enters the data into the MES (or into a spreadsheet that someone later imports into the MES). The MES uses this data to calculate line efficiency and declare production to the ERP.
The problems in this chain are at least four. First: delay. The data declared in the MES is already hours or a full day behind reality. If a quality issue is occurring, it is discovered only after production has already advanced.
Second: transcription errors. Reading a value from the SCADA screen and writing it on paper inevitably introduces mistakes. Transposed digits, wrong units of measure, values written in the wrong field. In a pharmaceutical plant, a mistake like this can lead to the entire batch being blocked.
Third: systematic discrepancies. The SCADA counts the pieces that pass the end-of-line sensor. The operator declares packaged units in the MES. The difference between the two numbers should be rejects, but often the two sources use different definitions of "piece" or have different counting points. Who is right? Without integration, there is no way to reconcile the two counts automatically.
Fourth: duplication of work. Data is collected once in the SCADA and entered manually a second time in the MES. Double work, double risk of error, double cost.
A Manufacturing Enterprise Solutions Association study estimates that manufacturing companies lose between 5% and 15% of production efficiency due to unintegrated information systems. On a line that generates 2 million euros of value per year, that means between 100,000 and 300,000 euros of unrealized value.
There is also a less quantifiable but equally real problem: the loss of contextual information. When an operator manually transcribes data, he selects what to report and what to omit. Anomalies that seem unimportant to him, temperature spikes lasting a few seconds, micro-stoppages not declared as official stops: all of this remains in the SCADA but never reaches the MES. The production history is incomplete by definition.
OPC UA as the industrial integration standard: why it is the right choice in 2026
When studying how to connect a SCADA to a MES, several technical options come to mind. Custom REST APIs, CSV files on a shared folder, an intermediate database, message brokers like RabbitMQ or Kafka. Each has its use cases. But in the context of integration with industrial SCADA systems, OPC UA is the correct choice in the vast majority of cases, and it is worth understanding why.
OPC UA (OPC Unified Architecture) is the IEC 62541 standard for machine-to-machine communication in industrial systems. It is not a protocol invented by a vendor: it is an open standard maintained by the OPC Foundation and adopted by Siemens, ABB, Rockwell, Schneider, Beckhoff, and all major automation system manufacturers. When a SCADA exposes an OPC UA server, any OPC UA client can connect, regardless of the vendor of the SCADA or MES system.
Compared to alternatives, OPC UA offers three structural advantages that other solutions do not have:
The standardized object model (Address Space). A SCADA that exposes data via OPC UA does not just expose numerical values: it exposes a tree of nodes with types, units of measure, allowable ranges, descriptions, and hierarchical relationships. The client knows not only that the value is "87.3" but that it is the "Zone 3 temperature of Oven 1," measured in degrees Celsius, with an allowable range between 80 and 95. This semantic context is impossible to convey with a simple CSV or a REST API that returns raw numbers.
Built-in security. OPC UA includes X.509 certificate authentication and TLS encryption for all communications. This is critical when crossing the boundary between the OT network (where the SCADA lives) and the IT network (where the MES or middleware lives). Alternatives such as files on a shared folder or databases accessible from both networks create attack vectors that OT security managers will not accept.
The publish/subscribe mechanism (Subscriptions and MonitoredItems). Instead of constant polling (every second asking "what is the current temperature value?"), the OPC UA client creates a subscription and declares which nodes it wants to monitor. The server sends updates only when values change beyond a configurable threshold (the "deadband"). This drastically reduces network traffic and load on the SCADA server compared to polling, which in plants with thousands of tags can become a serious problem.
There is also the OPC UA PubSub mode, introduced in more recent versions of the standard, which enables one-to-many communication through MQTT or AMQP brokers. It is the preferred mode for cloud-first architectures where multiple systems need to consume the same SCADA data.
SCADA-MES integration architecture with .NET: the system components
Before writing a single line of code, the architecture must be clear. A common mistake in industrial integration projects is connecting the MES directly to the SCADA without an intermediate layer. It seems like the simplest solution, but in production it becomes a serious problem.
The two systems have completely different lifecycles. The SCADA is updated rarely (an update to a production SCADA system requires a scheduled maintenance window, extensive testing, and approval from the plant manager). The MES follows normal IT release cycles with frequent updates. If they are directly connected, every MES update risks interrupting communication with the SCADA.
The solution is an integration middleware, a dedicated software layer that decouples the two systems. The correct architecture has these components:
SCADA OPC UA Server: the SCADA system (Ignition, WinCC, iFIX, Aveva, or custom) exposes process data through an OPC UA server. The SCADA tags (temperatures, counters, machine states, alarm codes) are navigable in the OPC UA address space.
.NET Middleware (Windows Service or microservice): a C# application that connects as an OPC UA client to the SCADA, receives data via subscriptions, transforms it into the format expected by the MES, and writes it through the MES APIs. The middleware also handles the inverse logic: it receives production commands from the MES (batch start, recipe change, quantity target) and writes them as OPC UA variables to the SCADA.
MES with REST API or OPC UA client interface: the MES system receives data from the middleware through a REST API interface or, in more modern systems, exposes its own OPC UA server for data reception.
Historian database: a time-series database (InfluxDB, TimescaleDB, Aveva PI System) that historizes all process data read from the SCADA. The historian is separate from the MES database: it contains all data, including data that the MES does not use, at maximum temporal resolution.
The middleware has precise responsibilities that go beyond simply reading and writing data:
Tag mapping: the name of a tag in the SCADA ("PL01.Z3.TEMP.PV") does not correspond to the field name in the MES ("Zone3OvenCurrentTemperature"). The middleware maintains a mapping table that translates between the two worlds. This table is configurable without recompiling the application.
Transformation and normalization: the SCADA may express temperatures in Celsius, while the MES expects them in Kelvin. The SCADA may count pieces as integers, while the MES expects them as decimals with an explicit unit of measure. The middleware converts.
Local buffering and persistence: if the MES is unreachable (maintenance, update, network failure), the middleware accumulates data locally and sends it as soon as the connection is restored. Without this buffer, the MES downtime window translates into a gap in the historical data.
Validation and filtering: not all values read from the SCADA need to be sent to the MES. The middleware filters out values with OPC UA "Bad" quality, values outside physical range (broken sensors returning -9999), and duplicates identical to the previous value when the OPC UA deadband is not optimally configured.
Implementing an OPC UA client in C# to read data from the SCADA
Let us get to the code. The reference library for OPC UA in .NET is OPCFoundation.NetStandard.Opc.Ua, available on NuGet and maintained directly by the OPC Foundation. It is the official library, not a third-party wrapper, and it is the one that SCADA vendors themselves use for their SDKs.
Installation is straightforward. Add the NuGet package to the project file:
dotnet add package OPCFoundation.NetStandard.Opc.UaThe structure of an OPC UA client in C# follows these steps: configure the application (name, security certificate), create a session with the SCADA server, navigate the address space to find the nodes of interest, create a subscription and MonitoredItems to receive updates.
The central point is the Subscription. You do not poll: you tell the SCADA server "I want to be notified when the value of these tags changes beyond threshold X." The server takes care of sending updates. This is the mechanism that makes OPC UA efficient even with thousands of simultaneously monitored tags.
// Create the subscription
var subscription = new Subscription(session.DefaultSubscription)
{
PublishingInterval = 1000, // updates at most every 1 second
LifetimeCount = 100,
KeepAliveCount = 10
};
// Add the tags to monitor
var monitoredItem = new MonitoredItem(subscription.DefaultItem)
{
StartNodeId = new NodeId("ns=2;s=PL01.Z3.TEMP.PV"),
AttributeId = Attributes.Value,
SamplingInterval = 500, // server-side sampling every 500ms
QueueSize = 10,
DeadbandType = (uint)DeadbandType.Absolute,
DeadbandValue = 0.5 // notify only if change exceeds 0.5 degrees
};
monitoredItem.Notification += OnTagValueChanged;
subscription.AddItem(monitoredItem);
session.AddSubscription(subscription);
subscription.Create();The OnTagValueChanged callback receives a MonitoredItemNotificationEventArgs object containing the value, the sampling timestamp (on the SCADA side) and the reception timestamp (on the client side), and the data quality (Good, Bad, Uncertain).
One critical aspect is data quality management. OPC UA associates a status code with every value indicating whether the data is reliable. "Good" quality means the sensor is functioning correctly. "Bad" quality means the data is unreliable (sensor fault, broken communication between PLC and SCADA). "Uncertain" quality indicates intermediate situations (sensor in calibration, value outside input range). The middleware must handle these three states differently: "Bad" values should never be sent to the MES as real process values, but should be logged as anomaly events.
The other critical aspect is disconnection handling. The industrial network is not the internet: managed switches, dedicated VLANs, very low latencies. But disconnections still happen: network maintenance, scheduled SCADA restarts, firmware updates. The OPC Foundation library includes the SessionReconnectHandler pattern that automatically handles reconnection attempts:
session.KeepAlive += (s, e) =>
{
if (ServiceResult.IsBad(e.Status))
{
if (reconnectHandler == null)
{
reconnectHandler = new SessionReconnectHandler();
reconnectHandler.BeginReconnect(s, 10000, OnReconnectComplete);
}
}
};During reconnection, the middleware continues to accept commands from the MES and queues them. When the OPC UA session is restored, the queue is processed in order.
Sending commands from MES to SCADA and back: writing OPC UA variables
SCADA-MES integration is not just about reading. The MES must be able to send commands to the SCADA: start a production batch, stop the line for a changeover, set the recipe for the next product, define the shift quantity targets. This requires writing OPC UA variables from the .NET client.
Writing an OPC UA node is more delicate than reading for two reasons. First: not all nodes are writable. The OPC UA server can define read-only nodes (physical sensor values) and writable nodes (setpoints, commands, recipes). The client must respect this distinction. Second: an incorrect write can have immediate physical consequences. Sending a wrong setpoint temperature to an industrial furnace is not like writing a wrong value to a database: the consequences can be immediate and costly.
For this reason, the middleware must implement a validation logic before writing: verify that the value is within the allowable range, that the data type matches the OPC UA node type, that there are no other pending commands for the same node, and that the machine state allows the change (you do not change a recipe while the machine is running).
// Writing an OPC UA node with error handling
var writeValue = new WriteValue
{
NodeId = new NodeId("ns=2;s=PL01.RECIPE.SET"),
AttributeId = Attributes.Value,
Value = new DataValue(new Variant(recipeId))
};
var writeResults = await session.WriteAsync(
null,
new WriteValueCollection { writeValue },
CancellationToken.None);
if (StatusCode.IsBad(writeResults.Results[0]))
{
logger.LogError("Recipe write failed: {StatusCode} - NodeId: {NodeId}",
writeResults.Results[0], writeValue.NodeId);
throw new OpcUaWriteException(writeResults.Results[0]);
}For more complex operations, OPC UA defines the concept of a Method: a function exposed by the server that the client can call with input parameters and receive output parameters. An OPC UA Method can represent operations like "StartBatch(orderNumber, productCode, quantityTarget)" that the SCADA executes as an atomic operation. OPC UA Methods are preferable to multiple separate variable writes because they guarantee atomicity: either all settings are applied, or none are.
On the reverse flow side, when the SCADA needs to notify the MES of asynchronous events (batch end, critical alarm, machine state change), there are two approaches. The first is polling by the middleware: an OPC UA MonitoredItem that watches machine state tags in the SCADA and reacts to changes. The second is the use of OPC UA Events: the SCADA generates typed events (alarm events, state change events) that the OPC UA client receives as structured notifications.
The recommended pattern for critical commands (production start/stop, recipe change) is: the MES sends the command to the middleware, the middleware writes the OPC UA node or calls the SCADA Method, waits for execution confirmation by reading a status node, and only then notifies the MES of the outcome. This confirmation cycle is essential to prevent the MES from considering a command executed that the SCADA never received.
Managing data quality: timestamps, out-of-range values and broken connections
This is the chapter that tutorials never cover, yet it makes the difference between middleware that works in a lab and middleware that holds up in production for years. Data quality problems in SCADA-MES integration are predictable and manageable, provided they are considered during the design phase.
The timestamp problem. OPC UA data arrives with two timestamps: the SourceTimestamp (when the PLC sampled the value, using the SCADA clock) and the ServerTimestamp (when the OPC UA server received the value from the PLC). The middleware has a third clock: the operating system of the server it runs on. In a real plant, these three clocks can drift from each other by seconds. If the MES records data with the middleware timestamp and the SCADA records with its own timestamp, data from the two systems do not align correctly in time.
The solution is to always use the SourceTimestamp as the data timestamp, and to implement NTP synchronization across all systems in the plant. When the SourceTimestamp is anomalous (in the future, or much older than expected), the middleware must flag it as suspect data.
The stale value problem. When communication between the PLC and the SCADA is interrupted, the OPC UA server continues to expose the tag with the previous value, but with "Bad" or "Uncertain" quality. If the middleware does not check quality and still transmits the value to the MES, the MES receives data that appears current but is actually frozen at the time of the last good communication. In a process where the temperature of a furnace changes quickly, a 30-second stale reading can be dangerously misleading.
The rule: never transmit to the MES a data point with quality other than "Good" as a valid process value. Data with "Bad" quality is written to the event log as "sensor communication loss" with start and end timestamps.
The local buffer problem. When the MES is unreachable, the middleware accumulates data in a buffer. The buffer size must be dimensioned based on two parameters: the maximum expected MES downtime (typically an overnight update window, 2 to 4 hours) and the sampling frequency of the fastest tags. An oversized buffer wastes RAM unnecessarily; an undersized buffer leads to data loss during maintenance windows.
For buffers of significant size (millions of data points), SQLite is a pragmatic choice: it is embedded in the process, requires no separate server, and handles the fast sequential writes typical of industrial middleware well.
The spike and physically impossible value problem. Industrial sensors fail. A broken thermistor can return -9999 or 99999 degrees. These values pass through the PLC, reach the SCADA, are exposed via OPC UA, and if the middleware does not filter them, they arrive in the MES and historian as real data. The middleware must have a physical range table for each tag and discard (with logging) values outside the range before forwarding them.
ERP SAP integration through the MES: the complete flow from machine to management system
The ISA-95 pyramid does not stop at the MES. In structured companies, the MES in turn integrates with the ERP (typically SAP, but also Oracle, Microsoft Dynamics, or vertical solutions). Understanding this end-to-end flow is important for developers designing the SCADA-MES integration, because the format and structure of data are influenced by how the MES will pass them to the ERP.
The typical flow for a production batch, from ERP to plant and back, works like this:
Descending phase (from ERP to plant): SAP generates a production order with all parameters (product code, bill of materials version, quantity, required date, cost center). The MES receives the order, schedules it on the available line, and creates the production batch with a unique traceability number. The .NET middleware writes the batch parameters to the SCADA: identifier, process recipe, quantity target, expected cycle time.
Production phase: the SCADA monitors the machine, counts pieces, records stoppages, and measures quality parameters. The middleware reads this data in real time and writes it to the MES. The MES updates the batch status (percentage completion, pieces produced, rejects, declared stoppages) and calculates OEE in real time.
Ascending phase (from MES to ERP): at batch end, the MES confirms the SAP order with actual figures: how many units were produced, how much raw material was consumed, what processing times occurred. In SAP, this translates into a Production Confirmation (via MIGO or CORK in the PP transaction) that updates inventory, production costs, and item availability.
The technical challenges of this flow are mainly three. The first is unit of measure management: SAP manages materials using units of measure defined in the master data (pieces, kg, liters, meters). The SCADA measures in physical units that may not coincide (counter pulses, sensor millivolts, raw engineering units). The MES is the conversion point, and the middleware must know the applicable conversion factors.
The second challenge is bill of materials version management. SAP can have multiple versions of the same bill of materials, and the version to use depends on its validity date. When the middleware receives from the MES the bill of materials to apply, it must verify that the version matches the current one in SAP.
The third challenge is reject and rework management. The SCADA records pieces rejected at the inline quality check. But SAP distinguishes between definitive rejects (scrap) and pieces to be reworked. This classification requires a human decision that the middleware cannot fully automate: the system can flag the reject, but the final classification must go through the quality manager.
A mature architecture places the MES as the decoupling point between the SCADA and SAP: the SCADA knows nothing about SAP, and SAP knows nothing about the SCADA. The MES speaks both languages and acts as translator. This decoupling is valuable when one of the two systems is replaced: upgrading the SCADA does not require touching the SAP integration, and vice versa.
Security in SCADA-MES integration: crossing the IT/OT boundary without opening vulnerabilities
SCADA-MES integration requires connecting two networks that in most Italian plants are (correctly) kept separate: the OT network where the SCADA lives and the IT network where the MES and ERP live. Crossing this boundary securely is one of the primary responsibilities of the .NET middleware.
The standard network model for IT/OT integration includes a DMZ (demilitarized zone) between the two segments. The .NET middleware resides in this DMZ: it has read/write access to the OPC UA server in the OT network (with a firewall that permits only the OPC UA port, typically 4840) and access to the MES APIs in the IT network. There is no direct connectivity between the OT and IT networks.
OPC UA simplifies security because it integrates it directly into the protocol. Every OPC UA connection can be configured with three security levels: none (only for development, never in production), message signing with X.509 certificates, and signing plus encryption with TLS. The middleware must use at minimum the signing level, preferably signing and encryption.
Managing X.509 certificates in OPC UA is one of the most tedious aspects during setup, but it is essential. The SCADA server has a certificate, the middleware client has a certificate, and they must mutually trust each other. This trust is configured in the OPC UA server's "Trusted Store": the SCADA system administrator must approve the client certificate before the connection is accepted. In structured corporate environments, this process goes through the corporate PKI (Public Key Infrastructure).
On the application authentication front, the middleware authenticates to the OPC UA server using a dedicated account with only the necessary permissions: read access to process tags, write access to specific command nodes. Never use administrator accounts for application connections.
A frequently overlooked topic is the audit trail. Every OPC UA variable write by the middleware (every command sent to the SCADA) must be recorded in an immutable log with: timestamp, written value, previous value, write outcome, and application identity. In plants subject to regulatory compliance (pharmaceutical, food, chemical), this audit trail is not optional: it is required by FDA 21 CFR Part 11 regulation or European Good Manufacturing Practices.
Who can do this integration is worth gold: job opportunities in Italian manufacturing
Let us get to the point that probably brought you to read this far. Not OPC UA theory, but the concrete question: is this skill worth anything on the job market? The short answer is: yes, and more than you might think.
Italian manufacturing is the second largest industrial sector in Europe by added value. Companies in mechanical engineering, pharmaceuticals, food and beverage, ceramics, paper, and textiles have production plants that generate data continuously. But most of these plants have SCADA and MES systems that do not communicate, or that communicate through manual processes that add delays and errors.
The problem is not the will to integrate: it is the lack of professionals who know how to do it. A developer who knows only the IT world (C#, REST APIs, relational databases) does not have the skills to work with OT protocols. An automation engineer who knows only the OT world (PLCs, SCADA, industrial networks) does not have the software skills to build robust middleware. The person who knows how to do both is genuinely rare.
The hardest positions to fill at system integration companies specializing in Industry 4.0 are exactly this: .NET developers with knowledge of industrial protocols (OPC UA, Modbus, Profinet) and understanding of IT/OT architecture. Annual salaries for these senior positions range from 45,000 to 65,000 euros, with peaks above that for those with specific experience in SAP integration or pharmaceutical plants.
The types of companies seeking these skills are diverse. System integration firms (Accenture Industry X, Reply, Engineering, and dozens of smaller specialized firms) build SCADA-MES integration platforms on behalf of manufacturing clients. MES vendors (Aveva, Siemens, and vertical software houses) look for developers who can build OPC UA connectors to the various SCADA systems on the market. Large manufacturing companies with in-house IT departments (familiar names like Barilla, Luxottica, Brembo) seek industrial developers to manage and develop their internal systems.
How does one build this professional profile starting from C# and .NET? The path has three phases. The first is acquiring the fundamentals of industrial protocols: understanding what PLCs are, how OPC UA works, what the ISA-95 model means. This part is theoretical and can be studied. The second is hands-on practice with the OPC Foundation library against a test OPC UA server (open-source simulators like Prosys OPC UA Simulation Server are available for free). The third, and most important, is working on a real project, even a small one, in an industrial context.
A structured training program, like the one BestDeveloper offers for C# developers who want to enter the industrial world, significantly compresses the timeline of this learning curve. Those who already have a solid foundation in C# and .NET architectures can acquire the specific OT skills within a few months of guided work.
Italian manufacturing needs this kind of professional. The line is producing. The data exists. Someone has to make it talk.
Frequently asked questions
MES stands for Manufacturing Execution System. It is the software that manages production execution at the shop floor level: it receives production orders from the ERP, assigns them to production lines, tracks progress in real time, records material consumption, monitors quality, and calculates KPIs such as OEE (Overall Equipment Effectiveness). It is the middle layer between the physical world of SCADA and the administrative world of ERP.
SCADA and MES live in two different worlds. SCADA belongs to OT (Operational Technology): it measures the physical world in milliseconds, has extremely high availability requirements, and often runs on isolated networks. MES belongs to IT: it handles business logic, integrates with ERP and CRM, and follows normal software release cycles. Making them communicate means crossing the IT/OT boundary with all the security, data format, and update frequency challenges that entails.
OPC UA (OPC Unified Architecture) is the IEC 62541 standard protocol for communication between industrial systems. Compared to alternatives (custom REST APIs, CSV files, shared databases), it offers three key advantages: a standardized object model that describes data semantically, built-in security with X.509 certificates and TLS encryption, and a publish/subscribe mechanism that allows the MES to receive updates as soon as values change, without constant polling.
The official library is OPCFoundation.NetStandard.Opc.Ua, available on NuGet. It is maintained by the OPC Foundation, the body that defines the standard, and supports both client mode (for reading and writing nodes on a SCADA server) and server mode (for exposing data from a .NET application). It supports .NET Standard 2.0 and is therefore compatible with .NET 6, 7, 8 and later.
ISA-95 is the international standard (ANSI/ISA-95) that defines data models and interfaces between industrial control systems and management systems. It defines a five-level automation pyramid (from the physical field to the ERP) and specifies which information must flow between each level: production orders, output declarations, material consumption, quality data. Following ISA-95 in SCADA-MES integration ensures that data has a shared meaning between the two systems.
The OPC Foundation library includes the SessionReconnectHandler pattern that automatically handles reconnection attempts when a session is interrupted. The client monitors the KeepAlive event: when the status becomes Bad, it starts the reconnection process with exponential backoff. In the meantime, a local buffer (in-memory queue or SQLite) saves data received before disconnection to avoid losing it. When the connection is restored, the buffer is flushed to the MES.
A .NET developer with industrial integration skills (OPC UA, field protocols, IT/OT architecture) is a rare hybrid profile. Annual salaries for senior positions at specialized system integrators or industrial IT departments range from 45,000 to 65,000 euros, with peaks above that for those with specific experience in SAP integration or pharmaceutical plants (where GMP compliance adds significant value). Demand consistently outpaces supply in the Italian market.
