screen -> machine stater

This commit is contained in:
cryptonote-social 2020-08-20 20:13:30 -07:00
parent 5a42c68d78
commit 0643c871f3
5 changed files with 69 additions and 64 deletions

View File

@ -30,7 +30,7 @@ var (
wallet = flag.String("wallet", "", "your wallet id. only specify this when establishing a new username, or specifying a 'secure' config change such as a change in donation amount")
)
func MultiMain(s ScreenStater, agent string) {
func MultiMain(s MachineStater, agent string) {
flag.Usage = func() {
fmt.Fprintf(flag.CommandLine.Output(), "==== %s %s ====\n", APPLICATION_NAME, VERSION_STRING)
fmt.Fprint(flag.CommandLine.Output(),
@ -116,7 +116,7 @@ func MultiMain(s ScreenStater, agent string) {
}
config := MinerConfig{
ScreenStater: s,
MachineStater: s,
Threads: *t,
Username: *uname,
RigID: *rigid,

View File

@ -12,13 +12,17 @@ import (
)
func main() {
csminer.MultiMain(GnomeScreenStater{}, "csminer "+csminer.VERSION_STRING+" (linux)")
csminer.MultiMain(GnomeMachineStater{}, "csminer "+csminer.VERSION_STRING+" (linux)")
}
type GnomeScreenStater struct {
type GnomeMachineStater struct {
}
func (s GnomeScreenStater) GetScreenStateChannel() (chan csminer.ScreenState, error) {
func (s GnomeMachineStater) GetMachineStateChannel(saver bool) (chan csminer.MachineState, error) {
ret := make(chan csminer.MachineState)
if !saver {
return ret, nil // return channel on which we never send updates
}
bus, err := dbus.ConnectSessionBus()
if err != nil {
crylog.Error("dbus connection failed")
@ -34,8 +38,6 @@ func (s GnomeScreenStater) GetScreenStateChannel() (chan csminer.ScreenState, er
dChan := make(chan *dbus.Message, 128)
bus.Eavesdrop(dChan)
ret := make(chan csminer.ScreenState)
go func() {
defer bus.Close()
for m := range dChan {
@ -47,11 +49,11 @@ func (s GnomeScreenStater) GetScreenStateChannel() (chan csminer.ScreenState, er
str := fmt.Sprintf("%v", m.Body[0])
if str == "true" {
crylog.Info("Gnome screensaver turned on")
ret <- csminer.ScreenState(csminer.SCREEN_IDLE)
ret <- csminer.MachineState(csminer.SCREEN_IDLE)
continue
} else if str == "false" {
crylog.Info("Gnome screensaver turned off")
ret <- csminer.ScreenState(csminer.SCREEN_ACTIVE)
ret <- csminer.MachineState(csminer.SCREEN_ACTIVE)
continue
}
}

View File

@ -17,23 +17,23 @@ import (
var ()
const (
// Valid screen states
// Valid machine state changes
SCREEN_IDLE = 0
SCREEN_ACTIVE = 1
BATTERY_POWER = 2
AC_POWER = 3
)
type ScreenState int
type MachineState int
type ScreenStater interface {
// Returns a channel that produces true when state changes from screen off to screen on,
// and false when it changes from on to off.
GetScreenStateChannel() (chan ScreenState, error)
type MachineStater interface {
// Returns a channel that produces events when screen state & power state of the machine
// changes.
GetMachineStateChannel(saver bool) (chan MachineState, error)
}
type MinerConfig struct {
ScreenStater ScreenStater
MachineStater MachineStater
Threads int
Username, RigID string
Wallet string
@ -97,19 +97,18 @@ func Mine(c *MinerConfig) error {
return errors.New("pool refused login")
}
if c.Saver {
ch, err := c.ScreenStater.GetScreenStateChannel()
if err != nil {
minerlib.ReportIdleScreenState(true)
crylog.Error("failed to get screen state monitor, screen state will be ignored")
} else {
// We assume the screen is active when the miner is started. This may
// not hold if someone is running the miner from an auto-start script?
go monitorScreenSaver(ch)
}
} else {
// We assume the screen is active when the miner is started. This may
// not hold if someone is running the miner from an auto-start script?
if !c.Saver {
minerlib.ReportIdleScreenState(true)
}
ch, err := c.MachineStater.GetMachineStateChannel(c.Saver)
if err != nil {
minerlib.ReportIdleScreenState(true)
crylog.Error("failed to machine state monitor, screen & battery state will be ignored")
} else {
go monitorMachineState(ch)
}
go printStatsPeriodically()
@ -226,7 +225,7 @@ func printStatsPeriodically() {
}
}
func monitorScreenSaver(ch chan ScreenState) {
func monitorMachineState(ch chan MachineState) {
for state := range ch {
switch state {
case SCREEN_IDLE:

View File

@ -3,7 +3,7 @@
package main
// main() for the osx version of csminer with OSX lock screen state polling.
// main() for the osx version of csminer with OSX lock screen & battery state polling.
import (
"context"
@ -14,31 +14,33 @@ import (
"time"
)
type OSXScreenStater struct {
type OSXMachineStater struct {
}
// The OSX implementation of the screen 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.
func (s OSXScreenStater) GetScreenStateChannel() (chan csminer.ScreenState, error) {
ret := make(chan csminer.ScreenState)
// 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.
func (s OSXMachineStater) GetMachineStateChannel(saver bool) (chan csminer.ScreenState, error) {
ret := make(chan csminer.MachineState)
go func() {
screenActive := true
batteryPower := false
for {
time.Sleep(time.Second * 5)
screenActiveNow, err := getScreenActiveState()
if err != nil {
crylog.Error("getScreenActiveState failed:", err)
continue
}
if screenActiveNow != screenActive {
screenActive = screenActiveNow
if screenActive {
ret <- csminer.ScreenState(csminer.SCREEN_ACTIVE)
} else {
ret <- csminer.ScreenState(csminer.SCREEN_IDLE)
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)
@ -50,9 +52,9 @@ func (s OSXScreenStater) GetScreenStateChannel() (chan csminer.ScreenState, erro
if batteryPower != batteryPowerNow {
batteryPower = batteryPowerNow
if batteryPower {
ret <- csminer.ScreenState(csminer.BATTERY_POWER)
ret <- csminer.MachineState(csminer.BATTERY_POWER)
} else {
ret <- csminer.ScreenState(csminer.AC_POWER)
ret <- csminer.MachineState(csminer.AC_POWER)
}
}
}
@ -107,5 +109,5 @@ func getBatteryPowerState() (bool, error) {
}
func main() {
csminer.MultiMain(OSXScreenStater{}, "csminer "+csminer.VERSION_STRING+" (osx)")
csminer.MultiMain(OSXMachineStater{}, "csminer "+csminer.VERSION_STRING+" (osx)")
}

View File

@ -2,7 +2,7 @@
// the license found in the LICENSE file.
package main
// main() for the Windows version of csminer with support for Windows locks screen monitoring.
// main() for the Windows version of csminer with support for Windows machine state monitoring.
import (
"syscall"
@ -15,17 +15,17 @@ import (
"golang.org/x/sys/windows"
)
type WinScreenStater struct {
type WinMachineStater struct {
lockedOnStartup bool
}
// We assume the screen is active when the miner is started. This may
// not hold if someone is running the miner from an auto-start script?
func (ss *WinScreenStater) GetScreenStateChannel() (chan csminer.ScreenState, error) {
ret := make(chan csminer.ScreenState)
func (ss *WinScreenStater) GetMachineStateChannel(saver bool) (chan csminer.MachineState, error) {
ret := make(chan csminer.MachineState)
chanMessages := make(chan session_notifications.Message, 100)
chanClose := make(chan int)
chanMessages := make(chan session_notifications.Message, 100)
go func() {
// TODO: Also monitor for ac vs battery power state
@ -43,14 +43,14 @@ func (ss *WinScreenStater) GetScreenStateChannel() (chan csminer.ScreenState, er
currentlyLocked = true
if !isIdle {
isIdle = true
ret <- csminer.ScreenState(csminer.SCREEN_IDLE)
ret <- csminer.MachineState(csminer.SCREEN_IDLE)
}
case session_notifications.WTS_SESSION_UNLOCK:
crylog.Info("win session unlocked")
currentlyLocked = false
if isIdle {
isIdle = false
ret <- csminer.ScreenState(csminer.SCREEN_ACTIVE)
ret <- csminer.MachineState(csminer.SCREEN_ACTIVE)
}
default:
}
@ -58,18 +58,18 @@ func (ss *WinScreenStater) GetScreenStateChannel() (chan csminer.ScreenState, er
close(m.ChanOk)
case <-time.After(10 * time.Second):
b, err := isBatteryPower()
if err != nil {
if err != nil {
crylog.Error("failed to get battery power state:", err)
} else {
if b != batteryPower {
if b {
crylog.Info("Detected battery power")
batteryPower = true
ret <- csminer.ScreenState(csminer.BATTERY_POWER)
ret <- csminer.MachineState(csminer.BATTERY_POWER)
} else {
crylog.Info("Detected AC power")
batteryPower = false
ret <- csminer.ScreenState(csminer.AC_POWER)
ret <- csminer.MachineState(csminer.AC_POWER)
}
}
}
@ -85,24 +85,26 @@ func (ss *WinScreenStater) GetScreenStateChannel() (chan csminer.ScreenState, er
if saver {
crylog.Info("Detected running screensaver")
isIdle = true
ret <- csminer.ScreenState(csminer.SCREEN_IDLE)
ret <- csminer.MachineState(csminer.SCREEN_IDLE)
} else {
crylog.Info("No longer detecting active screensaver")
isIdle = false
ret <- csminer.ScreenState(csminer.SCREEN_ACTIVE)
ret <- csminer.MachineState(csminer.SCREEN_ACTIVE)
}
}
}
}
crylog.Error("win screen stater loop exit")
crylog.Error("win machine stater loop exit")
}()
session_notifications.Subscribe(chanMessages, chanClose)
if saver {
session_notifications.Subscribe(chanMessages, chanClose)
}
return ret, nil
}
func main() {
ss := WinScreenStater{lockedOnStartup: false}
ss := WinMachineStater{lockedOnStartup: false}
csminer.MultiMain(&ss, "csminer "+csminer.VERSION_STRING+" (win)")
}