Hello World, I'm cvag

  • Software Engineer
  • Industrial IoT
  • Systems Monitoring
  • Backend & Infrastructure

Either increase your sacrifice or reduce desire.

Career

Roles and scope — the systems themselves are in Projects.

2023 — Present

Software Engineer

@ Synapsecom Telecoms S.A.

End-to-end engineer on two production lines: Coolblock, the company's immersion-cooling product, and the platform running the company's data centre. A two-person team — a solutions architect and me — which is why the span is the whole of it: sensor and PLC at one end, the operator's interface at the other, and the pipeline that puts a release on site in between.

  • Coolblock, the software — the controller inside every deployed unit and the platform over the whole fleet, joined by a zero-trust overlay: telemetry out, setpoints in and upgrades applied in place, with no inbound firewall rule, no public address and no VPN into the customer's network. A unit that loses the overlay keeps running. See Coolblock Panel and Coolblock Portal.
  • Coolblock, the plant — the process side that software drives: heat and flow balance, component selection, the PID routines holding the operating band, and the calibrated instrumentation and unit network it is all measured on — solved for a PUE below 1.1. See Immersion Cooling System R&D and Immersion Cooling IoT.
  • Data centre monitoring and control — one operator view over facility equipment speaking four different protocols — generators, UPS, precision cooling, fire detection and Siemens PLCs — with control actions issued and faults alerted from that same view. See Data Center Infrastructure Monitoring.
  • Metering and server telemetry — per-rack electrical consumption for every tenant in the facility, ending in the monthly report the business bills against — a scheduled, auditable job in place of manual meter readings — and out-of-band health, thermal and power readings taken from the submerged cluster servers without an agent on them. See Tenant Power & Energy Monitoring Platform and Redfish Server Telemetry.

2022 — 2023

Presidential Guard

@ Hellenic Army

  • One year of national service with the Presidential Guard.
  • Awarded the rank of Lance-Corporal, Company Duty.

2021

Software Engineering Intern

@ PD Neurotechnology

Signal analysis for a Parkinson's disease monitoring platform — custom wearable sensors, an Android application and a cloud platform. My part was the algorithm that turns a patient recording into a measurable clinical result.

  • Recording to score — time-series and Fourier analysis of accelerometer, gyroscope and magnetometer signals, with classifiers trained on the captured recordings scoring tremor, bradykinesia, dyskinesia, dysmobility and finger tapping from the same data.
  • Inputs worth trusting — filtering and cross-device calibration, so two units report the same movement as the same numbers before any symptom analysis runs on them.
  • Validated, then shipped — output checked against real patient recordings and clinical observation, then delivered as a class inside the Android application, so a guided test returns its result on the phone rather than in the cloud. See Signal Analysis for Parkinson's Disease Symptoms.

2016 — 2022

Diploma — Electrical and Computer Engineer

@ University of Patras School of Engineering

  • Five-year integrated Diploma in Electrical and Computer Engineering — the Greek engineering degree, an integrated Master's-level qualification.
  • Diploma thesis — blockchain health records — a platform where patients own their vital signs and grant or revoke a doctor's access on-chain: vital signs captured by a sensor board of my own design, reports stored on IPFS, access enforced by a Solidity contract on Ethereum, and an Android client for each side. I built all four. The thesis is in Nemertes. See Blockchain Health Records Platform.

Featured Projects

Production systems I built end to end. The source lives in private company repositories — the architecture is all here.

Coolblock Portal

Coolblock · Synapsecom Telecoms S.A. · 2023 — Present

The fleet-facing platform for immersion cooling systems: one place to watch and drive every deployed unit. Each system in the field runs its own Coolblock Panel, and the Portal reaches all of them across a zero-trust overlay network — no unit exposes a port and no site needs an inbound firewall rule.

Coolblock Panel

Coolblock · Synapsecom Telecoms S.A. · 2023 — Present

The on-site controller for a single immersion cooling system, running on the embedded industrial PC bolted to the unit. The same containerised stack ships to every system in the fleet and is provisioned per installation by model and serial number, so one build serves the whole product line while each appliance drives exactly one machine. It is the field half of Coolblock Portal.

Immersion Cooling System R&D

Coolblock · Synapsecom Telecoms S.A. · 2023 — Present

The process side of the immersion cooling line, with one target behind all of it: a system whose cooling costs under a tenth of what the IT load draws — a PUE below 1.1. Everything here serves that number — the heat and flow balance that fixes where the system has to run, the component selection that follows from it, the PLC routines that hold it there, and the instrumentation it is all measured on. It is what Coolblock Panel reads and writes on site.

Immersion Cooling IoT

Coolblock · Synapsecom Telecoms S.A. · 2023 — Present

The instrumentation and network layer of an immersion cooling unit: the sensors calibrated and configured, the controllers that carry their readings, the fieldbus between controller and PLC, and the LAN everything sits on. It is the layer between the plant designed in Immersion Cooling System R&D and the software of Coolblock Panel — the path a physical reading takes before any application ever sees it. Laid out so every unit ships with the same LAN and stays serviceable for configuration and diagnostics without a site visit.

