skreader

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jan 23, 2024 License: MIT Imports: 10 Imported by: 0

README

skreader

Test Go code Lint Go code

Golang library and command line tool for SEKONIC spectrometers.

Based on original C# SDK for Windows from SEKONIC.

Supported (tested) models

  • Sekonic C-700
  • Sekonic C-800
  • Sekonic C-7000 (supports extended measurement configuration: FOV and Exposure Time)

Supported (tested) platforms

  • Darwin
  • Windows
  • Linux

Dependencies

Default implementation uses gousb wrapper for the libusb library.

You must have libusb-1.0 be installed on your target system to be able to communicate with USB devices.

Installation for different platforms is covered in gousb documentation.

Alternatively you can provide custom USB implementation with simple interface close to io.Reader. See the default gousb based implementation for reference.

SDK usage

See the skread command implementation.

Command line usage

go run github.com/akares/skreader/cmd/skread

License

This project is licensed under the terms of the MIT license.

All product names, logos, and brands are property of their respective owners. All company, product and service names used in this package are for identification purposes only. Use of these names, logos, and brands does not imply endorsement.

  • SEKONIC is a registered trademark of SEKONIC CORPORATION.
  • Google is a registered trademark of Google LLC.
  • Windows is a registered trademark of Microsoft Corporation.
  • Linux is the registered trademark of Linus Torvalds.

Documentation

Index

Constants

View Source
const (
	WaitConnTimeoutDefault = time.Duration(5) * time.Second       // how long to wait for device to start measuring
	WaitMeasTimeoutDefault = time.Duration(20) * time.Second      // how long to wait for device to end measuring
	WaitPollFreqDefault    = time.Duration(50) * time.Millisecond // how often to poll device for status

	ReadBufSize = MeasurementDataValidSize // MeasurementDataValidSize bytes is currently the maximum size of the data that can be sent by the device
)
View Source
const (
	IDVendor  = 0x0A41
	IDProduct = 0x7003

	EndpointNumOut = 0x02
	EndpointNumIn  = 0x81
)
View Source
const (
	MeasurementDataValidSize = 2380 // tested on C-7000, C-800, C-700
)

Variables

View Source
var (
	GousbNewContext = func() *gousb.Context {
		return gousb.NewContext()
	}
	GousbOpenDeviceWithVIDPID = func(ctx *gousb.Context, vid gousb.ID, pid gousb.ID) (*gousb.Device, error) {
		return ctx.OpenDeviceWithVIDPID(vid, pid)
	}
	GousbDefaultInterface = func(d *gousb.Device) (*gousb.Interface, func(), error) {
		return d.DefaultInterface()
	}
	GousbInEndpoint = func(i *gousb.Interface, epNum int) (*gousb.InEndpoint, error) {
		return i.InEndpoint(epNum)
	}
	GousbOutEndpoint = func(i *gousb.Interface, epNum int) (*gousb.OutEndpoint, error) {
		return i.OutEndpoint(epNum)
	}
	GousbManufacturer = func(d *gousb.Device) (string, error) {
		return d.Manufacturer()
	}
	GousbProduct = func(d *gousb.Device) (string, error) {
		return d.Product()
	}
	GousbRead = func(ep *gousb.InEndpoint, buf []byte) (int, error) {
		return ep.Read(buf)
	}
	GousbWrite = func(ep *gousb.OutEndpoint, buf []byte) (int, error) {
		return ep.Write(buf)
	}
)

Expose all used gousb functions as variables to be able to mock them in tests.

View Source
var (
	SkResponseOK = []byte{6, 48} // ACK response from device when command executed successfully
)
View Source
var Testdata = []byte{} /* 2380 elements not displayed */
View Source
var TestdataUnder = []byte{} /* 2380 elements not displayed */

Functions

This section is empty.

Types

type CIE1931Value

type CIE1931Value struct {
	X DecimalValue
	Y DecimalValue
	Z DecimalValue
}

CIE1931Value represents a CIE 1931 (x, y, z) chromaticity coordinates.

type CIE1976Value

type CIE1976Value struct {
	Ud DecimalValue
	Vd DecimalValue
}

CIE1976Value represents a CIE 1976 (u', v') chromaticity coordinates.

type ColorRenditionIndexesValue

type ColorRenditionIndexesValue struct {
	Ra DecimalValue
	Ri [14]DecimalValue
}

ColorRenditionIndexesValue represents a color rendition indexes Ra and Ri.

type ColorTemperatureValue

type ColorTemperatureValue struct {
	//nolint:all
	Tcp     DecimalValue // Correlated Color Temperature
	DeltaUv DecimalValue // Deviation from the Planckian locus
}

ColorTemperatureValue represents a correlated color temperature value in Kelvin.

type DecimalValue

type DecimalValue struct {
	Val   float64
	Str   string
	Range ValueRange
}

func (DecimalValue) String

func (v DecimalValue) String() string

type Device

type Device struct {
	Manufacturer string
	Product      string

	MeasurementConfig DeviceMeasurementConfig // Currently supported only by C-7000
	// contains filtered or unexported fields
}

Device represents SEKONIC device handler.

func NewDeviceWithAdapter

func NewDeviceWithAdapter(adapter UsbAdapter) (*Device, error)

NewDeviceWithAdapter creates SEKONIC device handler using provided UsbAdapter concrete implementation. Running this function will ensure that device is connected and will read its minimal USB device info.

Sending commands to device is done by calling methods on returned Device struct.

Command execution is synchronized, so only one command can be executed at a time and (hopefully) is safe for concurrent use by multiple goroutines within one Device instance. Note that even if commands sent in parallel will be executed in sequence, it still can put the device into incorrect logical state.

After using device, Close method must be called to release all allocated resources. Until Close is called, device may not be available for other processes.

func (*Device) Close

func (d *Device) Close() error

Close releases all allocated resources. After calling this method, device handle is no longer usable. There is no separate Open method, because it is done implicitly by NewFromAdapter.

func (*Device) FirmwareVersion

func (d *Device) FirmwareVersion() (int, error)

FirmwareVersion requests device main firmware version.

func (*Device) Measure

func (d *Device) Measure() (*Measurement, error)

Measure performs one measurement and returns result.

func (*Device) MeasurementResult

func (d *Device) MeasurementResult() (*Measurement, error)

MeasurementResult requests device measurement result data.

func (*Device) ModelName

func (d *Device) ModelName() (string, error)

ModelName requests device model name.

func (*Device) SetMeasurementConfiguration

func (d *Device) SetMeasurementConfiguration() error

SetMeasurementConfiguration sends measurement configuration options to device.

func (*Device) SetRemoteOff

func (d *Device) SetRemoteOff() error

SetRemoteOff sets device back to normal control mode.

func (*Device) SetRemoteOn

func (d *Device) SetRemoteOn() error

SetRemoteOn sets device to remote control mode.

func (*Device) StartMeasuring

func (d *Device) StartMeasuring() error

StartMeasuring sends command to device to start measuring.

func (*Device) State

func (d *Device) State() (*DeviceState, error)

State requests device current operational mode, knobs and buttons states.

func (*Device) String

func (d *Device) String() string

String returns device readble name. It tries to use Manufacturer and Product, but if any of them is empty, it uses "SEKONIC" dummy name.

func (*Device) SupportsExtendedMeasurementConfiguration

func (d *Device) SupportsExtendedMeasurementConfiguration() bool

SupportsExtendedMeasurementConfiguration reports whether device supports extended measurement configuration. Tested C-700, C-800, C-7000 models.

func (*Device) SupportsMeasurementConfiguration

func (d *Device) SupportsMeasurementConfiguration() bool

SupportsMeasurementConfiguration reports whether device supports measurement configuration. Tested C-700, C-800, C-7000 models.

func (*Device) WaitReady

func (d *Device) WaitReady(duration, step time.Duration) error

WaitReady waits for device to be ready for next measurement. It polls device state every step duration until idle status is reached or timeout duration is reached. If device state is not valid for measurement, error is returned. If timeout is reached, error is returned.

type DeviceMeasurementConfig

type DeviceMeasurementConfig struct {
	MeasuringMode SkMeasuringMode // only ambient is supported yet
	FieldOfView   SkFieldOfView
	ExposureTime  SkExposureTime
	ShutterSpeed  SkShutterSpeed
}

DeviceMeasurementConfig represents configuration used for measurement.

type DeviceState

type DeviceState struct {
	Status SkDeviceStatus
	Remote SkRemoteStatus
	Button SkButtonStatus
	Ring   SkRingStatus
}

DeviceState represents device current operational mode, knobs and buttons states.

type DominantWavelengthValue

type DominantWavelengthValue struct {
	Wavelength       DecimalValue
	ExcitationPurity DecimalValue
}

DominantWavelengthValue represents a dominant wavelength value in nm and excitation purity in %.

type FakeusbAdapter

type FakeusbAdapter struct {
	OpenResponse         error
	CloseResponse        error
	WriteResponse        error
	ReadResponse         []FakeusbAdapterReadResponse
	ReadResponseIndex    int
	ManufacturerResponse FakeusbAdapterManufacturerResponse
	ProductResponse      FakeusbAdapterProductResponse
}

FakeusbAdapter implements UsbAdapter interface for testing purposes. It does nothing but allows to mock USB device responses by setting up desired values in struct fields.

func (*FakeusbAdapter) Close

func (f *FakeusbAdapter) Close() (err error)

func (*FakeusbAdapter) Manufacturer

func (f *FakeusbAdapter) Manufacturer() (string, error)

func (*FakeusbAdapter) Open

func (f *FakeusbAdapter) Open() (err error)

func (*FakeusbAdapter) Product

func (f *FakeusbAdapter) Product() (string, error)

func (*FakeusbAdapter) Read

func (f *FakeusbAdapter) Read(buf []byte) (int, error)

func (*FakeusbAdapter) Write

func (f *FakeusbAdapter) Write(_ []byte) (int, error)

type FakeusbAdapterManufacturerResponse

type FakeusbAdapterManufacturerResponse struct {
	Val string
	Err error
}

type FakeusbAdapterProductResponse

type FakeusbAdapterProductResponse struct {
	Val string
	Err error
}

type FakeusbAdapterReadResponse

type FakeusbAdapterReadResponse struct {
	Data []byte
	Err  error
}

type GousbAdapter

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

GousbAdapter implements UsbAdapter interface using `gousb` library. The gousb package is a Google's Go-like wrapper around `libusb` library which is required to be installed on the target system. See more: https://github.com/libusb/libusb/wiki

func (*GousbAdapter) Close

func (u *GousbAdapter) Close() (err error)

func (*GousbAdapter) Manufacturer

func (u *GousbAdapter) Manufacturer() (string, error)

func (*GousbAdapter) Open

func (u *GousbAdapter) Open() (err error)

func (*GousbAdapter) Product

func (u *GousbAdapter) Product() (string, error)

func (*GousbAdapter) Read

func (u *GousbAdapter) Read(buf []byte) (int, error)

func (*GousbAdapter) Write

func (u *GousbAdapter) Write(buf []byte) (int, error)

type IlluminanceValue

type IlluminanceValue struct {
	Lux        DecimalValue
	FootCandle DecimalValue
}

IlluminanceValue represents an illuminance value in Lux and foot-candle units.

type Measurement

type Measurement struct {
	Tristimulus      TristimulusValue        // Tristimulus values in XYZ color space
	ColorTemperature ColorTemperatureValue   // Correlated Color Temperature
	Illuminance      IlluminanceValue        // Illuminance
	CIE1931          CIE1931Value            // CIE 1931 (x, y, z) chromaticity coordinates
	CIE1976          CIE1976Value            // CIE 1976 (u', v') chromaticity coordinates
	DWL              DominantWavelengthValue // Dominant Wavelength
	PPFD             DecimalValue            // Photosynthetic Photon Flux Density

	ColorRenditionIndexes ColorRenditionIndexesValue // Color Rendition Indexes

	SpectralData5nm [80]DecimalValue  // Spectral Data (5nm)
	SpectralData1nm [400]DecimalValue // Spectral Data (1nm)
	PeakWavelength  int               // Peak Wavelength (380...780nm)
}

Measurement represents a measurement data from SEKONIC device. Data format is based on original C-7000 SDK from SEKONIC (distributed only as Windows DLL).

func NewMeasurementFromBytes

func NewMeasurementFromBytes(data []byte) (*Measurement, error)

NewMeasurementFromBytes creates a new Measurement instance from the given raw binary response from SEKONIC device. Note: currently only ambient measuring mode results are supported. Magic numbers for limits and precisions are based on original C-7000 SDK from SEKONIC.

func (*Measurement) Repr

func (m *Measurement) Repr() string

Repr returns a full string representation of the Measurement instance.

func (*Measurement) String

func (m *Measurement) String() string

String returns limited a string representation of the Measurement instance.

type SkButtonStatus

type SkButtonStatus int
const (
	SkButtonStatusNone      SkButtonStatus = 0
	SkButtonStatusPower     SkButtonStatus = 1
	SkButtonStatusMeasuring SkButtonStatus = 2
	SkButtonStatusMemory    SkButtonStatus = 4
	SkButtonStatusMenu      SkButtonStatus = 8
	SkButtonStatusPanel     SkButtonStatus = 0x10
)

type SkCommand

type SkCommand string
const (
	SkCommandGetFirmwareVersion   SkCommand = "FV"  // Get Firmware Version
	SkCommandGetModelNumber       SkCommand = "MN"  // Get Model Name
	SkCommandGetStatus            SkCommand = "ST"  // Get Device Status
	SkCommandSetRemoteOn          SkCommand = "RT1" // Set Remote Mode On
	SkCommandSetRemoteOff         SkCommand = "RT0" // Set Remote Mode Off
	SkCommandSetFov               SkCommand = "AGw" // Set Field of View
	SkCommandSetMeasuringMode     SkCommand = "MMw" // Set Measuring Mode
	SkCommandSetExposureTime      SkCommand = "AMw" // Set Exposure Time
	SkCommandSetShutterSpeed      SkCommand = "SSw" // Set Shutter Speed
	SkCommandStartMeasuring       SkCommand = "RM0" // Start Measuring
	SkCommandGetMeasurementResult SkCommand = "NR"  // Get Measurement Result
)

type SkDeviceStatus

type SkDeviceStatus int
const (
	SkDeviceStatusIdle SkDeviceStatus = iota
	SkDeviceStatusIdleOutMeas
	SkDeviceStatusBusyFlashStandby
	SkDeviceStatusBusyMeasuring
	SkDeviceStatusBusyInitializing
	SkDeviceStatusBusyDarkCalibration
	SkDeviceStatusErrorHw
)

type SkExposureTime

type SkExposureTime int
const (
	SkExposureTimeAuto    SkExposureTime = iota
	SkExposureTime100Msec                // 0.1 s
	SkExposureTime1Sec                   // 1 s
)

type SkFieldOfView

type SkFieldOfView int
const (
	SkFieldOfView2Deg  SkFieldOfView = iota // 2°
	SkFieldOfView10Deg                      // 10°
)

type SkMeasuringMethod

type SkMeasuringMethod int
const (
	SkMeasuringMethodSingle SkMeasuringMethod = iota
	SkMeasuringMethodContinuous
)

type SkMeasuringMode

type SkMeasuringMode int
const (
	SkMeasuringModeAmbient SkMeasuringMode = iota
	SkMeasuringModeCordlessFlash
	SkMeasuringModeCordFlash
)

type SkRemoteStatus

type SkRemoteStatus int
const (
	SkRemoteStatusOff SkRemoteStatus = iota
	SkRemoteStatusOn
)

type SkRingStatus

type SkRingStatus int
const (
	SkRingStatusUnpositioned SkRingStatus = iota
	SkRingStatusCal
	SkRingStatusLow
	SkRingStatusHigh
)

type SkShutterSpeed

type SkShutterSpeed string
const (
	SkShutterSpeed1Sec   SkShutterSpeed = "01" // 1 s
	SkShutterSpeed2Sec   SkShutterSpeed = "02" // 2 s
	SkShutterSpeed4Sec   SkShutterSpeed = "03" // 4 s
	SkShutterSpeed8Sec   SkShutterSpeed = "04" // 8 s
	SkShutterSpeed15Sec  SkShutterSpeed = "05" // 15 s
	SkShutterSpeed30Sec  SkShutterSpeed = "06" // 30 s
	SkShutterSpeed60Sec  SkShutterSpeed = "07" // 1/60 s
	SkShutterSpeed125Sec SkShutterSpeed = "08" // 1/125 s
	SkShutterSpeed250Sec SkShutterSpeed = "09" // 1/250 s
	SkShutterSpeed500Sec SkShutterSpeed = "10" // 1/500 s
)

type TristimulusValue

type TristimulusValue struct {
	X DecimalValue
	Y DecimalValue
	Z DecimalValue
}

TristimulusValue represents a tristimulus value in XYZ color space.

type UsbAdapter

UsbAdapter is an interface that used to abstract USB communication. It is used by SEKONIC Device handler to communicate with device. It is not intended to be used by end user exept of initial injecting as dependency to Device handler. It is not mandatory to make it thread safe, it is (hopefully) done by Device handler.

type UsbAdapterDescriber

type UsbAdapterDescriber interface {
	Manufacturer() (string, error) // Manufacturer must return device manufacturer name or empty string or an error.
	Product() (string, error)      // Product must return device product name or empty string or an error.
}

type UsbAdapterOpenerCloser

type UsbAdapterOpenerCloser interface {
	Open() error // Open must ensure that device is in correct state for communication or return an error.
	io.Closer    // Close must release all previously allocated resources.
}

type UsbAdapterReaderWriter

type UsbAdapterReaderWriter interface {
	io.Reader // Read must read raw binary data from device or an error.
	io.Writer // Write must ensure the raw binary data is correctly sent to device or return an error.
}

type ValueRange

type ValueRange int
const (
	RangeOk ValueRange = iota
	RangeUnder
	RangeOver
)

func (ValueRange) String

func (r ValueRange) String() string

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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