resistor

package module
v1.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 29, 2026 License: MIT Imports: 7 Imported by: 0

README

resistor

CI Go Report Card Go Reference Latest Release

A Go library for working with fixed resistors. Decode and encode color band and SMD markings, snap values to IEC preferred series, and infer unknown properties from physical observations.

No UI dependencies. Import it as a library, or use the included CLI, TUI, and web app.

Contents


Library

go get github.com/sss7526/resistor
Color band decode and encode

Supports 4-band, 5-band, and 6-band resistors per IEC 60062:

bands := []resistor.Color{resistor.Green, resistor.Brown, resistor.Brown, resistor.Gold}
spec, err := resistor.DecodeBands(bands)
// spec.ResistanceOhms == 510, spec.TolerancePct == 5

spec := resistor.ResistorSpec{ResistanceOhms: 510, TolerancePct: 5}
bands, err := resistor.EncodeBands(spec)
// []Color{Green, Brown, Brown, Gold}

6-band resistors include a temperature coefficient in the sixth band.

SMD markings

Supports 3-digit, 4-digit, R-notation, and EIA-96 formats:

spec, err := resistor.DecodeSMD("472")   // 4700 ohms
spec, err := resistor.DecodeSMD("4R7")   // 4.7 ohms
spec, err := resistor.DecodeSMD("01C")   // EIA-96

marking, err := resistor.EncodeSMD(4700, resistor.SMDAuto)
// "472"
E-series value selection

Snap an arbitrary resistance to the nearest IEC 60063 preferred series value (E3 through E192):

v, err := resistor.NearestStandard(487, resistor.E24, resistor.RoundNearest) // 510
v, err := resistor.NearestStandard(487, resistor.E12, resistor.RoundUp)      // 560
Standard resistor selection

Returns the snapped value, color bands, and all defaults applied:

result, err := resistor.SelectStandardResistor(resistor.SelectionRequest{
    Resistance: 487,
    Series:     resistor.E24,
})
// result.SelectedResistance == 510
// result.Bands              == [Green, Brown, Brown, Gold]
// result.Assumptions        == ["Tolerance defaulted to +/-5%", ...]

Unspecified fields default to E24, 5% tolerance, and nearest rounding.

Physical inference

Estimate unknown properties from any combination of bands, SMD marking, body color, length, and package type:

result, err := resistor.InferResistor(resistor.ObservedResistor{
    Bands:     []resistor.Color{resistor.Brown, resistor.Black, resistor.Red, resistor.Gold},
    BodyColor: resistor.Blue,
    LengthMM:  6.3,
})
// result.Spec.ResistanceOhms == 1000
// result.Spec.PowerWatts     == 0.25         (inferred from length)
// result.Spec.Type           == "metal_film" (inferred from body color)
// result.Meta.Confidence     == 0.92
// result.Meta.Assumptions    == ["Blue body assumed metal film", ...]

Decoded facts always take precedence over heuristic estimates. Confidence is a value in [0.0, 1.0].

Engineering analysis