Data Center Infrastructure Monitoring

Synapsecom Telecoms S.A. · 2023 — Present

Real-time monitoring and control for critical data centre facility systems, giving operators one view of equipment that speaks four different protocols. Telemetry from generators, UPS systems, Uniflair precision cooling, VESDA fire detection and Siemens PLCs is collected, stored, visualised and alerted on.

Tenant Power & Energy Monitoring Platform

Synapsecom Telecoms S.A. · 2023 — Present

An end-to-end platform for collecting, storing and billing electrical consumption per data centre tenant. Racks fitted with a power distribution unit are polled over SNMP; racks without one are metered directly by Accuenergy current transformers measuring each phase. A scheduled Python job reads both, so every rack is accounted for regardless of how it is instrumented.

Nautobot is the source of truth for tenants, racks and infrastructure ownership. The collection logic lives in GitLab and is synchronised with Nautobot, so the job is scheduled, its changes are reviewable and its reports are structured. Measurements are written to InfluxDB and presented through Grafana.

Redfish Server Telemetry

Synapsecom Telecoms S.A. · 2023 — Present

Health, thermal and power telemetry for the cluster servers running inside the immersion cooling system. Each server's baseboard management controller is polled over the Redfish API, so readings come from the hardware itself rather than from an agent inside the operating system, and a submerged server is monitored without touching what runs on it.

Blockchain Health Records Platform

University of Patras · Diploma thesis · 2021 — 2022

A health monitoring and management platform where patients own their vital signs and grant or revoke a doctor's access on-chain. Conceived during the COVID-19 pandemic, it pairs a custom sensor board with two Android clients and an Ethereum contract that holds the authorisation logic.

Signal Analysis for Parkinson's Disease Symptoms

PD Neurotechnology · 2021

Signal analysis for Parkinson disease symptoms monitoring. Custom PCB wearables capture movement during guided patient tests and daily life, stream it to an Android app, and an analysis algorithm turns each recording into a measurable result. The result is pushed to cloud platform.

Coolblock Portal

PUBLIC SURFACE Browser Cloudflare zone · proxied · DNS-01 token ORIGIN TLS · LET'S ENCRYPT Traefik mTLS · OWN CA / /auth /api /monitor nginx + React static SPA · replicated Keycloak OIDC · realm from config FastAPI uvicorn · replicated Grafana auth.jwt · verifies via JWKS admin proxy dashboard POST iframe request the caller's Keycloak JWT, forwarded as a header resources PostgreSQL isolated network Redis QUEUE PER INTENT telemetry wide · single-threaded each PLC writes concurrency 1 · serialised time-series writes multi-threaded resources sync runs alone · read-only InfluxDB data network · not published alerts + history Grafana rules · REST API OPENZITI OVERLAY telemetry pulled GET · the Panel's API PLC operations pushed POST · the Panel's API FIELD Coolblock Panel hosted service under the unit's own identity CI · GITLAB CD · PORTAINER GitLab CI env vars · build push GitLab Registry private · versioned pull Portainer stack + env deploy Target VM Docker agent

Solution

Domain and public edge
Cloudflare holds the zone and proxies the public hostnames: it terminates TLS at its own edge and re-encrypts to the origin, so the origin address never appears in DNS. It also holds the API token Traefik uses to answer the DNS-01 challenge, so certificate issuance and renewal need no inbound HTTP path of their own.
Origin routing
Traefik terminates the origin connection on Let's Encrypt certificates and dispatches by host and path: the interface at the root, the API under /api, identity under /auth and embedded dashboards under /monitor. The identity provider's admin console answers only on a separate entrypoint, so it is never reachable on the public hostname.
Internal TLS
public trust stops at Traefik. Behind Traefik the stack mints its own certificate authority at deploy and issues a leaf per service, and the internal hops are mutually authenticated on those certificates: Traefik re-encrypts to every backend rather than passing plaintext between containers, and a service proves its identity to its peer instead of being trusted for sharing a bridge network.
Application tier
a replicated FastAPI backend on uvicorn, behind a React and TypeScript interface served as static assets by nginx, also replicated.
Identity
Keycloak as the OIDC provider, its realm rendered from configuration and imported at boot, backed by a PostgreSQL instance of its own on an isolated network.
Keycloak reached through the backend
the interface never calls Keycloak's admin API itself: FastAPI proxies those calls under an admin service account, and the resources sync worker holds a separate read-only service account to pull realm resources back on its own schedule. Neither account's token is cached or written to a database — each is requested, used and dropped.
Dashboards provisioned from the backend
a Grafana dashboard is rendered from a Jinja template per system model and POSTed to Grafana's API, so a new model arrives with its dashboard rather than with a ticket asking someone to build one.
Dashboard embeds authenticated as the user
the monitoring page asks the backend for a panel and Traefik carries the caller's Keycloak token through to Grafana in the header its JWT auth reads. Grafana verifies the signature against the realm's JWKS endpoint rather than holding a secret of its own, takes the user from the token's sub claim, and maps a realm claim onto a Grafana role, so an embedded panel renders as the signed-in user with the permissions their own token grants. There is no shared Grafana account, no anonymous embed and no second login to keep in step with the portal's own.
Alerts and alert history
Grafana alert rules run over the fleet's time series, so a threshold breach, an equipment fault or a unit that has stopped reporting raises an alert without anything in the application tier polling for it. The portal reads both live and resolved alerts back over Grafana's REST API and renders them in its own interface, so an operator sees the fleet's alert state and its history without leaving the portal to go and find it.
Queue per intent
Celery over Redis, with worker count and concurrency sized to the job rather than uniformly: telemetry collection runs wide across single-threaded workers, PLC writes stay serialised so two setpoints can never race a controller, time-series writes run multi-threaded, and the Keycloak resources sync runs alone.
Scheduling
a celery beat scheduler enqueues the recurring collection and reconciliation work, so polling the fleet is a scheduled job rather than a request.
Time-series storage
InfluxDB holds the fleet's history, bound to localhost and reachable only across the internal data network rather than published.
Network segmentation
seven bridge networks partition the stack by concern — public surface, application tier, identity, broker, data plane, relational stores and the field overlay — so a container only sees the peers its job actually requires.
Zero-trust field reach
only the telemetry and PLC-write workers sit on the overlay network. They are the sole path from the platform out to deployed units, and nothing else in the stack can reach the field at all.

