github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/plugins/cpuspeed/actor.go (about) 1 // This file is part of the Smart Home 2 // Program complex distribution https://github.com/e154/smart-home 3 // Copyright (C) 2016-2023, Filippov Alex 4 // 5 // This library is free software: you can redistribute it and/or 6 // modify it under the terms of the GNU Lesser General Public 7 // License as published by the Free Software Foundation; either 8 // version 3 of the License, or (at your option) any later version. 9 // 10 // This library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 // Library General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public 16 // License along with this library. If not, see 17 // <https://www.gnu.org/licenses/>. 18 19 package cpuspeed 20 21 import ( 22 "sync" 23 24 "github.com/rcrowley/go-metrics" 25 "github.com/shirou/gopsutil/v3/cpu" 26 27 "github.com/e154/smart-home/common" 28 m "github.com/e154/smart-home/models" 29 "github.com/e154/smart-home/system/supervisor" 30 ) 31 32 // Actor ... 33 type Actor struct { 34 *supervisor.BaseActor 35 cores int64 36 model string 37 mhz float64 38 all metrics.GaugeFloat64 39 loadMin metrics.GaugeFloat64 40 loadMax metrics.GaugeFloat64 41 allCpuPrevTotal float64 42 allCpuPrevIdle float64 43 updateLock *sync.Mutex 44 } 45 46 // NewActor ... 47 func NewActor(entity *m.Entity, 48 service supervisor.Service) *Actor { 49 50 actor := &Actor{ 51 BaseActor: supervisor.NewBaseActor(entity, service), 52 all: metrics.NewGaugeFloat64(), 53 loadMin: metrics.NewGaugeFloat64(), 54 loadMax: metrics.NewGaugeFloat64(), 55 updateLock: &sync.Mutex{}, 56 } 57 58 cpuInfo, err := cpu.Info() 59 if err == nil { 60 actor.mhz = cpuInfo[0].Mhz 61 actor.cores = int64(cpuInfo[0].Cores) 62 actor.model = cpuInfo[0].Model 63 } 64 65 if entity != nil { 66 actor.Metric = entity.Metrics 67 } 68 69 return actor 70 } 71 72 func (e *Actor) Destroy() { 73 74 } 75 76 func (e *Actor) selfUpdate() { 77 78 e.updateLock.Lock() 79 defer e.updateLock.Unlock() 80 81 // export CGO_ENABLED=1 82 timeStats, err := cpu.Times(false) 83 if err != nil { 84 return 85 } 86 if len(timeStats) == 0 { 87 return 88 } 89 90 total := timeStats[0].Total() 91 diffIdle := timeStats[0].Idle - e.allCpuPrevIdle 92 diffTotal := total - e.allCpuPrevTotal 93 all := common.Rounding(100*(diffTotal-diffIdle)/diffTotal, 2) 94 if v := e.loadMin.Value(); v == 0 || all < v { 95 e.loadMin.Update(all) 96 } 97 if v := e.loadMax.Value(); v == 0 || all > v { 98 e.loadMax.Update(all) 99 } 100 101 e.all.Update(all) 102 e.allCpuPrevTotal = total 103 e.allCpuPrevIdle = timeStats[0].Idle 104 105 e.AttrMu.Lock() 106 e.Attrs[AttrCpuCores].Value = e.cores 107 e.Attrs[AttrCpuMhz].Value = e.mhz 108 e.Attrs[AttrCpuAll].Value = e.all.Value() 109 e.Attrs[AttrLoadMax].Value = e.loadMax.Value() 110 e.Attrs[AttrLoadMin].Value = e.loadMin.Value() 111 e.AttrMu.Unlock() 112 113 //e.SetMetric(e.Id, "cpuspeed", map[string]float32{ 114 // "all": common.Rounding32(e.all.Value(), 2), 115 //}) 116 117 e.SaveState(false, false) 118 }