By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
Energy and Industrial IoT (IIoT) is the backbone of critical infrastructure—power grids, oil rigs, manufacturing plants, and water treatment facilities. As an FDE, you’ll deploy sensor networks, SCADA integrations, and predictive maintenance models in high-stakes, low-connectivity, high-security environments. Example: You’re on-site at a refinery when a critical pump fails. The customer’s SCADA system logs vibration data, but their on-premise historian is air-gapped. You must: 1. Extract sensor data from an OPC-UA server (no internet, no cloud).2. Process it locally (Python + SQLite) to flag anomalies.3. Deploy a lightweight ML model (ONNX runtime) to predict failures before the next shutdown.4. Integrate with their existing HMI (Human-Machine Interface) without disrupting operations.5. Train operators to use it—while they’re running a 24/7 shift.
This isn’t just "IoT"—it’s mission-critical, zero-trust, zero-downtime engineering.
SCADA (Supervisory Control and Data Acquisition): The nervous system of industrial control systems (ICS). Real tools: Ignition, Siemens WinCC, Rockwell FactoryTalk, OSIsoft PI. FDEs often write Python scripts to pull data from SCADA via OPC-UA or Modbus.
OPC-UA (Open Platform Communications Unified Architecture): The secure, vendor-neutral protocol for industrial data exchange. Use opcua-asyncio (Python) or UA-.NET (C#) to read/write tags. ⚠️ Never expose OPC-UA to the internet—it’s a prime attack vector.
opcua-asyncio
UA-.NET
Edge Computing: Running analytics on-site (e.g., Raspberry Pi, NVIDIA Jetson, or industrial PCs) to avoid latency and comply with air-gapped requirements. Tools: K3s (lightweight Kubernetes), Docker (with --privileged for hardware access), TensorFlow Lite.
--privileged
Predictive Maintenance (PdM): Using ML to predict equipment failures before they happen. Not just "train a model"—FDEs must:
Integrate with CMMS (Computerized Maintenance Management System) like SAP PM or IBM Maximo.
Air-Gapped Deployment: No internet? No problem. FDEs use:
apt-offline
yum --downloadonly
pip install --no-index --find-links=/mnt/usb/wheels
Manual ATO (Authorization to Operate) processes (expect 3–6 months of paperwork).
Modbus (RTU/TCP): The old-school industrial protocol (1979!). Used in legacy PLCs. Tools: pymodbus (Python), libmodbus (C). ⚠️ Modbus is unencrypted—never use it over public networks.
pymodbus
libmodbus
Time-Series Databases (TSDB): Optimized for sensor data. Real tools:
OSIsoft PI (enterprise, but requires a PI Server license).
Digital Twin: A real-time virtual replica of a physical asset (e.g., a wind turbine, a pump). FDEs build these by:
Pyomo
Visualizing in Grafana or Ignition Perspective.
MQTT (Message Queuing Telemetry Transport): Lightweight pub/sub protocol for IoT. Use Mosquitto (broker) + paho-mqtt (Python client). ⚠️ Always use TLS—MQTT is a common attack vector.
paho-mqtt
PLC (Programmable Logic Controller): The "brain" of industrial automation (e.g., Siemens S7, Allen-Bradley ControlLogix). FDEs interact with PLCs via:
Python libraries (python-snap7 for Siemens).
python-snap7
ATO (Authorization to Operate): The security approval required to deploy in government/defense/energy sectors. FDEs must:
Pass audits (e.g., NIST 800-53, IEC 62443).
Ask vs. Infer (FDE Mindset):
Goal: Avoid building the wrong thing.Actions:- Map the data flow: - OPC-UA Server (PLC) → SCADA (Ignition) → Historian (OSIsoft PI) → ??? - Draw this on a whiteboard (take a photo).- Identify constraints: - Is the network air-gapped? (→ No cloud, no pip install.) - What’s the PLC brand? (Siemens? Allen-Bradley? → Different protocols.) - What’s the security policy? (→ No Docker? No Python 3.10?) - Ask the "5 Whys": - "Why do you need predictive maintenance?" → "To reduce downtime." - "Why is downtime a problem?" → "Because it costs $500K/hour." - Now you know the real ROI.
OPC-UA Server (PLC) → SCADA (Ignition) → Historian (OSIsoft PI) → ???
pip install
Goal: Pull data from industrial systems into a usable format.Actions:- For OPC-UA: python from opcua import Client client = Client("opc.tcp://192.168.1.10:4840") client.connect() pump_vibration = client.get_node("ns=2;i=12345") print(pump_vibration.get_value()) # Live data! ⚠️ Test with Wireshark to confirm the OPC-UA traffic is encrypted (port 4840).- For Modbus: python from pymodbus.client import ModbusTcpClient client = ModbusTcpClient("192.168.1.20") response = client.read_holding_registers(0, 10, slave=1) print(response.registers) # Raw sensor values - For SCADA (Ignition): - Use Ignition’s REST API or SQL Bridge to query tags. - Example: curl -u admin:password "http://ignition-server/data/tags?path=Pump/Vibration"
python from opcua import Client client = Client("opc.tcp://192.168.1.10:4840") client.connect() pump_vibration = client.get_node("ns=2;i=12345") print(pump_vibration.get_value()) # Live data!
Wireshark
4840
python from pymodbus.client import ModbusTcpClient client = ModbusTcpClient("192.168.1.20") response = client.read_holding_registers(0, 10, slave=1) print(response.registers) # Raw sensor values
curl -u admin:password "http://ignition-server/data/tags?path=Pump/Vibration"
Goal: Ensure data is usable before modeling.Actions:- Check for missing data: python import pandas as pd df = pd.read_csv("sensor_data.csv") print(df.isnull().sum()) # >5% missing? Investigate. - Check for drift: python df["vibration"].plot() # Sudden jumps? Sensor miscalibrated. - Check for outliers: python df["vibration"].hist() # Values >1000? Probably noise. - Cross-check with SCADA: - Does the vibration value match what’s on the HMI? If not, the OPC-UA tag might be wrong.
python import pandas as pd df = pd.read_csv("sensor_data.csv") print(df.isnull().sum()) # >5% missing? Investigate.
python df["vibration"].plot() # Sudden jumps? Sensor miscalibrated.
python df["vibration"].hist() # Values >1000? Probably noise.
Goal: Build a model that runs on a Raspberry Pi (or worse).Actions:- Start simple: - Rule-based: "If vibration > X, alert." - Statistical: "If vibration > 3σ from mean, alert." - Then ML (if needed): python from sklearn.ensemble import IsolationForest model = IsolationForest(contamination=0.01) model.fit(df[["vibration", "temperature"]]) df["anomaly"] = model.predict(df) # -1 = anomaly - Optimize for edge: - Convert to ONNX (smaller, faster): python from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType initial_type = [("float_input", FloatTensorType([None, 2]))] onx = convert_sklearn(model, initial_types=initial_type) with open("model.onnx", "wb") as f: f.write(onx.SerializeToString()) - Test on target hardware: bash # On the edge device (e.g., Jetson Nano) python3 -m onnxruntime model.onnx
python from sklearn.ensemble import IsolationForest model = IsolationForest(contamination=0.01) model.fit(df[["vibration", "temperature"]]) df["anomaly"] = model.predict(df) # -1 = anomaly
python from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType initial_type = [("float_input", FloatTensorType([None, 2]))] onx = convert_sklearn(model, initial_types=initial_type) with open("model.onnx", "wb") as f: f.write(onx.SerializeToString())
bash # On the edge device (e.g., Jetson Nano) python3 -m onnxruntime model.onnx
Goal: Get the model running in production without breaking anything.Actions:- For air-gapped environments: - Pre-download dependencies: bash pip download -d ./wheels pandas scikit-learn onnxruntime - Transfer via USB (with checksums): bash sha256sum wheels/* > checksums.txt - Install offline: bash pip install --no-index --find-links=./wheels pandas - For zero-downtime: - Blue-green deployment: - Run old and new versions side-by-side. - Switch traffic only after validation. - Feature flags: python if os.getenv("USE_NEW_MODEL") == "1": model = load_onnx_model() else: model = load_old_model() - For security: - Hardening: bash # Disable SSH root login sudo sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config sudo systemctl restart sshd - Network segmentation: - Put the edge device on a separate VLAN from the SCADA network. - Use firewall rules to restrict access (e.g., only allow OPC-UA from the PLC).
bash pip download -d ./wheels pandas scikit-learn onnxruntime
bash sha256sum wheels/* > checksums.txt
bash pip install --no-index --find-links=./wheels pandas
python if os.getenv("USE_NEW_MODEL") == "1": model = load_onnx_model() else: model = load_old_model()
bash # Disable SSH root login sudo sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config sudo systemctl restart sshd
Goal: Ensure the customer can use and maintain the system.Actions:- Integrate with SCADA/HMI: - Write a Python script that pushes alerts to Ignition via REST API. - Example: python import requests requests.post( "http://ignition-server/api/alerts", json={"message": "Pump vibration anomaly detected!"}, auth=("admin", "password") ) - Train operators: - 1-page cheat sheet (e.g., "How to acknowledge an alert"). - Live demo (e.g., "Here’s what happens when the vibration spikes").- Documentation: - Runbook: "How to restart the edge device if it crashes." - Data dictionary: "What does ns=2;i=12345 mean?" - Security checklist: "How to rotate API keys."
python import requests requests.post( "http://ignition-server/api/alerts", json={"message": "Pump vibration anomaly detected!"}, auth=("admin", "password") )
ns=2;i=12345
time.sleep(0.1)
journalctl -u opcua-server -f
dmesg | grep -i error
df.to_csv("predictions.csv")
Answer: Use Python + ONNX runtime (no Docker needed) and pre-download all dependencies (pip download).Why: Docker is often blocked in industrial environments—stick to lightweight, container-free deployments.
pip download
Answer: Scaling factor mismatch—SCADA applies a multiplier (e.g., 100x) to raw sensor data. Check the OPC-UA tag’s engineering units.Why: Always cross-check with the HMI to avoid unit mismatches.
Answer: Use a Modbus-to-OPC-UA gateway (e.g., Kepware) or write a Python script with pymodbus to read registers.Why: Modbus RTU is serial (RS-485)—you’ll need a USB-to-serial adapter and the correct baud rate.
4843
502
1883
8883
pip install onnxruntime
pip install --no-index --find-links=/mnt/usb/wheels pandas
tcp.port == 4840
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.