Panel and Portal

Two halves of one product
the Panel is the software inside a unit; the Portal is the platform over the fleet. Every deployed system runs its own Panel, and the Portal is the single place the whole fleet is seen and driven from.
The Panel hosts, the Portal dials
the Panel publishes its API as a hosted service on the OpenZiti overlay under the unit's own identity, and the Portal's workers are enrolled identities authorised to dial it. Neither side opens an inbound port, and no VPN reaches into the customer's network.
Telemetry pulled
the telemetry workers poll each unit's Panel API across the overlay on a schedule, and the readings land in the Portal's own time-series store, so fleet-wide history is queryable in one place rather than per machine.
Setpoints pushed
control actions travel the other way over the same overlay to the Panel, which is what actually reaches the Siemens and Carel PLCs. The Portal never speaks a field protocol itself.
Where the boundary sits
the Panel owns the machine and keeps controlling it on its own, with its own interface, storage and alerting; the Portal owns the fleet view. A unit that loses the overlay keeps running.

CI/CD

Build
GitLab CI builds the backend and interface images and publishes them to a private registry, versioned, so a deployment names a release rather than a branch.
Deploy
the stack is deployed and tracked as a Portainer stack from a central server, with no compose file on the host itself; the agent on each host only exposes the Docker socket to it. What runs is defined in one place rather than on whichever machine happens to run it.
Convergence at start
certificate generation, realm templating, schema patching and dashboard provisioning run as one-shot jobs that execute at stack start and exit. A fresh deployment converges on its own, and a rebuild reproduces the same stack rather than a hand-finished one.
Edge & TLS
  • Traefik
  • Nginx
  • Cloudflare
  • Let's Encrypt
Application
  • FastAPI
  • React
  • TypeScript
  • REST APIs
Identity
  • Keycloak
  • OAuth 2.0 / OIDC
  • SSO
  • JWT
  • OpenZiti
Queue
  • Celery
  • Redis
Databases
  • InfluxDB
  • PostgreSQL
Observability
  • Grafana
Delivery
  • Docker
  • Portainer
  • GitLab CI

Coolblock Panel

SITE NETWORK OPENZITI OVERLAY Operator on the unit's own network Coolblock Portal dials in as an enrolled identity Traefik terminates TLS on the unit's network interface the operator interface is the only published route OpenZiti tunnel host networking · unit's identity hosts the panel — no inbound port / requests inward nginx + HTML/CSS/JS operator interface · replicated Express server behind the interface FastAPI uvicorn · replicated · unpublished MySQL bound to localhost config · users · rules · audit Redis broker · six queues by intent QUEUE PER INTENT PLC reads runs wide PLC writes concurrency 1 time-series reads runs wide time-series writes concurrency 1 alert evaluation concurrency 1 alert notification concurrency 1 InfluxDB every cycle's readings · live values and their history notifications off the eval path telemetry in setpoints out FIELD Siemens PLC · Profinet Carel PLC · Modbus TCP same local network — no boundary crossed CI · GITLAB CD · BASH ON THE UNIT GitLab CI builds versioned images push GitLab Registry private · pinned tags docker login · that account pinned images Embedded PC Ubuntu · Docker · systemd one Compose project recreated in place installer + credentials the unit's own identity GitHub deploy repo · one per unit installer script · compose definition system model · component models · device serial ziti JWT · GitLab registry account (read-only)

Solution

One build, provisioned per unit
the stack is written against a model definition rather than one machine. System model, serial number and PLC model come from the installation's own environment, so the same images drive every model in the product line and supporting a new one is configuration, not a fork.
Edge
Traefik terminates TLS on the unit's network interface and fronts the operator interface. The API carries no route of its own, so the interface is the only thing published on the site network.
Operator interface
replicated frontend containers serving plain HTML, CSS and JavaScript, with an Express server behind them and MySQL holding system configuration, users, alert rules and audit records. The database is bound to localhost, so it is never reachable off the box.
API
a replicated FastAPI backend on uvicorn, serving both the interface and the fleet platform.
Queue per intent
Celery over Redis, split into six queues each with its own replicas and concurrency: PLC reads and time-series reads run wide, while PLC writes, time-series writes, alert evaluation and alert notification each run at a concurrency of one.
Serialised writes
every write queue runs single-threaded, so setpoints reaching the PLC and points reaching InfluxDB are serialised and cannot interleave, no matter how many replicas are up.
Field I/O
two protocol clients drive the system's control hardware: Profinet to the Siemens PLC and Modbus TCP to the Carel PLC, carrying telemetry in and setpoints out. The controllers sit on the same local network as the panel, so control traffic never crosses a network boundary.
Time-series storage
InfluxDB holds the real-time metrics: every polling cycle writes the readings taken from the PLCs, so the interface, the alert rules and the metrics API all query live values and their history from one store.
Alerting
operator-defined rules are evaluated against live readings on every cycle, and a separate notifier queue delivers whatever fires, so evaluation is never blocked behind delivery.
Audit logging
control actions and configuration changes are recorded against the identity that made them, so any setpoint written to the plant can be traced back to a person.
Zero-trust remote access
a tunnel container with host networking and its own overlay identity publishes the panel as a hosted service on an OpenZiti network. Instead of opening a port, the panel is reachable only to enrolled identities the overlay authorises, so a unit needs no inbound firewall rule, no public address and no VPN into the site network.
Flat network by design
one bridge network carries every container except the host-mode tunnel. A single-tenant appliance on a controlled site network trades the fleet platform's per-concern segmentation for something an engineer can reason about on site.

Panel and Portal

Two halves of one product
the Panel is the software inside a unit, the Coolblock Portal is the platform over the fleet. Every deployed system runs its own Panel; the Portal is where the whole fleet is seen and driven from.
Opposite ends of the same overlay
the Panel's tunnel hosts its service inward onto the overlay under the unit's identity, while the Portal's workers dial outward as enrolled identities. Same network, opposite roles, and neither side opens an inbound port.
Telemetry out
the Portal reaches the panel across the overlay and keeps its own fleet-wide history, so the same readings serve both the local interface and the fleet view without the unit ever being exposed.
Setpoints in
control actions arriving from the Portal land on the same API and go through the Panel's own write queues, so a remote setpoint is serialised, audited and traced to an identity exactly like a local one.
Standalone by design
the Panel owns the machine. It keeps controlling, storing, evaluating alerts and serving its operator interface whether or not the overlay is up; the Portal adds the fleet view on top, it is not a dependency.

CI/CD

Build
application code and its pipeline live in GitLab, which builds and publishes versioned images to a private registry, so what ships to a unit is a pinned image rather than a checkout. The code and the images live in GitLab; the deployment repository that installs them lives in GitHub, one per unit.
Log shipping
a Vector container collects the unit's container and host logs and forwards them off the box into a central Loki store, so a deployed unit's logs are queryable without anyone logging into it.
Deploy
an installer script brings the stack up from a single Compose definition held in that unit's own GitHub deployment repository, and the whole stack is one Compose project owned by a systemd unit, so a power cut restores the machine to running without anyone logging in.
Remote upgrade
a deployed unit is upgraded in place over the overlay by pulling pinned image versions and recreating the stack, so any installation in the fleet reaches a known release without a site visit.
A credential per unit, not one for the fleet
every immersion system authenticates to the image registry as its own service account rather than sharing a single pull credential. A unit lives on a customer's site, in a room nobody here controls, so it is treated as something that can be lost: if one is compromised its access is revoked on its own and the rest of the fleet keeps pulling. It is the same principle as the unit's own overlay identity, applied to the supply of its code — per-unit identity, individually revocable, so decommissioning needs no more of a site visit than upgrading does.
Field I/O
  • Profinet
  • Modbus TCP
  • Siemens PLC
  • Carel PLC
Application
  • FastAPI
  • Express
  • HTML5
  • CSS
  • JavaScript
  • REST APIs
Queue
  • Celery
  • Redis
Databases
  • InfluxDB
  • MySQL
Observability
  • Vector
  • Loki
Edge & access
  • Nginx
  • Traefik
  • OpenZiti
Platform
  • Advantech
  • Ubuntu
  • Docker
  • systemd
Delivery
  • GitLab CI
  • GitHub

Immersion Cooling System R&D

Solution

Heat balance
the IT load sets the heat the dielectric fluid has to carry, and the fluid's own properties set how much flow that takes for a given temperature rise. A dielectric fluid holds less heat per litre than water and is thicker, so the same load needs more flow and costs more pressure — most of the design follows from that.
Setpoints
fluid temperature is derived from the equipment's own limit downwards, and flow from the temperature rise allowed across the tank against what that flow costs in pumping power. Both come out as bands that hold across the load range, not single design points.
Optimisation
more flow evens out temperatures but costs power faster than it buys them, and colder fluid helps the equipment while making the fluid thicker and the heat harder to reject. The operating point is the one with the lowest total power that still keeps every component under its limit at worst-case ambient — that total, against the IT load, is the PUE, so the design target is what the optimisation is solved for rather than something checked afterwards.
Component selection
pumps, exchanger and heat rejection sized against that operating point rather than a catalogue rating, and compared under real thermal load, since off-design behaviour and fluid compatibility are not on a datasheet.
PLC routines
the control logic on the Siemens and Carel PLCs that holds the band: PID loops on circulation and heat rejection, temperature and pressure differences as the process variables, min/max limits, interlocks, safety conditions and the alarm states the panel surfaces to an operator.

Instrumentation

Measured where the balance is written
temperatures, differential pressure, flow and level taken at the points the heat balance is drawn across, so the routines act on measured conditions and the balance closes on real numbers.
Calibration
the balance rests on a small temperature difference, so a fraction of a degree of sensor offset is a large error in it. Every sensor is commissioned against reference readings and checked across units, so the same condition reports the same number on two systems.
Controller and PLC
readings land on IFM controllers as analogue or digital field I/O and reach the Siemens or Carel PLC over Profinet or Modbus, so the routines run against the same I/O the telemetry comes from. The path from there into software is Immersion Cooling IoT.
Engineering
  • Thermodynamics
  • Heat Transfer
  • Fluid Dynamics
  • Heat Dissipation
  • Control Systems
Control & I/O
  • Siemens PLC
  • Carel PLC
  • PLC
  • Profinet
  • Modbus TCP
Field signals
  • 4-20mA
  • 0-10 VDC
  • Digital I/O
Instrumentation
  • IFM Controllers
  • IFM Sensors
  • Sensor Calibration
IoT
  • MQTT
  • HTTP

Immersion Cooling IoT

INTERNET Engineer, off the WAN no route to a private WAN address the tunnel is the only way in Internet reached outbound, never inbound the router dials out to the cloud VPN — full tunnel, no translation NATed again at the edge CORPORATE INDUSTRIAL WAN Corporate industrial WAN private routed network — the gateway's WAN address lives here an engineer already on it needs no tunnel · the LAN's only path out GATEWAY · NAT WAN-IP:port egress Gateway device WAN side: a corporate address · LAN side: the unit's private range destination NAT — a port on the WAN address lands on device:port source NAT — the LAN reaches the internet as that WAN address uplinks, in order: wifi · ethernet · cellular tracked by ping UNIT LAN in: device:port out IFM controller IoT: HTTP · MQTT fieldbus: to the master reads sensor metrics sensor firmware & config sensor diagnostics Siemens / Carel PLC the fieldbus master reads controller metrics writes to field devices runs the plant Pumps & field devices Profinet or Modbus card on the models that carry one Embedded PC runs the Coolblock Panel Modbus / Profinet client Profinet / Modbus Profinet / Modbus polls the PLC over the LAN WIRED I/O IFM sensors calibrated · scaled · sampled wired in, not on the LAN Analogue a continuous range, scaled to engineering units two kinds carry it Digital a discrete on / off state 0 or 1, nothing to scale 4–20 mA current loop · live zero 0–10 VDC voltage · run-length bound

Solution

Sensor calibration and setup
each sensor is commissioned against reference readings and set up on its controller with the right range, scaling and sampling, so what the controller reports is the measured condition rather than a raw count.
Controller and sensor communication
addressing, protocol parameters and process-data mapping configured per device, so every reading arrives on a known address in a known unit instead of being discovered later in software.
IFM controller, two interfaces
the controller carries an IoT management interface speaking HTTP and MQTT for configuration and telemetry, and a separate fieldbus interface — Profinet or Modbus — for communication with the master PLC. The two are configured independently: one is how the unit is managed and read, the other is how it is controlled.
PLC as fieldbus master
the Siemens or Carel PLC drives Profinet and Modbus devices and reads and writes the signal level underneath them, in two classes: analogue, a continuous range arriving either as a 4-20 mA current loop or as a 0-10 VDC input, and digital, a discrete 0/1 state.
What sits on the LAN
the IFM controller, the PLC, the embedded PC running Coolblock Panel, and, on the models that carry a network card, the pumps and any other Profinet or Modbus field device. Sensors stay wired into the controller rather than networked.
The panel is a fieldbus client too
the embedded PC does not just sit on the LAN, it speaks the protocols: its own Modbus TCP and Profinet clients poll the PLC for telemetry and push setpoints back, so control traffic stays inside the unit and never crosses the gateway.
Network configuration
every one of those has fixed addressing on the unit's own LAN. There is no dynamic pool at all: each device is pinned by a static mapping against its MAC, so an address exists because it was declared rather than because something asked for one.
One gateway, two sides
the LAN sits behind a gateway whose WAN side is a static address on the company's industrial WAN, not a public one, and whose LAN side is the unit's own subnet and first hop. The internet sits upstream of that WAN rather than being it.
Outbound, source NAT
LAN-to-WAN forwarding is enabled for both private and public destinations, translated to the address of whichever uplink is active. That is how a controller or the panel reaches the internet at all, and the corporate edge translates it a second time on the way out.
Inbound, destination NAT in two shapes
port-translating forwards for the field devices, where an outside high port lands on Modbus TCP 502 or on a controller's HTTP 80; and same-port rules bound to a specific WAN address for the panel host's HTTPS, HTTP and SSH. The rule set is declared once per uplink, so a failover does not take the mappings with it.
Several uplinks, one policy
wifi, ethernet and cellular in that failover order, each tracked by pinging public resolvers so a dead uplink is detected rather than assumed. Public resolvers and rebind protection are set on the WAN side.
Devices with no default gateway still answer
gateway-less routing is enabled, so a PLC or controller commissioned with an address and nothing else stays reachable from outside its own subnet, which is the normal state of field equipment.
Why translation rather than routing
units ship with the same private LAN layout, so LAN addresses are not unique across the fleet. The gateway's WAN address is what identifies a unit, and NAT at that boundary is what lets identical LANs coexist on one WAN without renumbering a deployment.

Remote access

From the industrial WAN, no tunnel
an engineer already on the corporate WAN reaches the gateway's WAN address directly and a forwarding rule lands them on a specific controller, PLC or panel. The WAN routes as far as the gateway; the gateway translates the rest of the way in. What is reachable this way is exactly what has a rule.
From the internet, a full tunnel
a private WAN address is not routable from the internet, so the path in is a VPN that terminates on the gateway itself and lands on its LAN interface. Source NAT is off on the tunnel: the client keeps its own address, and every device on the unit is reachable on its own LAN address and native port rather than through a mapped one.
Nothing opened for the tunnel
the gateway dials out to the cloud service that brokers the VPN session, so remote access needs no inbound rule on the WAN and no listening port on a public address anywhere.
The two paths are deliberately unequal
the forwarding rules are a keyhole per service, reachable by anything on that plant WAN, so they stay limited to what must be reachable from it. The tunnel is the whole LAN, and it is gated on the VPN instead. Either way a deployed unit is serviceable for configuration and diagnostics without a site visit.

Hardware stack

Controllers
IFM controllers as the IoT and field-IO layer.
Sensors
temperature, pressure, flow and level instrumentation, calibrated per unit.
PLCs
Siemens and Carel controllers as fieldbus masters.
Gateway
an IXON IXrouter: the unit's router onto the corporate industrial WAN, its NAT boundary, its VPN endpoint, and its multi-uplink failover.
Instrumentation
  • IFM Controllers
  • IFM Sensors
  • Sensor Calibration
Field signals
  • 4-20mA
  • 0-10 VDC
  • Digital I/O
Fieldbus
  • Profinet
  • Modbus TCP
  • Siemens PLC
  • Carel PLC
  • PLC
IoT
  • MQTT
  • HTTP
  • REST APIs
Network
  • LAN
  • Industrial WAN
  • VLANs
  • NAT & Port Forwarding
  • VPN
  • IXON Remote Access

Data Center Infrastructure Monitoring

Facility equipment Generators · UPS systems Uniflair precision cooling VESDA fire detection Siemens PLCs Modbus TCP/IP PROFINET MQTT SNMP REST API Node-RED poll · protocol translation scheduling · error handling normalises to consistent names, units, tags and timestamps one flow per equipment class InfluxDB retained for incidents, capacity, trends Grafana one operator view · real-time and historical Alert rules equipment faults · UPS battery · cooling failure · threshold breach · comms loss authorised control actions CI · GITLAB CD · PORTAINER GitLab compose definition + flows push Portainer redeploys the stack on commit deploy Stack on VM Node-RED · InfluxDB · Grafana

Solution

Multi-protocol collection
Node-RED flows poll each class of equipment over Modbus TCP/IP, PROFINET, MQTT, SNMP and REST APIs, so hardware from different vendors and communication layers reaches one workflow. The flows carry the polling, event processing, protocol translation, scheduling and error handling.
What is measured
generator state, alarms, electrical values and runtime; UPS input and output metrics, battery condition, load, bypass and power quality; cooling temperature, humidity, compressor and fan status and set points; fire-detection early-warning, fault and health conditions; PLC signals, interlocks and environmental values.
Normalisation
protocol-specific payloads become structured time-series points with consistent naming, units, timestamps, tags and equipment metadata.
Operator actions
authorised control actions are issued from the platform through the automation layer, shortening operator response time.
Storage and dashboards
InfluxDB retains the telemetry for incident investigation, capacity planning and trend review; Grafana presents real-time and historical views across electrical, cooling, environmental and fire-detection data.
Alerting
Grafana alert rules cover equipment faults, abnormal temperatures, UPS battery issues, generator alarms, cooling failure, communication loss and threshold breaches.

