gosmc

package module
v0.0.0-...-36c9172 Latest Latest
Warning

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

Go to latest
Published: Jul 13, 2026 License: GPL-2.0 Imports: 9 Imported by: 1

README

gosmc

gosmc is a Go library and example CLI for reading and writing Apple SMC keys on macOS.

The low-level SMC calls use CGO and IOKit. Key lookup, caching, value encoding, and value decoding live in Go.

Requirements

  • macOS with CGO enabled
  • Go 1.22 or newer
  • Permission to read or write the target SMC key

Library

Install:

go get github.com/charlie0129/gosmc

Read a value:

package main

import (
	"fmt"

	"github.com/charlie0129/gosmc"
)

func main() {
	client, err := gosmc.Open()
	if err != nil {
		panic(err)
	}
	defer client.Close()

	value, err := client.Read("FNum")
	if err != nil {
		panic(err)
	}

	count, err := value.Uint64()
	if err != nil {
		panic(err)
	}
	fmt.Println("fans:", count)
}

Write typed values without manually packing bytes:

// Writes ui32 as big-endian SMC bytes after checking the key type and size.
if err := client.WriteUint32("TEST", 1234); err != nil {
	panic(err)
}

// Writes flt/fixed-point/{pwm} keys using the key's native representation.
if err := client.WriteFloat64("F0Tg", 2200); err != nil {
	panic(err)
}

// Raw byte writes are still available when you need full control.
if err := client.WriteBytes("CH0B", []byte{0x02}); err != nil {
	panic(err)
}

Supported numeric data types include ui8 , ui16, ui32, si8 , si16, flt , common unsigned/signed fixed-point types such as fpe2 and sp78, and {pwm}.

CLI

Build:

make

Read one or more keys:

bin/gosmc read FNum
bin/gosmc read F0Ac F0Mn F0Mx

Write a number using the key's native SMC data type:

bin/gosmc write F0Tg 2200
bin/gosmc write TEST 0x4d2

Write raw bytes when the key is not a supported numeric type:

bin/gosmc write CH0B 02 --hex

List keys and inspect common groups:

bin/gosmc list --prefix F
bin/gosmc temps
bin/gosmc fans

The CLI prints command results to stdout in a human-readable format by default. Use --json for machine-readable output. Human-readable float formatting defaults to at most 2 fractional digits and can be adjusted with --float-digits. Diagnostic logs and warnings still go to stderr.

bin/gosmc read FNum
bin/gosmc --float-digits 1 list --prefix T
bin/gosmc --json read FNum
bin/gosmc --log-level debug list --continue-on-error
bin/gosmc --json-logs --log-level debug list --continue-on-error

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidKey      = errors.New("smc key must be exactly 4 bytes")
	ErrInvalidData     = errors.New("invalid smc data")
	ErrNoData          = errors.New("smc key has no data")
	ErrClosed          = errors.New("smc client is not open")
	ErrUnsupported     = errors.New("operation is not supported")
	ErrTypeMismatch    = errors.New("value is incompatible with smc data type")
	ErrValueOutOfRange = errors.New("value is out of range")
)

Functions

func DecodeFloat

func DecodeFloat(dataType DataType, bytes []byte) (float64, error)