Accepts voltage or current (or both, checked for Ohm's Law consistency):

report, err := resistor.AnalyzeResistor(resistor.AnalysisInput{
    Spec:           resistor.ResistorSpec{ResistanceOhms: 100, PowerWatts: 0.25, TolerancePct: 5},
    AppliedVoltage: 10,
})
// report.Current                == 0.1 A
// report.PowerDissipation       == 0.1 W
// report.DeratedSafePower       == 0.125 W
// report.WorstCaseResistanceMin == 95 ohms
// report.WorstCaseResistanceMax == 105 ohms
// report.Warnings               == [{Caution, "Power dissipation exceeds 50% derated threshold"}]

CLI

go install github.com/sss7526/resistor/cmd/resistor-cli@latest

All commands accept --json for machine-readable output.

Select a standard value:

resistor-cli select 487
resistor-cli select 487 --series E12 --tol 1 --round up

Infer from physical observations:

resistor-cli infer --bands brown,black,red,gold
resistor-cli infer --bands brown,black,red,gold --body blue --length 6.3
resistor-cli infer --smd 472 --pkg 0603

Analyze under electrical conditions:

resistor-cli analyze --r 100 --v 10 --pwr 0.25 --tol 5
resistor-cli analyze --r 100 --i 0.1

Decode and encode SMD markings:

resistor-cli smd decode 472
resistor-cli smd decode 4R7
resistor-cli smd encode 4700

TUI

An interactive terminal interface for all operations.

go install github.com/sss7526/resistor/cmd/resistor-tui@latest

Navigate with arrow keys, confirm with Enter, return to menu with Escape, quit with q or Ctrl+C.


Web

The WASM module exposes all library operations as browser-callable JavaScript functions. The included server embeds the compiled WASM and all static assets into a single binary.

Build
make build-wasm           # standard Go WASM (~3.4 MB uncompressed)
make build-server         # server + standard WASM
make build-server-tinygo  # server + TinyGo WASM (~430 KB gzip, ~1.1 MB uncompressed)

TinyGo must be installed for the TinyGo targets. See tinygo.org/getting-started/install.

Install to GOPATH/bin:

make install-server
make install-server-tinygo
Run
./bin/resistor-server               # listens on :8080
./bin/resistor-server --addr :9000  # custom port
RESISTOR_ADDR=:9000 ./bin/resistor-server

The server sets strict security headers (CSP with per-request nonce, COEP, COOP, X-Frame-Options) and is designed to sit behind a TLS-terminating reverse proxy.

JavaScript API

All functions live on the resistor global and return {ok: true, value: ...} on success or {ok: false, error: "..."} on failure. Inputs are JSON strings.

Function Input Returns
decodeBands '["green","brown","brown","gold"]' ResistorSpec
encodeBands '{"resistanceOhms":510,"tolerancePct":5}' Color[]
decodeSMD "472" ResistorSpec
encodeSMD '{"resistance":4700,"mode":"auto"}' marking string
nearestStandard '{"value":487,"series":"E24","mode":"nearest"}' number
selectStandardResistor '{"resistance":487}' SelectionResult
inferResistor '{"bands":[...],"bodyColor":"blue","lengthMM":6.3}' InferenceResult
analyzeResistor '{"spec":{...},"appliedVoltage":10}' AnalysisReport

Deployment

The server binary is self-contained and designed to run behind Caddy (or any reverse proxy). Caddy handles TLS automatically via Let's Encrypt.

Docker
# Standard Go WASM
docker build -t resistor .
docker run --rm -p 8080:8080 resistor

# TinyGo WASM (~430 KB gzip)
docker build --build-arg WASM=tinygo -t resistor .

The final image is built on scratch and runs as UID 10001.

Docker Compose + Caddy

The included docker-compose.yml pulls sss7526/resistor:latest from Docker Hub and runs it behind Caddy. Set RESISTOR_HOST to your public domain and start:

RESISTOR_HOST=resistor.example.com docker compose up -d

Caddy provisions TLS automatically. For local testing (HTTP only, no cert needed):

docker compose up

Certificate data is persisted in the caddy_data named volume. Edit Caddyfile before starting Compose to add rate limiting, authentication, or other directives.

Watchtower runs as a sidecar and polls Docker Hub every 5 minutes. When a new :latest image is pushed it pulls and restarts the resistor container automatically. Caddy is intentionally excluded from Watchtower's watch scope.


Development

Requires Go 1.26 or later.

Build:

make build        # CLI + TUI to bin/
make build-cli
make build-tui
make build-server

Test:

make test         # unit tests
make test-cli     # CLI integration tests
make test-all     # both
make smoke        # end-to-end smoke tests against the built binary

Fuzz:

make fuzz
make fuzz FUZZTIME=60s

Benchmark:

go test -bench=. -benchtime=1s ./...
go test -bench=BenchmarkInferResistor -benchmem ./...

Lint and vulnerability check:

make lint
make vuln

Contributing

See CONTRIBUTING.md.


License

MIT. See LICENSE.

Documentation

Overview

Package resistor provides deterministic standards support and heuristic inference capabilities for fixed resistors.

The package is organized into layered responsibilities:

  1. Standards Encoding/Decoding - 4, 5, and 6-band color code support (IEC 60062) - SMD 3-digit, 4-digit, R-notation, and EIA‑96 support - Full E-series (E3–E192) preferred value support (IEC 60063)

  2. Selection Engine - Snap arbitrary resistance values to preferred E-series values - Encode selected values into visual band representations - Explicitly track defaults and assumptions

  3. Inference Engine - Deterministic extraction of known properties - Heuristic inference of type, power rating, voltage rating - Monotonic confidence model - Explicit assumption tracking

Design Principles:

  • Deterministic logic always overrides heuristic inference.
  • All assumptions are explicitly recorded.
  • Confidence values are bounded in [0.0, 1.0].
  • No silent guessing or hidden defaults.
  • API symmetry between encoding and decoding where possible.

This package is suitable for:

  • Engineering tools
  • Educational applications
  • Interactive TUI interfaces
  • WASM/web frontends

The API surface is intentionally explicit and structured to allow long-term stability and future extensibility.

Index

Examples

Constants

This section is empty.

Variables

View Source
var DigitColor = map[int]Color{
	0: Black,
	1: Brown,
	2: Red,
	3: Orange,
	4: Yellow,
	5: Green,
	6: Blue,
	7: Violet,
	8: Grey,
	9: White,
}

DigitColor maps digit → band color.

View Source
var DigitValue = map[Color]int{
	Black:  0,
	Brown:  1,
	Red:    2,
	Orange: 3,
	Yellow: 4,
	Green:  5,
	Blue:   6,
	Violet: 7,
	Grey:   8,
	White:  9,
}

DigitValue maps band color → digit.

View Source
var ErrInvalidBandCount = errors.New("invalid number of bands (must be 4, 5, or 6)")

ErrInvalidBandCount indicates that the provided band slice does not contain 4, 5, or 6 entries.

4-band format:

digit, digit, multiplier, tolerance

5-band format:

digit, digit, digit, multiplier, tolerance

6-band format:

digit, digit, digit, multiplier, tolerance, temp coefficient
View Source
var ErrInvalidDigitColor = errors.New("invalid digit color")

ErrInvalidDigitColor indicates that a band expected to represent a significant digit does not map to a valid digit color (0–9).

View Source
var ErrInvalidMultiplier = errors.New("invalid multiplier color")

ErrInvalidMultiplier indicates the multiplier band color does not map to a valid multiplier value.

View Source
var ErrInvalidTempCoeff = errors.New("invalid temperature coefficient color")

ErrInvalidTempCoeff indicates the 6th band color does not map to a known temperature coefficient.

View Source
var ErrInvalidTolerance = errors.New("invalid tolerance color")

ErrInvalidTolerance indicates the tolerance band color does not map to a known tolerance value.

View Source
var ErrUnencodableValue = errors.New("resistance cannot be encoded in 4 or 5 band format")

ErrUnencodableValue indicates that the provided resistance cannot be represented exactly in standard 4-band or 5-band format.

This happens when:

  • The resistance requires more than 2 or 3 significant digits
  • The resistance does not divide cleanly by any defined multiplier
  • The tolerance cannot be represented by a standard color
View Source
var MultiplierColor = map[float64]Color{
	1:             Black,
	10:            Brown,
	100:           Red,
	1_000:         Orange,
	10_000:        Yellow,
	100_000:       Green,
	1_000_000:     Blue,
	10_000_000:    Violet,
	100_000_000:   Grey,
	1_000_000_000: White,
	0.1:           Gold,
	0.01:          Silver,
}

MultiplierColor maps multiplier factor → band color.

View Source
var MultiplierValue = map[Color]float64{
	Black:  1,
	Brown:  10,
	Red:    100,
	Orange: 1_000,
	Yellow: 10_000,
	Green:  100_000,
	Blue:   1_000_000,
	Violet: 10_000_000,
	Grey:   100_000_000,
	White:  1_000_000_000,
	Gold:   0.1,
	Silver: 0.01,
}

MultiplierValue maps band color → multiplier factor.

View Source
var TempCoeffColor = map[int]Color{
	100: Brown,
	50:  Red,
	15:  Orange,
	25:  Yellow,
	10:  Blue,
	5:   Violet,
}

TempCoeffColor maps ppm value → color.

View Source
var TempCoeffValue = map[Color]int{
	Brown:  100,
	Red:    50,
	Orange: 15,
	Yellow: 25,
	Blue:   10,
	Violet: 5,
}

TempCoeffValue maps 6th band color → temperature coefficient in ppm/°C. Defined according to IEC 60062.

View Source
var ToleranceColor = map[float64]Color{
	1.0:  Brown,
	2.0:  Red,
	0.5:  Green,
	0.25: Blue,
	0.1:  Violet,
	0.05: Grey,
	5.0:  Gold,
	10.0: Silver,
	20.0: None,
}

ToleranceColor maps tolerance percentage → band color.

View Source
var ToleranceValue = map[Color]float64{
	Brown:  1.0,
	Red:    2.0,
	Green:  0.5,
	Blue:   0.25,
	Violet: 0.1,
	Grey:   0.05,
	Gold:   5.0,
	Silver: 10.0,
	None:   20.0,
}

ToleranceValue maps band color → tolerance percentage.

Functions

func EncodeSMD

func EncodeSMD(resistance float64, mode SMDEncodingMode) (string, error)

EncodeSMD encodes a resistance value into an SMD marking.

Mode behavior:

SMDAuto:

Attempt standard 3/4 digit encoding first.
If not representable in 3/4-digit format, fall back to EIA-96.
If neither succeeds, return an error.

SMDStandard:

Only use 3/4 digit encoding.
Return an error if the value is not representable.

SMDEIA96:

Attempt EIA‑96 encoding.
If value cannot be represented exactly in E96 series, error.

func NearestStandard

func NearestStandard(value float64, series ESeries, mode RoundingMode) (float64, error)

NearestStandard snaps a resistance value to the nearest preferred value in the specified E-series.

Process Overview:

  1. Normalize input value into its decade: value = normalized × 10^exponent

    Example: 4700 → 4.7 × 10^3

  2. Compare normalized value to preferred numbers within 1.0–10.0 range.

3. Apply rounding rule (Nearest, Up, Down).

4. Re-scale back to original decade.

Example:

NearestStandard(500, E24, RoundNearest)
→ 510

NearestStandard(500, E12, RoundNearest)
→ 470

NearestStandard(500, E12, RoundUp)
→ 560

This function does NOT:

  • Validate manufacturability
  • Snap tolerance
  • Perform band encoding

It strictly performs IEC 60063 value selection.

Example
package main

import (
	"fmt"
	"github.com/sss7526/resistor"
)

func main() {

	v, _ := resistor.NearestStandard(500, resistor.E24, resistor.RoundNearest)
	fmt.Println(v)

	v, _ = resistor.NearestStandard(500, resistor.E12, resistor.RoundUp)
	fmt.Println(v)

}
Output:
510
560

Types

type AnalysisInput

type AnalysisInput struct {
	// Spec is the resistor being analyzed.
	Spec ResistorSpec

	// AppliedVoltage is the voltage across the resistor in volts.
	// Leave zero if not known.
	AppliedVoltage float64

	// AppliedCurrent is the current through the resistor in amperes.
	// Leave zero if not known.
	AppliedCurrent float64
}

AnalysisInput contains electrical conditions for resistor analysis.

Either AppliedVoltage or AppliedCurrent (or both) may be provided. If both are provided, consistency is checked against Ohm's Law.

type AnalysisReport

type AnalysisReport struct {
	// PowerDissipation is the computed power dissipation in watts (P = I²R).
	PowerDissipation float64

	// VoltageDrop is the voltage across the resistor in volts.
	VoltageDrop float64

	// Current is the current through the resistor in amperes.
	Current float64

	// DeratedSafePower is the 50%-derated safe operating power in watts.
	// Nil if the rated power was not provided.
	DeratedSafePower *float64 `json:"DeratedSafePower,omitempty"`

	// WorstCaseResistanceMin is the minimum resistance at the tolerance limit in ohms.
	// Nil if tolerance was not provided.
	WorstCaseResistanceMin *float64 `json:"WorstCaseResistanceMin,omitempty"`

	// WorstCaseResistanceMax is the maximum resistance at the tolerance limit in ohms.
	// Nil if tolerance was not provided.
	WorstCaseResistanceMax *float64 `json:"WorstCaseResistanceMax,omitempty"`

	// Warnings contains any engineering warnings generated during analysis.
	Warnings []AnalysisWarning
}

AnalysisReport contains deterministic electrical analysis results.

Pointer fields (DeratedSafePower, WorstCaseResistanceMin, WorstCaseResistanceMax) are nil when the required inputs were absent. A non-nil pointer to zero is a legitimately computed value (e.g. WorstCaseResistanceMin at 100% tolerance).

func AnalyzeResistor

func AnalyzeResistor(input AnalysisInput) (AnalysisReport, error)

AnalyzeResistor performs deterministic engineering analysis of a resistor under specified electrical conditions.

It computes:

  • Power dissipation
  • Voltage drop
  • Current
  • Derated safe power (50% rule)
  • Worst-case resistance bounds

The function does not error for missing optional inputs. Instead, it produces structured warnings.

type AnalysisWarning

type AnalysisWarning struct {
	// Level is the severity classification of the warning.
	Level WarningLevel

	// Message is a human-readable description of the condition.
	Message string
}

AnalysisWarning represents a structured engineering warning produced during analysis.

type BandRole

type BandRole int

BandRole describes the semantic role of a resistor band position.

Roles are derived from IEC 60062 band structure definitions.

These roles are used to:

  • Determine valid colors for a band position
  • Drive UI selection logic
  • Prevent duplicated band structure logic in frontends
const (
	// RoleDigit is a significant digit band (contributes a decimal digit to the resistance value).
	RoleDigit BandRole = iota

	// RoleMultiplier is the multiplier band (power-of-ten scaling factor).
	RoleMultiplier

	// RoleTolerance is the tolerance band (percentage deviation from nominal value).
	RoleTolerance

	// RoleTempCoeff is the temperature coefficient band (ppm/°C; 6-band resistors only).
	RoleTempCoeff
)

func BandRolesForCount

func BandRolesForCount(count int) ([]BandRole, error)

BandRolesForCount returns the ordered band roles for a resistor with the specified band count.

Supported band counts:

  • 4 bands
  • 5 bands
  • 6 bands

IEC 60062 definitions:

4-band:

Digit, Digit, Multiplier, Tolerance

5-band:

Digit, Digit, Digit, Multiplier, Tolerance

6-band:

Digit, Digit, Digit, Multiplier, Tolerance, TempCoeff

func (BandRole) String

func (r BandRole) String() string

String returns the name of the band role.

type Color

type Color string

Color represents a standard IEC resistor band color.

const (
	Black  Color = "black"
	Brown  Color = "brown"
	Red    Color = "red"
	Orange Color = "orange"
	Yellow Color = "yellow"
	Green  Color = "green"
	Blue   Color = "blue"
	Violet Color = "violet"
	Grey   Color = "grey"
	White  Color = "white"

	Gold   Color = "gold"
	Silver Color = "silver"

	Beige Color = "beige"
	Tan   Color = "tan"

	None Color = "none" // used when no tolerance band exists (±20%)
)

func BodyColors

func BodyColors() []Color

BodyColors returns colors meaningful for resistor body inference.

These are distinct from band digit colors.

func DigitColors

func DigitColors() []Color

DigitColors returns colors valid for significant digit bands (0–9).

func EncodeBands

func EncodeBands(spec ResistorSpec) ([]Color, error)

EncodeBands converts a ResistorSpec into IEC color bands.

Behavior:

4-band:

Used when tolerance > 2% and TempCoeffPPM == 0

5-band:

Used when tolerance ≤ 2% and TempCoeffPPM == 0

6-band:

Used when TempCoeffPPM != 0

TempCoeffPPM must match a defined TempCoeffValue entry exactly.

func EncodeBandsSimple

func EncodeBandsSimple(resistance, tolerance float64) ([]Color, error)

EncodeBandsSimple preserves backward compatibility.

Encodes resistance and tolerance without tempco.

func MultiplierColors

func MultiplierColors() []Color

MultiplierColors returns valid multiplier band colors.

func TempCoeffColors

func TempCoeffColors() []Color

TempCoeffColors returns valid 6th band temperature coefficient colors.

func ToleranceColors

func ToleranceColors() []Color

ToleranceColors returns valid tolerance band colors.

func ValidColorsForRole

func ValidColorsForRole(role BandRole) []Color

ValidColorsForRole returns the valid colors for a given band role.

This function exposes canonical color sets for UI layers and ensures no IEC duplication outside the core.

func (Color) String

func (c Color) String() string

String returns the color name as a plain string.

type ESeries

type ESeries int

ESeries represents a standard IEC 60063 preferred number series.

The number indicates how many logarithmically spaced values exist per decade (between 1.0 and 10.0).

Examples:

E6 → 6 values per decade E12 → 12 values per decade E24 → 24 values per decade E96 → 96 values per decade E192 → 192 values per decade

These series are used to standardize commercially available resistor values.

const (
	E3   ESeries = 3
	E6   ESeries = 6
	E12  ESeries = 12
	E24  ESeries = 24
	E48  ESeries = 48
	E96  ESeries = 96
	E192 ESeries = 192
)

func AllESeries

func AllESeries() []ESeries

AllESeries returns the supported E-series values.

func ParseESeries

func ParseESeries(input string) (ESeries, error)

ParseESeries converts a string into an ESeries value.

func (ESeries) String

func (e ESeries) String() string

String returns the canonical string representation of an E-series.

type InferenceMeta

type InferenceMeta struct {
	// Assumptions lists the human-readable reasoning steps applied during inference.
	Assumptions []string

	// Confidence is the aggregated confidence score in [0.0, 1.0].
	// Higher values indicate more corroborating evidence.
	Confidence float64
}

InferenceMeta contains metadata produced by the inference engine.

type InferenceResult

type InferenceResult struct {
	// Spec contains the inferred electrical characteristics of the resistor.
	Spec ResistorSpec

	// VoltageRating is a conservative estimated maximum operating voltage in volts.
	VoltageRating float64

	// Meta contains the confidence score and list of assumptions made during inference.
	Meta InferenceMeta
}

InferenceResult represents the inferred characteristics of an observed resistor.

Spec:

Electrical characteristics either deterministically decoded
or inferred via heuristic rules.

VoltageRating:

Conservative estimate derived from physical characteristics.

Meta:

Contains assumptions made and overall confidence score.

Confidence Model:

Confidence ∈ [0.0 – 1.0]

Deterministic facts contribute weight = 1.0
Heuristic rules contribute weight ∈ (0,1)

Final confidence is a weighted average of all applied rules.

func InferResistor

func InferResistor(obs ObservedResistor) (InferenceResult, error)

InferResistor attempts to infer properties of an observed resistor.

Process:

1. Extract deterministic facts:

  • Decode color bands (if present)
  • Decode SMD marking (if present)

2. Apply heuristic rules:

  • Body color → resistor type
  • Band count → tolerance hint
  • Physical length → power rating
  • Package type → power estimate

3. Aggregate results:

  • Deterministic values override heuristics
  • Heuristic contributions averaged by weight
  • Confidence computed as weighted mean

This engine is intentionally transparent and deterministic.

type InferenceRule

type InferenceRule struct {
	// Name is a human-readable identifier for this rule (used in logging/debugging).
	Name string

	// Weight is the relative confidence contribution of this rule in [0.0, 1.0].
	Weight float64

	// Apply evaluates the rule against an observed resistor and returns a
	// contribution and whether the rule fired.
	Apply func(obs ObservedResistor) (inferenceContribution, bool)
}

InferenceRule defines a single heuristic rule.

Weight:

Relative confidence in this rule (0.0–1.0)

Apply:

Returns a contribution and whether rule applied.

type ObservedResistor

type ObservedResistor struct {
	// Bands holds observed color bands. Valid counts are 4, 5, or 6.
	Bands []Color

	// BodyColor is the body color of the resistor (used for type inference).
	BodyColor Color

	// LengthMM is the physical body length in millimeters (used for power inference).
	LengthMM float64

	// Package is the observed package type (used for power and voltage inference).
	Package PackageType

	// Marking is the printed SMD code, if visible (e.g. "472", "4R7", "01C").
	Marking string
}

ObservedResistor represents incomplete data collected from a physical resistor without reference to its original packaging or datasheet. All fields are optional; provide whichever are observable.

type PackageType

type PackageType string

PackageType represents the physical mounting style of a resistor.

const (
	// ThroughHole is a standard leaded resistor for PCB through-hole mounting.
	ThroughHole PackageType = "through_hole"

	// SMD is a generic surface-mount resistor with unspecified case size.
	SMD PackageType = "smd"

	// SMD0402 is a 1.0×0.5 mm surface-mount case (1/16 W typical).
	SMD0402 PackageType = "smd_0402"

	// SMD0603 is a 1.6×0.8 mm surface-mount case (0.1 W typical).
	SMD0603 PackageType = "smd_0603"

	// SMD0805 is a 2.0×1.25 mm surface-mount case (0.125 W typical).
	SMD0805 PackageType = "smd_0805"

	// SMD1206 is a 3.2×1.6 mm surface-mount case (0.25 W typical).
	SMD1206 PackageType = "smd_1206"

	// Axial is a leaded resistor with leads extending from both ends along the axis.
	Axial PackageType = "axial"

	// Radial is a leaded resistor with leads extending from the same end.
	Radial PackageType = "radial"

	// UnknownPKG is used when the package type cannot be determined.
	UnknownPKG PackageType = "unknown"
)

func AllPackageTypes

func AllPackageTypes() []PackageType

AllPackageTypes returns the commonly selectable package types. UnknownPKG is excluded; it is used internally when a type cannot be determined.

func ParsePackageType

func ParsePackageType(input string) (PackageType, error)

ParsePackageType converts a string into a PackageType.

func (PackageType) String

func (p PackageType) String() string

String returns the canonical string representation of a package type.

type ResistorSpec

type ResistorSpec struct {
	// ResistanceOhms is the nominal resistance in ohms.
	ResistanceOhms float64

	// TolerancePct is the tolerance as a percentage (e.g. 5 for ±5%).
	TolerancePct float64

	// PowerWatts is the rated power dissipation in watts.
	PowerWatts float64

	// TempCoeffPPM is the temperature coefficient in ppm/°C (6-band resistors only).
	TempCoeffPPM int

	// Package is the physical mounting style.
	Package PackageType

	// Type is the construction technology.
	Type ResistorType
}

ResistorSpec represents a fully specified resistor with known, deterministic values.

func DecodeBands

func DecodeBands(bands []Color) (ResistorSpec, error)

DecodeBands converts a slice of 4, 5, or 6 color bands into a ResistorSpec.

Only the following fields of ResistorSpec are populated:

  • ResistanceOhms
  • TolerancePct
  • TempCoeffPPM (6-band only)

No inference is performed. No power rating is assumed.

Resistor Band Structure (IEC 60062):

4-band resistor:

Band 1: First significant digit
Band 2: Second significant digit
Band 3: Multiplier (power of ten scaling factor)
Band 4: Tolerance

5-band resistor:

Band 1: First significant digit
Band 2: Second significant digit
Band 3: Third significant digit
Band 4: Multiplier
Band 5: Tolerance

6-band resistor:

Band 1: First significant digit
Band 2: Second significant digit
Band 3: Third significant digit
Band 4: Multiplier
Band 5: Tolerance
Band 6: Temperature coefficient

Example (4-band):

Green, Brown, Brown, Gold

Digits: 5 1
Multiplier: 10
→ 51 × 10 = 510Ω
Tolerance: ±5%

Mathematical Model:

Resistance = (significant digits combined as integer) × multiplier

Example:

Digits: [5, 1]
Combined: 51
Multiplier: 10
Result: 51 × 10 = 510Ω

This function strictly follows that model.

func DecodeSMD

func DecodeSMD(marking string) (ResistorSpec, error)

DecodeSMD decodes a surface-mount resistor marking.

Supported formats:

3-digit:

"472" → 47 × 10² = 4700Ω

4-digit:

"4701" → 470 × 10¹ = 4700Ω

R-notation:

"4R7" → 4.7Ω
"R47" → 0.47Ω

EIA‑96:

"01C" → lookup(01) × multiplier(C)

Tolerance is not encoded in SMD markings. TolerancePct will be left as zero.

type ResistorType

type ResistorType string

ResistorType represents the construction technology of a resistor.

const (
	// CarbonFilm is a carbon film resistor; common, low cost, moderate tolerance.
	CarbonFilm ResistorType = "carbon_film"

	// MetalFilm is a metal film resistor; tight tolerance, low noise, blue body typical.
	MetalFilm ResistorType = "metal_film"

	// ThickFilm is a thick film SMD resistor; standard surface-mount construction.
	ThickFilm ResistorType = "thick_film"

	// ThinFilm is a thin film SMD resistor; high precision, low temperature coefficient.
	ThinFilm ResistorType = "thin_film"

	// Wirewound is a wire-wound resistor; high power, high precision, inductive.
	Wirewound ResistorType = "wirewound"

	// MetalOxide is a metal oxide resistor; high stability, flame-resistant, green body typical.
	MetalOxide ResistorType = "metal_oxide"

	// UnknownType is used when the resistor construction type cannot be determined.
	UnknownType ResistorType = "unknown"
)

type RoundingMode

type RoundingMode int

RoundingMode defines how a value should be snapped to the nearest preferred number.

const (
	// RoundingUnspecified is the zero value; treated as RoundNearest by all functions.
	RoundingUnspecified RoundingMode = iota

	// RoundNearest selects the closest preferred value.
	RoundNearest

	// RoundUp selects the next highest preferred value.
	RoundUp

	// RoundDown selects the next lowest preferred value.
	RoundDown
)

func AllRoundingModes

func AllRoundingModes() []RoundingMode

AllRoundingModes returns all supported rounding modes.

func ParseRoundingMode

func ParseRoundingMode(input string) (RoundingMode, error)

ParseRoundingMode converts a string into a RoundingMode.

func (RoundingMode) String

func (r RoundingMode) String() string

String returns the canonical string representation of a rounding mode.

type SMDEncodingMode

type SMDEncodingMode int

SMDEncodingMode controls how EncodeSMD formats output.

SMDAuto:

Automatically choose 3-digit or 4-digit encoding.
If not representable, return error.

SMDStandard:

Force 3/4-digit encoding only.

SMDEIA96:

Force EIA‑96 encoding (1% precision format).
const (
	// SMDAuto tries standard 3/4-digit encoding first, then falls back to EIA-96.
	SMDAuto SMDEncodingMode = iota

	// SMDStandard forces 3/4-digit numeric encoding only.
	SMDStandard

	// SMDEIA96 forces EIA-96 two-digit-plus-letter encoding only.
	SMDEIA96
)

type SelectionRequest

type SelectionRequest struct {
	// Desired resistance in ohms.
	Resistance float64

	// Optional preferred E-series.
	// If zero-value, defaults to E24.
	Series ESeries

	// Optional tolerance percentage.
	// If zero-value, defaults to 5%.
	TolerancePct float64

	// Optional rounding mode.
	// If zero-value, defaults to RoundNearest.
	Rounding RoundingMode
}

SelectionRequest represents an engineering intent to select a standard resistor.

Zero-value fields are treated as unspecified and will be replaced with sensible defaults.

type SelectionResult

type SelectionResult struct {
	RequestedResistance float64
	SelectedResistance  float64

	Series       ESeries
	TolerancePct float64
	Rounding     RoundingMode

	Bands []Color

	Assumptions []string
}

SelectionResult represents the fully resolved resistor selection.

This includes:

  • The originally requested resistance
  • The snapped standard resistance
  • The E-series used
  • The tolerance applied
  • The rounding mode used
  • The resulting color bands
  • Explicit assumptions made during selection

func SelectStandardResistor

func SelectStandardResistor(req SelectionRequest) (SelectionResult, error)

SelectStandardResistor performs a full forward transformation:

Engineering intent → Standard value → Color bands

Process:

1. Validate requested resistance. 2. Apply defaults where fields are unspecified. 3. Snap resistance to preferred E-series value. 4. Encode selected value into color bands. 5. Return structured result with explicit assumptions.

Defaults:

Series        → E24
Tolerance     → 5%
Rounding Mode → RoundNearest

This function is deterministic and does not perform inference.

Example
package main

import (
	"fmt"
	"github.com/sss7526/resistor"
)

func main() {
	req := resistor.SelectionRequest{
		Resistance: 487,
	}

	res, _ := resistor.SelectStandardResistor(req)

	fmt.Println(res.SelectedResistance)
	fmt.Println(res.Bands)

}
Output:
470
[yellow violet brown gold]

type VisualProfile

type VisualProfile struct {
	// Bands holds the ordered color bands (4, 5, or 6 entries).
	Bands []Color

	// BodyColor is the primary body color of the resistor package.
	BodyColor Color

	// SMDCode is the printed surface-mount marking (e.g. "472", "01C").
	SMDCode string
}

VisualProfile represents a visual encoding of a resistor's markings.

type WarningLevel

type WarningLevel string

WarningLevel indicates the severity of an analysis warning.

const (
	// WarningInfo is an informational note; no action required.
	WarningInfo WarningLevel = "info"

	// WarningCaution indicates a condition that may warrant review.
	WarningCaution WarningLevel = "caution"

	// WarningDanger indicates a condition likely to cause component failure.
	WarningDanger WarningLevel = "danger"
)

Directories

Path Synopsis
cmd
resistor-cli command
resistor-server command
resistor-tui command
resistor-tui/app
Package app implements the Bubble Tea application layer for the interactive resistor TUI.
Package app implements the Bubble Tea application layer for the interactive resistor TUI.
resistor-wasm command
internal
cli

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL