From c00b6ba4749ae3eb6e8a82cb5fad6b8c1d238627 Mon Sep 17 00:00:00 2001 From: parMaster Date: Sun, 5 Nov 2023 15:10:57 +0200 Subject: [PATCH] SMC768 module, chart, view --- config/config.yml | 2 ++ mod-smc768.go | 19 ++++++++++------ web/chart.html | 39 +++++++++++++++++++++++++++++++ web/view.html | 58 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 111 insertions(+), 7 deletions(-) diff --git a/config/config.yml b/config/config.yml index 2367bc7..b4277b1 100755 --- a/config/config.yml +++ b/config/config.yml @@ -20,3 +20,5 @@ modules: addr: 0x40 system: enabled: true +# smc768: # for Macmini 2014 with SMC768 +# enabled: true \ No newline at end of file diff --git a/mod-smc768.go b/mod-smc768.go index f35c95a..0700207 100644 --- a/mod-smc768.go +++ b/mod-smc768.go @@ -32,7 +32,9 @@ var Sensors = []string{ "ThrottleTime", // Core throttle time in milliseconds } -type Smc768Response map[string]string +type Smc768Data map[string]string + +type Smc768Response map[string][]string type Smc768Reporter struct { data Smc768Response @@ -53,7 +55,7 @@ func LoadSmc768Reporter(cfg config.Smc768, store storage.Storer, dbg bool) (*Smc return &Smc768Reporter{ dbg: dbg, store: store, - data: make(map[string]string), + data: make(Smc768Response), }, nil } @@ -65,14 +67,14 @@ func (r *Smc768Reporter) Collect(ctx context.Context) (err error) { r.mx.Lock() defer r.mx.Unlock() - r.data = r.ReadSMC768() + data := r.ReadSMC768() if err != nil { return errors.Join(err, fmt.Errorf("failed to get load avg: %v", err)) } if r.store != nil { for _, label := range Sensors { - err := r.store.Write(ctx, model.Data{Module: r.Name(), Topic: label, Value: r.data[label]}) + err := r.store.Write(ctx, model.Data{Module: r.Name(), Topic: label, Value: data[label]}) if err != nil { return errors.Join(err, fmt.Errorf("failed to write to storage: %v", err)) } @@ -87,9 +89,9 @@ func (r *Smc768Reporter) Report() (interface{}, error) { return r.data, nil } -func (r *Smc768Reporter) ReadSMC768() Smc768Response { +func (r *Smc768Reporter) ReadSMC768() Smc768Data { - data := make(Smc768Response) + data := make(Smc768Data) // Read the data from the SMC768 and store it in the data map for i := 1; i <= 60; i++ { @@ -97,11 +99,14 @@ func (r *Smc768Reporter) ReadSMC768() Smc768Response { label := ReadInput(fmt.Sprintf("/sys/devices/platform/applesmc.768/temp%d_label", i)) if slices.Contains(Sensors, label) { data[label] = value + r.data[label] = append(r.data[label], value) } } data["Exhaust"] = ReadInput("/sys/devices/platform/applesmc.768/fan1_input") + r.data["Exhaust"] = append(r.data["Exhaust"], data["Exhaust"]) data["ThrottleTime"] = ReadInput("/sys/devices/system/cpu/cpu0/thermal_throttle/core_throttle_total_time_ms") + r.data["ThrottleTime"] = append(r.data["ThrottleTime"], data["ThrottleTime"]) if r.dbg { log.Printf("[DEBUG] Smc768Reporter: data:") @@ -120,7 +125,7 @@ func ReadInput(file string) (v string) { fmt.Println(err) } - v = strings.TrimSpace(string(value)) + v = strings.Trim(strings.TrimSpace(string(value)), "\n") return } diff --git a/web/chart.html b/web/chart.html index 501a01a..213df68 100755 --- a/web/chart.html +++ b/web/chart.html @@ -20,6 +20,7 @@
+
Dark/Light @@ -207,6 +208,44 @@ Plotly.newPlot('TimeInState', [TimeInState], TISlayout); } + // check if there is object with name "Modules" and if it has "bmp280" and "htu21" keys + if (data["Modules"] && data["Modules"]["smc768"] + && data["Modules"]["smc768"]["TC0C"] + && data["Modules"]["smc768"]["Exhaust"] ) { + + var cpu_temp = { + x: data["Dates"], + y: data["Modules"]["smc768"]["TC0C"], + type: 'scatter', + name: 'CPU core Temp, m˚C' + }; + var fan_rpm = { + x: data["Dates"], + y: data["Modules"]["smc768"]["Exhaust"], + type: 'scatter', + name: 'Fan RPM', + yaxis: 'y2', + }; + + var Layout = { + yaxis: { + title: 'CPU core Temp, m˚C', + gridcolor: 'rgba(99, 110, 250, 0.2)' + }, + yaxis2: { + title: 'Fan RPM', + overlaying: 'y', + side: 'right', + gridcolor: 'rgba(239, 85, 59, 0.2)' + }, + margin: {"t": 32, "b": 0, "l": 0, "r": 0}, + height: 400, + template: template + } + + Plotly.newPlot('Smc768Chart', [cpu_temp, fan_rpm], Layout); + } + tempDiv.on('plotly_relayout', function(eventdata){ Plotly.relayout(loadDiv, eventdata); Plotly.relayout('AmbTempChart', eventdata); diff --git a/web/view.html b/web/view.html index 58815a4..9906b41 100755 --- a/web/view.html +++ b/web/view.html @@ -18,6 +18,7 @@
+
Dark/Light @@ -103,6 +104,62 @@ Plotly.newPlot('main', plots, MainLayout); } +async function loadSmc768() { + let data = await getData("smc768"); + + // check if there temp data + if (data == null || data["TC0C"] == null) { + return; + } + + for (var key in data["TC0C"]) { + data["TC0C"][key] = parseInt(data["TC0C"][key]); + } + + var temp = { + x: Object.keys(data["TC0C"]), + y: Object.values(data["TC0C"]), + type: 'scatter', + name: 'CPU, m˚C' + }; + + var Layout = { + yaxis: { + title: 'CPU, m˚C', + gridcolor: 'rgba(99, 110, 250, 0.2)' + }, + margin: {"t": 32, "b": 0, "l": 0, "r": 0}, + height: 400, + template: template + } + plots = [temp]; + + // check if there rpm data + if (data["Exhaust"] != null) { + + for (var key in data["Exhaust"]) { + data["Exhaust"][key] = parseInt(data["Exhaust"][key]); + } + + var rpm = { + x: Object.keys(data["Exhaust"]), + y: Object.values(data["Exhaust"]), + type: 'scatter', + name: 'Fan RPM', + yaxis: 'y2', + }; + Layout.yaxis2 = { + title: 'Fan RPM', + overlaying: 'y', + side: 'right', + gridcolor: 'rgba(239, 85, 59, 0.2)', + showgrid: false, + } + plots.push(rpm); + } + Plotly.newPlot('smc768', plots, Layout); +} + async function loadLa5m() { let data = await getData("system"); @@ -180,6 +237,7 @@ await loadMain(); await loadLa5m(); await loadBMP280(); + await loadSmc768(); var mainDiv = document.getElementById('main'); var la5mDiv = document.getElementById('la5m');