Skip to content

Commit

Permalink
feat: magsafe led control (#3)
Browse files Browse the repository at this point in the history
* Magsafe led control

* chore: fix lint errors

---------

Co-authored-by: exi <xx.git.exi@kot.ms>
Co-authored-by: Charlie Chiang <charlie_c_0129@outlook.com>
  • Loading branch information
3 people committed Jun 20, 2023
1 parent 9ff89a6 commit 8c74ab2
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 5 deletions.
22 changes: 18 additions & 4 deletions loop.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ func maintainLoopInner() bool {
logrus.Errorf("EnableCharging failed: %v", err)
return false
}
if batteryCharge, err := smcConn.GetBatteryCharge(); err == nil {
_ = smcConn.SetMagSafeCharging(batteryCharge < 100)
}
}
maintainedChargingInProgress = false
return true
Expand All @@ -87,8 +90,6 @@ func maintainLoopInner() bool {

printStatus(batteryCharge, lower, upper, isChargingEnabled, isPluggedIn, maintainedChargingInProgress)

// batteryCharge < upper - delta &&
// charging is disabled
if batteryCharge < lower && !isChargingEnabled {
logrus.Infof("battery charge %d%% is below %d%% (%d-%d) but charging is disabled, enabling charging",
batteryCharge,
Expand All @@ -101,11 +102,10 @@ func maintainLoopInner() bool {
logrus.Errorf("EnableCharging failed: %v", err)
return false
}
isChargingEnabled = true
maintainedChargingInProgress = true
}

// batteryCharge >= upper &&
// charging is enabled
if batteryCharge >= upper && isChargingEnabled {
logrus.Infof("battery charge %d%% reached %d%% but charging is enabled, disabling charging",
batteryCharge,
Expand All @@ -116,15 +116,29 @@ func maintainLoopInner() bool {
logrus.Errorf("DisableCharging failed: %v", err)
return false
}
isChargingEnabled = false
maintainedChargingInProgress = false
}

updateMagSafeLed(isChargingEnabled)

// batteryCharge >= upper - delta && batteryCharge < upper
// do nothing, keep as-is

return true
}

func updateMagSafeLed(isChargingEnabled bool) {
ledCharging, err := smcConn.IsMagSafeCharging()
if err != nil {
logrus.Errorf("IsMagSafeCharging failed: %v", err)
}

if isChargingEnabled != ledCharging {
_ = smcConn.SetMagSafeCharging(isChargingEnabled)
}
}

func printStatus(batteryCharge int, lower int, upper int, isChargingEnabled bool, isPluggedIn bool, maintainedChargingInProgress bool) {
logrus.Debugf("batteryCharge=%d, lower=%d, upper=%d, chargingEnabled=%t, isPluggedIn=%t, maintainedChargingInProgress=%t",
batteryCharge,
Expand Down
59 changes: 58 additions & 1 deletion smc/smc.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@ type Connection struct {
*gosmc.Connection
}

// MagSafeLedState is the state of the MagSafe LED.
type MagSafeLedState int

// Representation of MagSafeLedState.
const (
LedOff MagSafeLedState = 1
LedGreen MagSafeLedState = 3
LedOrange MagSafeLedState = 4
LedErrorOnce MagSafeLedState = 5
LedErrorPerm MagSafeLedState = 6
)

// New returns a new Connection.
func New() *Connection {
return &Connection{
Expand Down Expand Up @@ -76,6 +88,7 @@ func (c *Connection) IsChargingEnabled() (bool, error) {
func (c *Connection) EnableCharging() error {
logrus.Tracef("EnableCharging called")

// CHSC
err := c.Write("CH0B", []byte{0x0})
if err != nil {
return err
Expand Down Expand Up @@ -157,8 +170,52 @@ func (c *Connection) IsPluggedIn() (bool, error) {
return false, err
}

ret := len(v.Bytes) == 1 && v.Bytes[0] == 0x1
ret := len(v.Bytes) == 1 && int8(v.Bytes[0]) > 0
logrus.Tracef("IsPluggedIn returned %t", ret)

return ret, nil
}

// SetMagSafeLedState .
func (c *Connection) SetMagSafeLedState(state MagSafeLedState) error {
logrus.Tracef("SetMagSafeLedState(%v) called", state)

return c.Write("ACLC", []byte{byte(state)})
}

// GetMagSafeLedState .
func (c *Connection) GetMagSafeLedState() (MagSafeLedState, error) {
logrus.Tracef("GetMagSafeLedState called")

v, err := c.Read("ACLC")
if err != nil || len(v.Bytes) != 1 {
return LedOrange, err
}

rawState := MagSafeLedState(v.Bytes[0])
ret := LedOrange
switch rawState {
case LedOff, LedGreen, LedOrange, LedErrorOnce, LedErrorPerm:
ret = rawState
case 2:
ret = LedGreen
}
logrus.Tracef("GetMagSafeLedState returned %v", ret)
return ret, nil
}

// SetMagSafeCharging .
func (c *Connection) SetMagSafeCharging(charging bool) error {
state := LedGreen
if charging {
state = LedOrange
}
return c.SetMagSafeLedState(state)
}

// IsMagSafeCharging .
func (c *Connection) IsMagSafeCharging() (bool, error) {
state, err := c.GetMagSafeLedState()

return state != LedGreen, err
}

0 comments on commit 8c74ab2

Please sign in to comment.