# Temperature gauge

Bimetal dial thermometer with an every-angle (hinged, back-connected) stainless case on a one-piece flanged thermowell with lagging extension and union. Origin and port on the thermowell flange face (pointing down).

**Standards:** EN 13190, ASME B40.200, ASME PTC 19.3 TW, ASME B16.5

## Installation

```bash
npx -y https://decktwin.com/cli/deck-twin-0.2.2.tgz add temperature-gauge
```

Copies `instruments/temperature-gauge.tsx`, any helper files it imports and the shared `lib/` into `src/components/deck-twin/`. Needs `three`, `@react-three/fiber` and `@react-three/drei`.

## Usage

```tsx
import { Canvas } from '@react-three/fiber'
import { OrbitControls } from '@react-three/drei'
import { Stage } from './components/deck-twin/lib/stage'
import { TemperatureGauge } from './components/deck-twin/instruments/temperature-gauge'

export default function Scene() {
  return (
    <Canvas shadows camera={{ position: [8, 5, 9], fov: 35 }}>
      <Stage>
        <TemperatureGauge />
      </Stage>
      <OrbitControls makeDefault />
    </Canvas>
  )
}
```

## Props

| Prop | Type | Default | Range |
| --- | --- | --- | --- |
| `nps` | `number (NPS, in)` | `1.5` |  |
| `rating` | `150 \| 300 \| 600 \| 900 \| 1500 \| 2500` | `600` |  |
| `insertion` | `number (m)` | `0.25` | 0.1 – 0.6 |
| `extension` | `number (m)` | `0.08` | 0.05 – 0.3 |
| `dial` | `0.1 \| 0.125 \| 0.15` | `0.125` |  |
| `max` | `100 \| 150 \| 200 \| 300 \| 400` | `200` |  |
| `tag` | `string` | `"TI-1101"` |  |
| `...group` | position, rotation, scale… |  |  |

## Ports

Flange faces in the component's local frame, metres. Origin: pipe centreline, flow along X.

| Id | Label | Position | Direction | Size | Class |
| --- | --- | --- | --- | --- | --- |
| `process` | Thermowell flange | 0.000, 0.000, 0.000 | 0, -1, 0 | 1-1/2" | 600 |

## P&ID

Field bubble marked TI (or TG) on a thermowell pocket in the pipe; no signal line.

tag TG · ISA TI · ISA TG · ISA TW · ISA 5.1 (field-mounted instrument bubble)

Same as the temperature transmitter but with TI / TG. A test thermowell with no instrument is a TW bubble alone.

Bimetal thermometer + thermowell specification forms (ISA-TR20.00.01; ASME B40.200) fields and the props they set:

| Field | Prop |
| --- | --- |
| Thermowell flange size | `nps` |
| Flange rating | `rating` |
| Insertion length (U) | `insertion` |
| Lagging extension (T) | `extension` |
| Dial size | `dial` |
| Range (max) | `max` |
| Tag number | `tag` |

## Typical suppliers

WIKA. The geometry is generic and sized from public standards. It is not vendor CAD.

## Source

`instruments/temperature-gauge.tsx`. This is the component file only: it imports shared code, so install it with the command above rather than pasting it alone. https://decktwin.com/r/temperature-gauge.json has every file.

```tsx
// Bimetal dial thermometer: every-angle stainless case on a hinged stem in a flanged thermowell. EN 13190 / ASME B40.200, ASME PTC 19.3 TW, ASME B16.5.
import { KitMesh, useKit, type GroupProps } from '../lib/mesh'
import { gauge } from '../lib/parts'
import { port, type Port } from '../lib/ports'
import type { Rating } from '../lib/standards'
import { SS, flangedThermowell, tag as tagPlate } from './_parts'

export interface TemperatureGaugeProps {
  /** thermowell flange size, inches */
  nps?: number
  rating?: Rating
  /** immersion length below the flange face, m */
  insertion?: number
  /** lagging extension, m */
  extension?: number
  /** dial size, m */
  dial?: number
  /** full-scale, °C */
  max?: number
  tag?: string
}

export const defaults = { nps: 1.5, rating: 600 as Rating, insertion: 0.25, extension: 0.08, dial: 0.125, max: 200, tag: 'TI-1101' }

export function ports(p: TemperatureGaugeProps = {}): Port[] {
  const { nps, rating } = { ...defaults, ...p }
  return [port('process', 'Thermowell flange', [0, 0, 0], [0, -1, 0], nps, rating)]
}

export function TemperatureGauge({ nps = defaults.nps, rating = defaults.rating, insertion = defaults.insertion, extension = defaults.extension, dial = defaults.dial, max = defaults.max, tag = defaults.tag, ...group }: TemperatureGaugeProps & GroupProps) {
  const data = useKit(
    (k) => {
      const y = flangedThermowell(k, nps, rating, insertion, extension)
      // stem, swivel knuckle and back-connected case
      k.cyl(SS, 0.0045, 0.05, [0, y + 0.025, 0], 'y', 10)
      const yk = y + 0.055
      k.sphere(SS, 0.011, [0, yk, 0], undefined, 14)
      k.cyl(SS, 0.009, 0.026, [0, yk, 0], 'x', 12)
      const depth = dial * 0.32
      const yc = yk + dial * 0.55
      const zc = depth / 2 + 0.014
      k.rod(SS, [0, yk, 0], [0, yc, 0], 0.006, 10)
      k.cyl(SS, 0.013, 0.014, [0, yc, 0.007], 'z', 14)
      gauge(k, [0, yc, zc], 'z', dial, '°C', max)
      tagPlate(k, tag, [0, y - 0.038 - extension / 2, 0.0115], 'z', 0.06)
    },
    [nps, rating, insertion, extension, dial, max, tag],
  )
  return (
    <group {...group}>
      <KitMesh data={data} />
    </group>
  )
}

export default TemperatureGauge
```
