programmati.ca Open Studio

Gallery / Application

Wind Operations

Explore a fictional wind fleet, inspect turbine readings, compare production and manage maintenance work saved in this browser.

Try this workflow

  1. Filter Fleet by Attention and open Headland 03 to see its own temperature history and related maintenance.
  2. Open Production to compare hourly generated and available energy and sort the underlying readings.
  3. Open Maintenance, add a work order, move its status and edit its notes. Reload to verify persistence. All readings are fictional fixed fixtures; no equipment is connected.

Records stay in this browser. Reset demo data clears the saved records for this app.

The AppSPEC

Use this complete declarative specification in Studio. The runner supplies the site navigation and sandbox; the specification defines the workflow.

View complete AppSPEC (77 lines)
<?xml version="1.0" encoding="UTF-8"?>
<APP ID="wind-operations" NAME="Wind Operations" THEME="modern-minimal" WIDTH="1240px">
  <DATA MODE="local">
    <COLLECTION ID="wind_turbines">[{"id":"T01","name":"Headland 01","status":"Generating","power_mw":2.16,"wind_mps":8.42,"bearing_c":41,"rated_mw":3.6,"commissioned":"2021","note":"Within demonstration reference range."},{"id":"T02","name":"Headland 02","status":"Generating","power_mw":2.27,"wind_mps":8.64,"bearing_c":43,"rated_mw":3.6,"commissioned":"2021","note":"Within demonstration reference range."},{"id":"T03","name":"Headland 03","status":"Attention","power_mw":2.38,"wind_mps":8.86,"bearing_c":78,"rated_mw":3.6,"commissioned":"2021","note":"Bearing temperature elevated. Inspect the seeded work order."},{"id":"T04","name":"Headland 04","status":"Generating","power_mw":2.49,"wind_mps":9.08,"bearing_c":47,"rated_mw":3.6,"commissioned":"2021","note":"Within demonstration reference range."},{"id":"T05","name":"Headland 05","status":"Generating","power_mw":2.6,"wind_mps":9.3,"bearing_c":49,"rated_mw":3.6,"commissioned":"2021","note":"Within demonstration reference range."},{"id":"T06","name":"Headland 06","status":"Generating","power_mw":2.71,"wind_mps":9.52,"bearing_c":51,"rated_mw":3.6,"commissioned":"2021","note":"Within demonstration reference range."},{"id":"T07","name":"Headland 07","status":"Service","power_mw":0,"wind_mps":9.74,"bearing_c":53,"rated_mw":3.6,"commissioned":"2021","note":"Scheduled service in the fictional snapshot."},{"id":"T08","name":"Headland 08","status":"Generating","power_mw":2.93,"wind_mps":9.96,"bearing_c":55,"rated_mw":3.6,"commissioned":"2021","note":"Within demonstration reference range."}]</COLLECTION>
    <COLLECTION ID="wind_readings">[{"id":"T01-6","turbine_id":"T01","hour":"06:00","bearing_c":39.4,"power_mw":1.57},{"id":"T01-7","turbine_id":"T01","hour":"07:00","bearing_c":39.5,"power_mw":1.62},{"id":"T01-8","turbine_id":"T01","hour":"08:00","bearing_c":39.6,"power_mw":1.67},{"id":"T01-9","turbine_id":"T01","hour":"09:00","bearing_c":39.8,"power_mw":1.73},{"id":"T01-10","turbine_id":"T01","hour":"10:00","bearing_c":40.0,"power_mw":1.78},{"id":"T01-11","turbine_id":"T01","hour":"11:00","bearing_c":40.1,"power_mw":1.84},{"id":"T01-12","turbine_id":"T01","hour":"12:00","bearing_c":40.2,"power_mw":1.89},{"id":"T01-13","turbine_id":"T01","hour":"13:00","bearing_c":40.4,"power_mw":1.94},{"id":"T01-14","turbine_id":"T01","hour":"14:00","bearing_c":40.5,"power_mw":2.0},{"id":"T01-15","turbine_id":"T01","hour":"15:00","bearing_c":40.7,"power_mw":2.05},{"id":"T01-16","turbine_id":"T01","hour":"16:00","bearing_c":40.9,"power_mw":2.11},{"id":"T01-17","turbine_id":"T01","hour":"17:00","bearing_c":41.0,"power_mw":2.16},{"id":"T02-6","turbine_id":"T02","hour":"06:00","bearing_c":41.4,"power_mw":1.65},{"id":"T02-7","turbine_id":"T02","hour":"07:00","bearing_c":41.5,"power_mw":1.7},{"id":"T02-8","turbine_id":"T02","hour":"08:00","bearing_c":41.6,"power_mw":1.76},{"id":"T02-9","turbine_id":"T02","hour":"09:00","bearing_c":41.8,"power_mw":1.82},{"id":"T02-10","turbine_id":"T02","hour":"10:00","bearing_c":42.0,"power_mw":1.87},{"id":"T02-11","turbine_id":"T02","hour":"11:00","bearing_c":42.1,"power_mw":1.93},{"id":"T02-12","turbine_id":"T02","hour":"12:00","bearing_c":42.2,"power_mw":1.99},{"id":"T02-13","turbine_id":"T02","hour":"13:00","bearing_c":42.4,"power_mw":2.04},{"id":"T02-14","turbine_id":"T02","hour":"14:00","bearing_c":42.5,"power_mw":2.1},{"id":"T02-15","turbine_id":"T02","hour":"15:00","bearing_c":42.7,"power_mw":2.16},{"id":"T02-16","turbine_id":"T02","hour":"16:00","bearing_c":42.9,"power_mw":2.21},{"id":"T02-17","turbine_id":"T02","hour":"17:00","bearing_c":43.0,"power_mw":2.27},{"id":"T03-6","turbine_id":"T03","hour":"06:00","bearing_c":47.8,"power_mw":1.73},{"id":"T03-7","turbine_id":"T03","hour":"07:00","bearing_c":50.5,"power_mw":1.78},{"id":"T03-8","turbine_id":"T03","hour":"08:00","bearing_c":53.2,"power_mw":1.84},{"id":"T03-9","turbine_id":"T03","hour":"09:00","bearing_c":56.0,"power_mw":1.9},{"id":"T03-10","turbine_id":"T03","hour":"10:00","bearing_c":58.8,"power_mw":1.96},{"id":"T03-11","turbine_id":"T03","hour":"11:00","bearing_c":61.5,"power_mw":2.02},{"id":"T03-12","turbine_id":"T03","hour":"12:00","bearing_c":64.2,"power_mw":2.08},{"id":"T03-13","turbine_id":"T03","hour":"13:00","bearing_c":67.0,"power_mw":2.14},{"id":"T03-14","turbine_id":"T03","hour":"14:00","bearing_c":69.8,"power_mw":2.2},{"id":"T03-15","turbine_id":"T03","hour":"15:00","bearing_c":72.5,"power_mw":2.26},{"id":"T03-16","turbine_id":"T03","hour":"16:00","bearing_c":75.2,"power_mw":2.32},{"id":"T03-17","turbine_id":"T03","hour":"17:00","bearing_c":78.0,"power_mw":2.38},{"id":"T04-6","turbine_id":"T04","hour":"06:00","bearing_c":45.4,"power_mw":1.81},{"id":"T04-7","turbine_id":"T04","hour":"07:00","bearing_c":45.5,"power_mw":1.87},{"id":"T04-8","turbine_id":"T04","hour":"08:00","bearing_c":45.6,"power_mw":1.93},{"id":"T04-9","turbine_id":"T04","hour":"09:00","bearing_c":45.8,"power_mw":1.99},{"id":"T04-10","turbine_id":"T04","hour":"10:00","bearing_c":46.0,"power_mw":2.05},{"id":"T04-11","turbine_id":"T04","hour":"11:00","bearing_c":46.1,"power_mw":2.12},{"id":"T04-12","turbine_id":"T04","hour":"12:00","bearing_c":46.2,"power_mw":2.18},{"id":"T04-13","turbine_id":"T04","hour":"13:00","bearing_c":46.4,"power_mw":2.24},{"id":"T04-14","turbine_id":"T04","hour":"14:00","bearing_c":46.5,"power_mw":2.3},{"id":"T04-15","turbine_id":"T04","hour":"15:00","bearing_c":46.7,"power_mw":2.37},{"id":"T04-16","turbine_id":"T04","hour":"16:00","bearing_c":46.9,"power_mw":2.43},{"id":"T04-17","turbine_id":"T04","hour":"17:00","bearing_c":47.0,"power_mw":2.49},{"id":"T05-6","turbine_id":"T05","hour":"06:00","bearing_c":47.4,"power_mw":1.89},{"id":"T05-7","turbine_id":"T05","hour":"07:00","bearing_c":47.5,"power_mw":1.95},{"id":"T05-8","turbine_id":"T05","hour":"08:00","bearing_c":47.6,"power_mw":2.02},{"id":"T05-9","turbine_id":"T05","hour":"09:00","bearing_c":47.8,"power_mw":2.08},{"id":"T05-10","turbine_id":"T05","hour":"10:00","bearing_c":48.0,"power_mw":2.15},{"id":"T05-11","turbine_id":"T05","hour":"11:00","bearing_c":48.1,"power_mw":2.21},{"id":"T05-12","turbine_id":"T05","hour":"12:00","bearing_c":48.2,"power_mw":2.27},{"id":"T05-13","turbine_id":"T05","hour":"13:00","bearing_c":48.4,"power_mw":2.34},{"id":"T05-14","turbine_id":"T05","hour":"14:00","bearing_c":48.5,"power_mw":2.41},{"id":"T05-15","turbine_id":"T05","hour":"15:00","bearing_c":48.7,"power_mw":2.47},{"id":"T05-16","turbine_id":"T05","hour":"16:00","bearing_c":48.9,"power_mw":2.54},{"id":"T05-17","turbine_id":"T05","hour":"17:00","bearing_c":49.0,"power_mw":2.6},{"id":"T06-6","turbine_id":"T06","hour":"06:00","bearing_c":49.4,"power_mw":1.96},{"id":"T06-7","turbine_id":"T06","hour":"07:00","bearing_c":49.5,"power_mw":2.03},{"id":"T06-8","turbine_id":"T06","hour":"08:00","bearing_c":49.6,"power_mw":2.1},{"id":"T06-9","turbine_id":"T06","hour":"09:00","bearing_c":49.8,"power_mw":2.17},{"id":"T06-10","turbine_id":"T06","hour":"10:00","bearing_c":50.0,"power_mw":2.24},{"id":"T06-11","turbine_id":"T06","hour":"11:00","bearing_c":50.1,"power_mw":2.3},{"id":"T06-12","turbine_id":"T06","hour":"12:00","bearing_c":50.2,"power_mw":2.37},{"id":"T06-13","turbine_id":"T06","hour":"13:00","bearing_c":50.4,"power_mw":2.44},{"id":"T06-14","turbine_id":"T06","hour":"14:00","bearing_c":50.5,"power_mw":2.51},{"id":"T06-15","turbine_id":"T06","hour":"15:00","bearing_c":50.7,"power_mw":2.57},{"id":"T06-16","turbine_id":"T06","hour":"16:00","bearing_c":50.9,"power_mw":2.64},{"id":"T06-17","turbine_id":"T06","hour":"17:00","bearing_c":51.0,"power_mw":2.71},{"id":"T07-6","turbine_id":"T07","hour":"06:00","bearing_c":51.4,"power_mw":0},{"id":"T07-7","turbine_id":"T07","hour":"07:00","bearing_c":51.5,"power_mw":0},{"id":"T07-8","turbine_id":"T07","hour":"08:00","bearing_c":51.6,"power_mw":0},{"id":"T07-9","turbine_id":"T07","hour":"09:00","bearing_c":51.8,"power_mw":0},{"id":"T07-10","turbine_id":"T07","hour":"10:00","bearing_c":52.0,"power_mw":0},{"id":"T07-11","turbine_id":"T07","hour":"11:00","bearing_c":52.1,"power_mw":0},{"id":"T07-12","turbine_id":"T07","hour":"12:00","bearing_c":52.2,"power_mw":0},{"id":"T07-13","turbine_id":"T07","hour":"13:00","bearing_c":52.4,"power_mw":0},{"id":"T07-14","turbine_id":"T07","hour":"14:00","bearing_c":52.5,"power_mw":0},{"id":"T07-15","turbine_id":"T07","hour":"15:00","bearing_c":52.7,"power_mw":0},{"id":"T07-16","turbine_id":"T07","hour":"16:00","bearing_c":52.9,"power_mw":0},{"id":"T07-17","turbine_id":"T07","hour":"17:00","bearing_c":53.0,"power_mw":0},{"id":"T08-6","turbine_id":"T08","hour":"06:00","bearing_c":53.4,"power_mw":2.12},{"id":"T08-7","turbine_id":"T08","hour":"07:00","bearing_c":53.5,"power_mw":2.2},{"id":"T08-8","turbine_id":"T08","hour":"08:00","bearing_c":53.6,"power_mw":2.27},{"id":"T08-9","turbine_id":"T08","hour":"09:00","bearing_c":53.8,"power_mw":2.34},{"id":"T08-10","turbine_id":"T08","hour":"10:00","bearing_c":54.0,"power_mw":2.42},{"id":"T08-11","turbine_id":"T08","hour":"11:00","bearing_c":54.1,"power_mw":2.49},{"id":"T08-12","turbine_id":"T08","hour":"12:00","bearing_c":54.2,"power_mw":2.56},{"id":"T08-13","turbine_id":"T08","hour":"13:00","bearing_c":54.4,"power_mw":2.64},{"id":"T08-14","turbine_id":"T08","hour":"14:00","bearing_c":54.5,"power_mw":2.71},{"id":"T08-15","turbine_id":"T08","hour":"15:00","bearing_c":54.7,"power_mw":2.78},{"id":"T08-16","turbine_id":"T08","hour":"16:00","bearing_c":54.9,"power_mw":2.86},{"id":"T08-17","turbine_id":"T08","hour":"17:00","bearing_c":55.0,"power_mw":2.93}]</COLLECTION>
    <COLLECTION ID="wind_production">[{"id":"P6","hour":"06:00","generated_mwh":12.73,"available_mwh":15.43},{"id":"P7","hour":"07:00","generated_mwh":13.15,"available_mwh":15.85},{"id":"P8","hour":"08:00","generated_mwh":13.59,"available_mwh":16.29},{"id":"P9","hour":"09:00","generated_mwh":14.03,"available_mwh":16.73},{"id":"P10","hour":"10:00","generated_mwh":14.47,"available_mwh":17.17},{"id":"P11","hour":"11:00","generated_mwh":14.91,"available_mwh":17.61},{"id":"P12","hour":"12:00","generated_mwh":15.34,"available_mwh":18.04},{"id":"P13","hour":"13:00","generated_mwh":15.78,"available_mwh":18.48},{"id":"P14","hour":"14:00","generated_mwh":16.23,"available_mwh":18.93},{"id":"P15","hour":"15:00","generated_mwh":16.66,"available_mwh":19.36},{"id":"P16","hour":"16:00","generated_mwh":17.11,"available_mwh":19.81},{"id":"P17","hour":"17:00","generated_mwh":17.54,"available_mwh":20.24}]</COLLECTION>
    <COLLECTION ID="wind_orders">[{"id":"WO-103","title":"Inspect bearing temperature","turbine_id":"T03","status":"planned","priority":"High","owner":"Service crew A","notes":"Compare the rising trend before planning an inspection. Fictional demonstration only."},{"id":"WO-107","title":"Complete scheduled service","turbine_id":"T07","status":"active","priority":"Normal","owner":"Service crew B","notes":"Return the fictional service record for review when complete."},{"id":"WO-101","title":"Review blade inspection notes","turbine_id":"T01","status":"done","priority":"Normal","owner":"Service crew A","notes":"Demonstration task already completed."}]</COLLECTION>
    <COLLECTION ID="wind_kpis">[{"label":"Snapshot output","value":17.54,"unit":"MW"},{"label":"Installed capacity","value":28.8,"unit":"MW"},{"label":"Turbines generating","value":7,"unit":"of 8"},{"label":"Needs inspection","value":1,"unit":"turbine"}]</COLLECTION>
  </DATA>
  <STATE ID="fleet" NAV="Fleet" ICON="wind">
    <TEXT STYLE="h1" TEXT="Headland wind fleet" />
    <TEXT STYLE="eyebrow" TEXT="Fictional coastal farm · fixed demonstration snapshot · work orders saved in this browser" />
    <PICTURE SRC="/media/wind-operations.png" HEIGHT="240px" FIT="cover" MODE="full" CAPTION="Headland: an illustrated fictional fleet, not a real monitored facility." />
    <KPI SRC="wind_kpis" COLS="4" />
    <TEXT STYLE="h2" TEXT="Inspect the fleet" />
    <TEXT STYLE="muted" TEXT="Filter a status or sort a column. Open a turbine to inspect its own readings and maintenance work." />
    <CATEGORY-NAV ID="fleet_status" SRC="wind_turbines" FIELD="status" ALL="All turbines" />
    <TABLE SRC="wind_turbines" OPEN="turbine" WHERE="status={fleet_status}" EMPTY="No turbines match this status.">
      <COL FIELD="name" LABEL="Turbine" />
      <COL FIELD="status" LABEL="Status" />
      <COL FIELD="power_mw" LABEL="Output (MW)" />
      <COL FIELD="wind_mps" LABEL="Wind (m/s)" />
      <COL FIELD="bearing_c" LABEL="Bearing (°C)" />
    </TABLE>
  </STATE>
  <STATE ID="turbine">
    <DETAIL SRC="wind_turbines" TITLE="name" FIELDS="status,power_mw,wind_mps,bearing_c,rated_mw,note" EMPTY="Choose a turbine from Fleet." />
    <GRID COLS="2" MIN="280px">
      <CHART SRC="wind_readings" WHERE="turbine_id={record.id}" X="hour" Y="bearing_c" TYPE="line" TITLE="Bearing temperature" UNIT="°C" HEIGHT="230px" />
      <CHART SRC="wind_readings" WHERE="turbine_id={record.id}" X="hour" Y="power_mw" TYPE="area" TITLE="Turbine output" UNIT="MW" HEIGHT="230px" />
    </GRID>
    <TEXT STYLE="h2" TEXT="Related maintenance" />
    <TABLE SRC="wind_orders" WHERE="turbine_id={record.id}" OPEN="order" EMPTY="No maintenance work for this turbine.">
      <COL FIELD="title" LABEL="Work order" />
      <COL FIELD="status" LABEL="Status" />
      <COL FIELD="priority" LABEL="Priority" />
    </TABLE>
    <BUTTON LABEL="Back to fleet" ACTION="fleet" STYLE="secondary" />
  </STATE>
  <STATE ID="production" NAV="Production" ICON="chart-column">
    <TEXT STYLE="h1" TEXT="Production and headroom" />
    <TEXT STYLE="muted" TEXT="Twelve fictional hourly intervals. Each generated-energy value equals the sum of the eight turbine readings for that one-hour interval. Available energy is an illustrative comparison, not a forecast." />
    <CHART SRC="wind_production" TYPE="bar" X="hour" Y="generated_mwh,available_mwh" NAMES="Generated,Available" UNIT="MWh" TITLE="Hourly energy comparison" HEIGHT="300px" />
    <TABLE SRC="wind_production">
      <COL FIELD="hour" LABEL="Hour" />
      <COL FIELD="generated_mwh" LABEL="Generated (MWh)" />
      <COL FIELD="available_mwh" LABEL="Available (MWh)" />
    </TABLE>
  </STATE>
  <STATE ID="maintenance" NAV="Maintenance" ICON="wrench">
    <TEXT STYLE="h1" TEXT="Maintenance planning" />
    <TEXT STYLE="muted" TEXT="Open a work order to edit its assignment and status. Drag between columns to change status. This updates the local work-order collection, never real equipment." />
    <TOTAL SRC="wind_orders" WHERE="status!=done" OP="count" LABEL="Open work orders:" />
    <BOARD SRC="wind_orders" GROUP="status" COLUMNS="planned:Planned,active:In progress,done:Completed" TITLE="title" SUBTITLE="{turbine_id} · {owner}" BADGE="priority" OPEN="order" />
    <TEXT STYLE="h2" TEXT="Plan a work order" />
    <FORM SAVE="wind_orders" SET="status=planned" SUBMIT-LABEL="Add work order" COLS="2">
      <FIELD NAME="title" LABEL="Work order" TYPE="text" REQUIRED="true" />
      <FIELD NAME="turbine_id" LABEL="Turbine" TYPE="select" REQUIRED="true" OPTIONS="T01:Headland 01,T02:Headland 02,T03:Headland 03,T04:Headland 04,T05:Headland 05,T06:Headland 06,T07:Headland 07,T08:Headland 08" />
      <FIELD NAME="priority" LABEL="Priority" TYPE="select" REQUIRED="false" OPTIONS="Normal,High" />
      <FIELD NAME="owner" LABEL="Assigned crew" TYPE="text" REQUIRED="false" />
      <FIELD NAME="notes" LABEL="Work notes" TYPE="textarea" REQUIRED="false" />
    </FORM>
  </STATE>
  <STATE ID="order" WIDTH="820px">
    <TEXT STYLE="h1" TEXT="Work order" />
    <FORM UPDATE="wind_orders" TO="maintenance" SUBMIT-LABEL="Save work order" COLS="2">
      <FIELD NAME="title" LABEL="Work order" TYPE="text" REQUIRED="true" />
      <FIELD NAME="turbine_id" LABEL="Turbine" TYPE="select" REQUIRED="true" OPTIONS="T01:Headland 01,T02:Headland 02,T03:Headland 03,T04:Headland 04,T05:Headland 05,T06:Headland 06,T07:Headland 07,T08:Headland 08" />
      <FIELD NAME="priority" LABEL="Priority" TYPE="select" REQUIRED="false" OPTIONS="Normal,High" />
      <FIELD NAME="owner" LABEL="Assigned crew" TYPE="text" REQUIRED="false" />
      <FIELD NAME="notes" LABEL="Work notes" TYPE="textarea" REQUIRED="false" />
      <FIELD NAME="status" LABEL="Work status" OPTIONS="planned:Planned,active:In progress,done:Completed" />
    </FORM>
    <BUTTON LABEL="Delete work order" ACTION="remove-order" STYLE="danger" />
  </STATE>
  <WIRE LABEL="remove-order" DELETE="wind_orders" TO="maintenance" />
</APP>