csminer/osx/csminer.go

114 lines
2.9 KiB
Go
Raw Permalink Normal View History

2020-06-20 01:21:08 +03:00
// Copyright 2020 cryptonote.social. All rights reserved. Use of this source code is governed by
// the license found in the LICENSE file.
package main
2020-08-21 06:13:30 +03:00
// main() for the osx version of csminer with OSX lock screen & battery state polling.
2020-06-20 01:21:08 +03:00
import (
"context"
"github.com/cryptonote-social/csminer"
"github.com/cryptonote-social/csminer/crylog"
2020-06-20 01:21:08 +03:00
"os/exec"
"strings"
"time"
)
2020-08-21 06:13:30 +03:00
type OSXMachineStater struct {
2020-06-20 01:21:08 +03:00
}
2020-08-21 06:13:30 +03:00
// The OSX implementation of the screen & batter state notification channel is based on polling the
// state every 10 seconds. It would be better to figure out how to get notified of state changes
// when they happen.
2020-08-21 06:42:42 +03:00
func (s OSXMachineStater) GetMachineStateChannel(saver bool) (chan csminer.MachineState, error) {
2020-08-21 06:13:30 +03:00
ret := make(chan csminer.MachineState)
2020-06-20 01:21:08 +03:00
go func() {
screenActive := true
batteryPower := false
2020-06-20 01:21:08 +03:00
for {
time.Sleep(time.Second * 5)
2020-08-21 06:13:30 +03:00
if saver {
screenActiveNow, err := getScreenActiveState()
if err != nil {
crylog.Error("getScreenActiveState failed:", err)
continue
}
if screenActiveNow != screenActive {
screenActive = screenActiveNow
if screenActive {
ret <- csminer.MachineState(csminer.SCREEN_ACTIVE)
} else {
ret <- csminer.MachineState(csminer.SCREEN_IDLE)
}
}
}
time.Sleep(time.Second * 5)
batteryPowerNow, err := getBatteryPowerState()
if err != nil {
crylog.Error("getBatteryPowerState failed:", err)
continue
}
if batteryPower != batteryPowerNow {
batteryPower = batteryPowerNow
if batteryPower {
2020-08-21 06:13:30 +03:00
ret <- csminer.MachineState(csminer.BATTERY_POWER)
} else {
2020-08-21 06:13:30 +03:00
ret <- csminer.MachineState(csminer.AC_POWER)
}
2020-06-20 01:21:08 +03:00
}
}
}()
return ret, nil
}
// getScreenActiveState gets the OSX lockscreen status. Current implementation
// invokes a python script; this should be improved.
func getScreenActiveState() (bool, error) {
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
2020-06-20 01:21:08 +03:00
defer cancel()
cmd := exec.CommandContext(
ctx,
"python",
"-c",
"import sys,Quartz; d=Quartz.CGSessionCopyCurrentDictionary(); print d",
)
b, err := cmd.CombinedOutput()
if err != nil {
crylog.Error("Error in cmd.CombinedOutput:", err)
return false, err
}
if strings.Contains(string(b), "CGSSessionScreenIsLocked = 1") {
return false, nil
}
return true, nil
}
// getBatteryPowerState returns true if the machine is running on battery power.
// Current implementation invokes "pmset -g ps"
func getBatteryPowerState() (bool, error) {
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
cmd := exec.CommandContext(
ctx,
"pmset",
"-g",
"ps",
)
b, err := cmd.CombinedOutput()
if err != nil {
crylog.Error("Error in cmd.CombinedOutput:", err)
return false, err
}
if strings.Contains(string(b), "Battery Power") {
return true, nil
}
return false, nil
}
2020-06-20 01:21:08 +03:00
func main() {
2020-08-21 06:13:30 +03:00
csminer.MultiMain(OSXMachineStater{}, "csminer "+csminer.VERSION_STRING+" (osx)")
2020-06-20 01:21:08 +03:00
}