package mk2driver import "time" type Led int const ( LedMain Led = iota LedAbsorption LedBulk LedFloat LedInverter LedOverload LedLowBattery LedTemperature ) var LedNames = map[Led]string{ LedTemperature: "led_over_temp", LedLowBattery: "led_bat_low", LedOverload: "led_overload", LedInverter: "led_inverter", LedFloat: "led_float", LedBulk: "led_bulk", LedAbsorption: "led_absorb", LedMain: "led_mains", } type LEDstate int const ( LedOff LEDstate = iota LedOn LedBlink ) var StateNames = map[LEDstate]string{ LedOff: "off", LedOn: "on", LedBlink: "blink", } type Mk2Info struct { // Will be marked as false if an error is detected. Valid bool Version uint32 BatVoltage float64 // Positive current == charging // Negative current == discharging BatCurrent float64 // Input AC parameters InVoltage float64 InCurrent float64 InFrequency float64 // Output AC parameters OutVoltage float64 OutCurrent float64 OutFrequency float64 // Charge state 0.0 to 1.0 ChargeState float64 // List LEDs LEDs map[Led]LEDstate Errors []error Timestamp time.Time } type Mk2 interface { C() chan *Mk2Info Close() } type PanelSwitchState byte const ( // PanelSwitchChargerOnly enables charging only. PanelSwitchChargerOnly PanelSwitchState = 0x01 // PanelSwitchInverterOnly enables inverter output and disables charging. PanelSwitchInverterOnly PanelSwitchState = 0x02 // PanelSwitchOn enables both inverter and charger. PanelSwitchOn PanelSwitchState = 0x03 // PanelSwitchOff disables inverter and charger. PanelSwitchOff PanelSwitchState = 0x04 ) type SettingsWriter interface { // WriteRAMVar writes a signed 16-bit value to a RAM variable id. WriteRAMVar(id uint16, value int16) error // WriteSetting writes a signed 16-bit value to a setting id. WriteSetting(id uint16, value int16) error // SetPanelState sends the MK2 "S" command using a virtual panel switch state. // If currentLimitA is nil, the command does not update the AC current limit. SetPanelState(switchState PanelSwitchState, currentLimitA *float64) error // SetStandby configures the remote panel standby line. // When enabled, the inverter is prevented from sleeping while switched off. SetStandby(enabled bool) error } type DeviceState byte const ( // DeviceStateChargerOnly enables charging only. DeviceStateChargerOnly DeviceState = 0x02 // DeviceStateInverterOnly enables inverter output and disables charging. DeviceStateInverterOnly DeviceState = 0x03 // DeviceStateOn enables both inverter and charger. DeviceStateOn DeviceState = 0x04 // DeviceStateOff disables inverter and charger. DeviceStateOff DeviceState = 0x05 ) var DeviceStateNames = map[DeviceState]string{ DeviceStateChargerOnly: "charger_only", DeviceStateInverterOnly: "inverter_only", DeviceStateOn: "on", DeviceStateOff: "off", } type RAMVarInfo struct { ID uint16 Scale int16 Offset int16 Factor float64 Signed bool Supported bool } // ProtocolControl exposes protocol 3.14 command paths for direct MK2 control. type ProtocolControl interface { SettingsWriter // GetDeviceState returns the current VE.Bus state using command 0x0E. GetDeviceState() (DeviceState, error) // SetDeviceState sets the VE.Bus state using command 0x0E. SetDeviceState(state DeviceState) error // ReadRAMVarByID reads a RAM variable via command 0x30. ReadRAMVarByID(id uint16) (int16, error) // ReadSettingByID reads a setting via command 0x31. ReadSettingByID(id uint16) (int16, error) // SelectRAMVar selects a RAM variable for follow-up read-selected/write-selected paths. SelectRAMVar(id uint16) error // SelectSetting selects a setting for follow-up read-selected/write-selected paths. SelectSetting(id uint16) error // ReadSelected reads the currently selected value via command 0x35. ReadSelected() (int16, error) // ReadRAMVarInfo reads RAM variable metadata via command 0x36. ReadRAMVarInfo(id uint16) (RAMVarInfo, error) // WriteSelectedData writes to the currently selected register via command 0x34. WriteSelectedData(value int16) error // WriteSettingBySelection performs 0x33 (select setting) followed by 0x34 (write data). WriteSettingBySelection(id uint16, value int16) error // WriteRAMVarBySelection performs 0x32 (select RAM var) followed by 0x34 (write data). WriteRAMVarBySelection(id uint16, value int16) error // WriteSettingByID writes a setting via command 0x37. WriteSettingByID(id uint16, value int16) error // WriteRAMVarByID writes a RAM variable via command 0x38. WriteRAMVarByID(id uint16, value int16) error } type RegisterKind string const ( RegisterKindSetting RegisterKind = "setting" RegisterKindRAMVar RegisterKind = "ram_var" ) type RegisterSafetyClass string const ( // RegisterSafetyReadOnly indicates no write path should be exposed. RegisterSafetyReadOnly RegisterSafetyClass = "read_only" // RegisterSafetyOperational indicates normal runtime write usage is expected. RegisterSafetyOperational RegisterSafetyClass = "operational" // RegisterSafetyGuarded indicates writes should be policy-guarded. RegisterSafetyGuarded RegisterSafetyClass = "guarded" // RegisterSafetyCritical indicates high-impact settings that need stricter controls. RegisterSafetyCritical RegisterSafetyClass = "critical" ) type TimeoutClass string const ( TimeoutClassFast TimeoutClass = "fast" TimeoutClassStandard TimeoutClass = "standard" TimeoutClassSlow TimeoutClass = "slow" ) // RegisterMetadata documents known MK2 register IDs and expected value behavior. type RegisterMetadata struct { Kind RegisterKind ID uint16 Name string Description string Unit string Scale float64 Writable bool Signed bool MinValue *int16 MaxValue *int16 SafetyClass RegisterSafetyClass } // TransactionOptions controls retry and verification semantics for safe writes. type TransactionOptions struct { // Retries is the number of additional write attempts after the first try. Retries int // RetryDelay is slept between retries. Zero uses a sensible default. RetryDelay time.Duration // BackoffFactor multiplies retry delay for each additional attempt (1 disables backoff). BackoffFactor float64 // ReadBeforeWrite captures previous value before writing when possible. ReadBeforeWrite bool // VerifyAfterWrite reads the register back and compares with written value. VerifyAfterWrite bool // TimeoutClass applies standard timeout buckets when CommandTimeout is not set. TimeoutClass TimeoutClass // CommandTimeout overrides timeout class for each protocol command inside the transaction. CommandTimeout time.Duration } // RegisterTransactionResult reports details about a transactional register write. type RegisterTransactionResult struct { Kind RegisterKind ID uint16 TargetValue int16 PreviousValue *int16 VerifiedValue *int16 Attempts int Timeout time.Duration Duration time.Duration } // MetadataControl adds register metadata and transactional safety helpers. type MetadataControl interface { ProtocolControl // RegisterMetadata returns metadata for a known register. RegisterMetadata(kind RegisterKind, id uint16) (RegisterMetadata, bool) // ListRegisterMetadata returns all known register metadata. ListRegisterMetadata() []RegisterMetadata // ReadRegister reads a setting or RAM var by kind and id. ReadRegister(kind RegisterKind, id uint16) (int16, error) // WriteRegister performs a safe transactional write with optional retry/verify. WriteRegister(kind RegisterKind, id uint16, value int16, opts TransactionOptions) (RegisterTransactionResult, error) } type RegisterAddress struct { Kind RegisterKind `json:"kind"` ID uint16 `json:"id"` } type RegisterSnapshotEntry struct { Kind RegisterKind `json:"kind"` ID uint16 `json:"id"` Name string `json:"name,omitempty"` Value int16 `json:"value"` Writable bool `json:"writable"` Safety RegisterSafetyClass `json:"safety_class,omitempty"` CapturedAt time.Time `json:"captured_at"` } type RegisterSnapshot struct { CapturedAt time.Time `json:"captured_at"` Entries []RegisterSnapshotEntry `json:"entries"` } type SnapshotDiff struct { Kind RegisterKind `json:"kind"` ID uint16 `json:"id"` Name string `json:"name,omitempty"` Current int16 `json:"current"` Target int16 `json:"target"` Changed bool `json:"changed"` Writable bool `json:"writable"` Safety RegisterSafetyClass `json:"safety_class,omitempty"` DiffValue int32 `json:"diff_value"` } type SnapshotRestoreResult struct { Applied []RegisterTransactionResult `json:"applied"` RolledBack bool `json:"rolled_back"` RollbackErrors []string `json:"rollback_errors,omitempty"` } // SnapshotControl provides register snapshot, diff preview, and rollback-aware restore. type SnapshotControl interface { MetadataControl // CaptureSnapshot reads the provided register list. Empty addresses captures known writable registers. CaptureSnapshot(addresses []RegisterAddress) (RegisterSnapshot, error) // DiffSnapshot compares current values against a snapshot. DiffSnapshot(snapshot RegisterSnapshot) ([]SnapshotDiff, error) // RestoreSnapshot applies snapshot target values; if restore fails mid-way it attempts rollback. RestoreSnapshot(snapshot RegisterSnapshot, opts TransactionOptions) (SnapshotRestoreResult, error) } type TraceDirection string const ( TraceDirectionTX TraceDirection = "tx" TraceDirectionRX TraceDirection = "rx" ) type ProtocolTrace struct { Timestamp time.Time `json:"timestamp"` Direction TraceDirection `json:"direction"` Frame string `json:"frame"` Command string `json:"command,omitempty"` BytesHex string `json:"bytes_hex"` } type DriverDiagnostics struct { GeneratedAt time.Time `json:"generated_at"` HealthScore int `json:"health_score"` LastFrameAt *time.Time `json:"last_frame_at,omitempty"` CommandTimeouts uint64 `json:"command_timeouts"` CommandFailures uint64 `json:"command_failures"` ChecksumFailures uint64 `json:"checksum_failures"` RecentErrors []string `json:"recent_errors,omitempty"` Traces []ProtocolTrace `json:"traces"` } // DiagnosticsControl exposes recent protocol traces and health information for troubleshooting bundles. type DiagnosticsControl interface { DriverDiagnostics(limit int) DriverDiagnostics } type CommandSource string const ( CommandSourceUnknown CommandSource = "unknown" CommandSourceUI CommandSource = "ui" CommandSourceMQTT CommandSource = "mqtt" CommandSourceAutomation CommandSource = "automation" ) // SourceAwareSettingsWriter accepts source tags for arbitration and diagnostics. type SourceAwareSettingsWriter interface { SettingsWriter WriteRAMVarWithSource(source CommandSource, id uint16, value int16) error WriteSettingWithSource(source CommandSource, id uint16, value int16) error SetPanelStateWithSource(source CommandSource, switchState PanelSwitchState, currentLimitA *float64) error SetStandbyWithSource(source CommandSource, enabled bool) error } type CommandHistoryProvider interface { History(limit int) []CommandEvent }