DecodeFloat decodes flt, fixed-point, and {pwm values.

func DecodeInt

func DecodeInt(dataType DataType, bytes []byte) (int64, error)

DecodeInt decodes si8, si16, si32, and si64 values.

func DecodeUint

func DecodeUint(dataType DataType, bytes []byte) (uint64, error)

DecodeUint decodes ui8, ui16, ui32, and ui64 values.

func EncodeFloat

func EncodeFloat(dataType DataType, size int, value float64) ([]byte, error)

EncodeFloat encodes flt, fixed-point, and {pwm values.

func EncodeInt

func EncodeInt(dataType DataType, size int, value int64) ([]byte, error)

EncodeInt encodes si8, si16, si32, and si64 values.

func EncodeUint

func EncodeUint(dataType DataType, size int, value uint64) ([]byte, error)

EncodeUint encodes ui8, ui16, ui32, and ui64 values.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is an open Apple SMC connection plus a Go-side key-info cache.

func New

func New() *Client

New creates a client. Call Open before using it, or use Open directly.

func NewMock

func NewMock(values ...Value) *Client

NewMock creates an in-memory SMC client for tests and tools.

func Open

func Open() (*Client, error)

Open opens the default Apple SMC connection.

func (*Client) Close

func (c *Client) Close() error

Close closes the SMC connection.

func (*Client) KeyAt

func (c *Client) KeyAt(index uint32) (string, error)

KeyAt returns the key at a zero-based SMC key index.

func (*Client) KeyCount

func (c *Client) KeyCount() (uint32, error)

KeyCount returns the SMC key count from #KEY.

func (*Client) KeyInfo

func (c *Client) KeyInfo(key string) (KeyInfo, error)

KeyInfo returns cached metadata for key, fetching it from the SMC if needed.

func (*Client) Keys

func (c *Client) Keys() ([]string, error)

Keys returns all SMC keys in firmware index order.

func (*Client) Open

func (c *Client) Open() error

Open opens the client's SMC connection.

func (*Client) Read

func (c *Client) Read(key string) (Value, error)

Read reads and decodes the metadata for key.

func (*Client) ReadAll

func (c *Client) ReadAll() ([]Value, error)

ReadAll reads every indexed SMC key.

func (*Client) WriteBytes

func (c *Client) WriteBytes(key string, data []byte) error

WriteBytes writes raw bytes to key after validating the key's expected size.

func (*Client) WriteFloat32

func (c *Client) WriteFloat32(key string, value float32) error

WriteFloat32 writes a float to an flt, fixed-point, or pwm SMC key.

func (*Client) WriteFloat64

func (c *Client) WriteFloat64(key string, value float64) error

WriteFloat64 writes a float to an flt, fixed-point, or pwm SMC key.

func (*Client) WriteInt8

func (c *Client) WriteInt8(key string, value int8) error

WriteInt8 writes a signed integer to a si8 SMC key.

func (*Client) WriteInt16

func (c *Client) WriteInt16(key string, value int16) error

WriteInt16 writes a signed integer to a si16 SMC key.

func (*Client) WriteInt64

func (c *Client) WriteInt64(key string, value int64) error

WriteInt64 writes a signed integer to a signed SMC integer key.

func (*Client) WriteUint8

func (c *Client) WriteUint8(key string, value uint8) error

WriteUint8 writes an unsigned integer to a ui8 SMC key.

func (*Client) WriteUint16

func (c *Client) WriteUint16(key string, value uint16) error

WriteUint16 writes an unsigned integer to a ui16 SMC key.

func (*Client) WriteUint32

func (c *Client) WriteUint32(key string, value uint32) error

WriteUint32 writes an unsigned integer to a ui32 SMC key.

func (*Client) WriteUint64

func (c *Client) WriteUint64(key string, value uint64) error

WriteUint64 writes an unsigned integer to an unsigned SMC integer key.

type DataType

type DataType string

DataType is the four-byte SMC data type attached to a key.

const (
	TypeFloat32 DataType = "flt "

	TypeFP1F DataType = "fp1f"
	TypeFP4C DataType = "fp4c"
	TypeFP5B DataType = "fp5b"
	TypeFP6A DataType = "fp6a"
	TypeFP79 DataType = "fp79"
	TypeFP88 DataType = "fp88"
	TypeFPA6 DataType = "fpa6"
	TypeFPC4 DataType = "fpc4"
	TypeFPE2 DataType = "fpe2"

	TypeSP1E DataType = "sp1e"
	TypeSP3C DataType = "sp3c"
	TypeSP4B DataType = "sp4b"
	TypeSP5A DataType = "sp5a"
	TypeSP69 DataType = "sp69"
	TypeSP78 DataType = "sp78"
	TypeSP87 DataType = "sp87"
	TypeSP96 DataType = "sp96"
	TypeSPB4 DataType = "spb4"
	TypeSPF0 DataType = "spf0"

	TypeUInt8  DataType = "ui8 "
	TypeUInt16 DataType = "ui16"
	TypeUInt32 DataType = "ui32"
	TypeUInt64 DataType = "ui64"

	TypeSInt8  DataType = "si8 "
	TypeSInt16 DataType = "si16"
	TypeSInt32 DataType = "si32"
	TypeSInt64 DataType = "si64"

	TypePWM DataType = "{pwm"
)

func (DataType) IsFixedPoint

func (t DataType) IsFixedPoint() bool

func (DataType) IsNumeric

func (t DataType) IsNumeric() bool

func (DataType) IsSignedInteger

func (t DataType) IsSignedInteger() bool

func (DataType) IsUnsignedInteger

func (t DataType) IsUnsignedInteger() bool

func (DataType) String

func (t DataType) String() string

type DisplayOption

type DisplayOption func(*DisplayOptions)

DisplayOption mutates DisplayOptions.

func WithFloatDigits

func WithFloatDigits(n int) DisplayOption

WithFloatDigits limits float output to at most n fractional digits. Use -1 to keep the default shortest representation.

func WithHexLimit

func WithHexLimit(n int) DisplayOption

WithHexLimit truncates fallback hex displays to at most n characters.

func WithStringLimit

func WithStringLimit(n int) DisplayOption

WithStringLimit truncates printable string values to at most n characters.

type DisplayOptions

type DisplayOptions struct {
	FloatDigits  int
	MaxStringLen int
	MaxHexLen    int
}

DisplayOptions controls how Value.Display renders human-readable output.

type IOReturnError

type IOReturnError struct {
	Op   string
	Code uint32
}

IOReturnError wraps a non-success kern_return_t from an IOKit SMC call.

func (IOReturnError) Error

func (e IOReturnError) Error() string

type KeyInfo

type KeyInfo struct {
	Key       string
	DataSize  int
	DataType  DataType
	Attribute byte
}

KeyInfo describes an SMC key without reading its value bytes.

type Value

type Value struct {
	Key      string
	DataType DataType
	Bytes    []byte
}

Value is a raw SMC value plus the data type needed to decode it.

func NewValue

func NewValue(key string, dataType DataType, bytes []byte) (Value, error)

NewValue builds a value and copies bytes so callers can safely reuse data.

func (Value) Decoded

func (v Value) Decoded() (value any, ok bool, err error)

Decoded decodes known SMC numeric types. Unknown types return ok=false.

func (Value) Display

func (v Value) Display(opts ...DisplayOption) string

Display returns a human-readable decoded value when possible, then falls back to hex.

func (Value) Float64

func (v Value) Float64() (float64, error)

Float64 decodes the value as an flt, fixed-point, or pwm SMC value.

func (Value) Hex

func (v Value) Hex() string

Hex returns the value bytes as a compact hex string.

func (Value) HexBytes

func (v Value) HexBytes() string

HexBytes returns the value bytes as space-separated hex bytes.

func (Value) Int64

func (v Value) Int64() (int64, error)

Int64 decodes the value as a signed SMC integer.

func (Value) StringValue

func (v Value) StringValue() (string, bool)

StringValue returns printable ASCII when all bytes are printable, otherwise ok=false.

func (Value) Uint64

func (v Value) Uint64() (uint64, error)

Uint64 decodes the value as an unsigned SMC integer.

Directories

Path Synopsis
cmd
gosmc command

Jump to

Keyboard shortcuts

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