CI/CD

Source of truth
the Compose definition and the Node-RED flows are held in GitLab, so a flow is reviewed and versioned rather than edited inside the running instance.
Deploy
Node-RED, InfluxDB and Grafana run together as a Portainer stack on a virtual machine, and every update to the repository triggers Portainer to redeploy it, so what runs in the data centre is what was last merged.
Why it matters here
a flow edited live in the runtime is a change nobody reviewed and nobody can restore. Releasing from source control makes a change to facility monitoring as auditable as a change to anything else.
Protocols
  • Modbus TCP/IP
  • PROFINET
  • MQTT
  • SNMP
Collection
  • Node-RED
  • REST APIs
Storage & dashboards
  • InfluxDB
  • Grafana
Delivery
  • Docker Compose
  • Portainer
  • GitLab CI

Tenant Power & Energy Monitoring Platform

Racks with a PDU load and accumulated energy over SNMP Racks without one Accuenergy current transformers on each phase meters read over Modbus TCP/IP Nautobot job Python collectors · SNMP + Modbus TCP/IP scheduled · every run and its result retained GitLab reviewed · versioned Nautobot source of truth tenants · racks · owners synced in as a job which rack is whose InfluxDB points tagged by rack and tenant Grafana current load · consumption · trends per tenant or rack per-phase readings expose an unbalanced circuit Monthly billing report accumulated energy per tenant for the period traceable to the run that produced it

Solution

Hybrid metering
PDU-equipped racks are read over SNMP and the remainder fall back to Accuenergy meters, covering whole-facility consumption without requiring uniform hardware.
Electrical measurements
Python collectors retrieve active, apparent and reactive power, power factor, per-phase current and accumulated energy over Modbus TCP/IP and SNMP.
Scheduled automation
collection runs as a Nautobot job on a schedule, replacing manual meter readings with a repeatable workflow.
Monthly billing report
accumulated readings and historical series are combined into per-tenant energy consumption for the billing period, mapped to the correct Nautobot tenant and rack so billing is auditable.
Dashboards
Grafana shows current load, phase balance, consumption and trends per tenant or rack over configurable periods.
Phase monitoring
per-phase readings expose unbalanced loads, overloaded circuits and changes in equipment behaviour.

Hardware stack

Current transformers
Accuenergy coils measuring current on each phase in racks with no PDU.
Energy meters
Accuenergy meters exposing power and accumulated energy over Modbus TCP/IP.
Power distribution units
rack PDUs reporting load and accumulated consumption over SNMP.

CI/CD

Jobs from source control
the collection and reporting logic lives in GitLab and is synchronised into Nautobot as a job, so the code that reads the meters is reviewed and versioned rather than pasted into the platform.
Scheduled execution
Nautobot runs the job on its schedule and retains the result, so a billing figure can be traced back to the run that produced it.
Containerised delivery
the supporting services ship as Docker images, so the environment the collectors run in is rebuilt rather than maintained by hand.
Source of truth
  • Nautobot
Collection
  • Python
  • Modbus TCP/IP
  • SNMP
  • REST APIs
Metering hardware
  • Accuenergy
  • PDU
Storage & dashboards
  • InfluxDB
  • Grafana
Delivery
  • Docker
  • GitLab

Redfish Server Telemetry

Board sensors · I²C CPU · PECI PSU · PMBus Drives · DIMMs Baseboard management controller Redfish REST API · out of band Thermal Power Health Python collector · cron on a VM GitLab CI COMPANY CLOUD InfluxDB Grafana Alert rules · Grafana Alertmanager

Solution

Out-of-band collection
a Python collector, run by cron on a VM, polls the Redfish REST API on each server's management controller on a schedule, so telemetry keeps arriving whether the operating system is up, busy or down.
Where the readings come from
the management controller reads the platform's own sensors directly: board and inlet temperatures and fan tachometers over I²C and SMBus, core temperatures over PECI, wattage and power supply state over PMBus, and drive and memory health from the devices themselves. Redfish is the REST face of that, so the API is enriched by the controller rather than by anything running in the operating system.
Thermal readings
inlet, outlet, CPU and board temperatures with their manufacturer thresholds, plus fan state, giving the immersion system's cooling performance measured at the load it is actually cooling.
Power readings
consumed watts, power supply state and redundancy, and the electrical draw of each server in the cluster.
Health state
chassis, processor, memory, storage and power subsystem status rolled up per server, so a degraded component is visible before it becomes an outage.
Normalisation
the Redfish JSON resources are flattened into structured time-series points tagged by server, chassis and sensor, so hardware from different vendors lands in one consistent schema.
Storage and dashboards
readings are written to the company's cloud InfluxDB and presented in its cloud Grafana, where per-server temperature and power are read against the immersion system's own telemetry over the same period.
Alerting
the rules are Grafana-managed and fire through its built-in Alertmanager, covering temperature thresholds, power supply faults, degraded health state and collection loss.

