DynDaCo

I build production systems in Ruby on Rails and .NET.

Twenty-eight years of it, mostly for manufacturers and operators, and from the PLC and the robot up to the browser — getting data off machines and onto screens, joining systems that were never meant to talk, and replacing the Access databases that quietly run a department.

Ruby on Rails

The applications people work in all day: registers, tracking, scheduling, reporting. Long-lived systems that keep changing for years — and the new home for whatever the business is running on now.

.NET

The part that talks to equipment. Reading PLCs, trackers and instruments over their own protocols, on machines that keep working when the network doesn't, and handing clean data to the systems above.

How far down it goes

"Full stack" usually means the browser and the server. In a plant it has to mean more than that. I've worked at every one of these layers, which is mostly useful because it means I know what the layer below is actually able to give me.

  1. Interface The screens people use — Hotwire, Vue, and operator terminals on the floor
  2. Application Rails and ASP.NET Core — registers, tracking, scheduling, reporting
  3. Edge services Software on plant machines that keeps working when the network doesn't
  4. Protocols Siemens S7, Modbus TCP, OPC UA, AIS and a good number of proprietary binary formats
  5. Automation Siemens PLC programs and Fanuc robot programs — the equipment itself
  6. Connected devices Electronics in the field reporting home, including EV charging equipment

Legacy modernisation

An Access database that runs a department. A mod_perl application nobody dares deploy. A VB6 tool one person maintains. It still works, which is exactly why replacing it is hard — there's no crisis to justify downtime and no tolerance for losing anything.

I move these onto Rails without a shutdown weekend. The method is always the same, and the order matters.

  1. 01

    Read what's actually there

    Not the documentation — the data. Old systems accumulate rules that live nowhere but in the records themselves: the status code that means something different after 2009, the field reused for a second purpose. I read the real database before proposing anything.

  2. 02

    Build the import so it can run again

    A one-off conversion script gets you one attempt. A repeatable import lets you re-run against live data as often as you like, so every assumption is tested against reality months before cutover. This single decision removes most of the risk.

  3. 03

    Keep people's habits

    Existing URLs keep working. Passwords migrate silently on first login rather than forcing a reset. Vocabulary stays whatever your people already call things. A migration users have to be trained through is a migration that gets resisted.

  4. 04

    Cut over on an ordinary day

    By the time it happens the import has run dozens of times and the new system has been checked against the old one on real records. Cutover should be a rehearsed, boring operation — and reversible if it isn't.

Selected work

All work

Keg tracking and line analysis for a brewery group

Kegs tracked through filling and washing, line stoppages explained to the minute, and data pipelines an engineer configures in a browser instead of commissioning.

  • ASP.NET Core 10
  • Akka.NET
  • Vue 3
  • TimescaleDB
  • InfluxDB
  • Ruby on Rails
  • Grafana

Wheel alignment and headlight aiming at end of line

Every vehicle coming off the line gets its wheel geometry and headlight aim measured and adjusted to spec, with operators guided by live readings as they turn the adjusters.

  • C++
  • Siemens PLC
  • Machine vision
  • Sensor acquisition
  • ASAM
  • Linux

Vessel tracking that knows what the ship is doing

One map of a mixed fleet, showing not just where each vessel is but what its onboard systems are reporting — fuel, machinery state, running hours — plus who is aboard.

  • Ruby on Rails
  • PostgreSQL
  • PostGIS
  • AIS
  • Binary TCP protocols

A membership system moved off Perl, without a big bang

Member records, board composition and a shared calendar for a three-tier federation — rebuilt off mod_perl, including a password migration no member ever noticed.

  • Ruby on Rails 8.1
  • PostgreSQL
  • Devise
  • Hotwire
  • Tailwind CSS