CI/CD

Build
the collector is built and published as a versioned Docker image from its GitLab repository.
Deploy
the VM's cron job runs that pinned image rather than a script on a host, so the collector polling a cluster is the one that was built, and rolling back means naming an earlier version.
Collection
  • Redfish
  • Python
  • REST APIs
Storage & dashboards
  • InfluxDB
  • Grafana
Delivery
  • Docker
  • GitLab

Blockchain Health Records Platform

Solution

Capture
the patient takes a reading and the board sends heart rate, blood oxygen and skin temperature to the phone over Bluetooth.
Publish
the app builds a health report, uploads it to IPFS and writes the returned content identifier to the contract.
Authorise
the patient grants or revokes a doctor's address on-chain; nothing else can reach the report.
Retrieve
the doctor's app calls the contract and pulls the report from IPFS while authorised.

Software stack

Firmware
C on the Arduino, beat detection reporting instantaneous and average BPM.
Mobile clients
Java on Android, AndroidX and Material Design, one app for patients and one for doctors.
Smart contract
Solidity, AccessControl exposing storeData, giveAccess, revokeAccess and retrieveData.
On-device store
MongoDB Realm, readings tagged by state and searchable by date or value.
Cloud and auth
Firebase for authentication and non-sensitive data.
Chain access
web3j from Android, web3.js for direct calls.

Hardware stack

Board
a custom PCB of my own design and wiring.
Microcontroller
Arduino Uno.
Pulse oximeter
MAX30102 over I²C, heart rate and SpO₂ from red against infrared absorption.
Thermometer
MLX90614, non-contact infrared skin temperature, over I²C.
Radio
HC-05 module, Bluetooth serial to the phone.

Networks & testing

Local chain
Ganache, a personal Ethereum node to develop against.
Contract IDE
Remix, for writing and deploying AccessControl.
Testnet
Rinkeby, chosen for its Proof of Authority consensus and the fast confirmations that follow.
Alternatives
Ropsten, Kovan and Goerli, the other public testnets at the time.
Node access
Infura, one endpoint for both Ethereum and IPFS, with MetaMask as the wallet.
Blockchain
  • Ethereum
  • Solidity
  • Smart Contracts
  • Web3j
  • Web3.js
Storage
  • IPFS
  • MongoDB
  • Firebase
Client
  • Android
  • Java
Device
  • Arduino
  • C
  • Bluetooth

Signal Analysis for Parkinson's Disease Symptoms

CAPTURE Custom PCB wearable 9-axis IMU — accelerometer, gyroscope, magnetometer guided patient tests and daily life Android app records the session, returns the result the shipped algorithm is a class inside it PIPELINE Calibration noise cut from the signal device-to-device check Time series motion held as recordings Fourier analysis time domain to frequency the features come from here Classifiers decision trees, trained on the captured recordings Symptom scores tremor · bradykinesia · dyskinesia dysmobility · finger tapping Cloud platform the result is pushed up VALIDATION Clinical check real patient recordings and clinical observation Video check OpenCV and ML over video, compared with the sensors Correlation sensor data × results × patient test outcomes

Solution

Wearable sensing
custom boards with a 9-axis IMU, monitoring body movement, hand motion, orientation and balance.
Calibration
recordings analysed to cut noise and check consistency between devices before any symptom analysis ran.
Time-series
motion handled as time-series recordings.
Frequency domain
Fourier analysis for migration from time domain to frequency domain in order to classify the symptoms.
Model training
the captured recordings trained the classifiers: Fourier features taken from the signals, fed into decision trees and other classical classifiers, to decide which symptom each recording shows.
Test workflow
the patient completes a guided test on the custom device, data reaches the Android app, and the algorithm returns a result.
Deployment
the final algorithm ships inside the Android app.
Movement assessments
tremor, bradykinesia, dyskinesia, dysmobility and finger tapping, each scored from the same recordings.
Clinical check
algorithm output validated against real patient recordings and clinical observations.
Correlation
correlation analysis across sensor data, algorithm results and patient test outcomes.
Video check
computer vision and machine learning over images and video, compared with the sensor readings.

Software stack

Analysis
MATLAB and Python with NumPy and SciPy.
Vision and ML
OpenCV and scikit-learn.
Visualisation
Python and MATLAB tooling for data review.
Android app
Java for implementing the algorithm as a class inside the android app.

Hardware stack

IMU
accelerometer, gyroscope, magnetometer.
Analysis
  • MATLAB
  • NumPy
  • SciPy
  • Fourier Analysis
Vision & learning
  • OpenCV
  • scikit-learn
Implementation
  • C
  • Python
  • Java

Technologies

Every tile above "also familiar" links to the project that uses it.