2019-10-02

thermal monitor plasmoid not working

As explained here, if you have a bug in the thermal monitor plasmoid, to fix it you can change main.qml in .local/share/plasma/plasmoids as following (updated 22 feb 2020, adding ": []" after "property var systemmonitorAvailableSources"):

/*
 * Copyright 2015  Martin Kotelnik
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
import QtQuick 2.2
import QtQuick.Layouts 1.1
import QtGraphicalEffects 1.0
import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.core 2.0 as PlasmaCore
import "../code/model-utils.js" as ModelUtils
import "../code/config-utils.js" as ConfigUtils

Item {
    id: main

    anchors.fill: parent

    property bool vertical: (plasmoid.formFactor == PlasmaCore.Types.Vertical)
    property bool planar: (plasmoid.formFactor == PlasmaCore.Types.Planar)

    property bool initialized: false

    // configuration
    property int temperatureUnit: plasmoid.configuration.temperatureUnit
    property string configuredResources: plasmoid.configuration.resources
    property int baseWarningTemperature: plasmoid.configuration.warningTemperature
    property int baseMeltdownTemperature: plasmoid.configuration.meltdownTemperature
    property int updateInterval: 1000 * plasmoid.configuration.updateInterval

    property int itemMargin: 5
    property double itemWidth:  0
    property double itemHeight: 0

    property color warningColor: Qt.tint(theme.textColor, '#60FF0000')
    property var textFontFamily: theme.defaultFont.family

    Plasmoid.preferredRepresentation: Plasmoid.fullRepresentation

    property double aliasFontSize: itemHeight * plasmoid.configuration.aliasFontSize * 0.01
    property double temperatureFontSize: itemHeight * plasmoid.configuration.temperatureFontSize * 0.01
    property double iconFontSize: itemHeight * plasmoid.configuration.iconFontSize * 0.01
    property double temperatureRightMargin: itemHeight * plasmoid.configuration.temperatureRightMargin * 0.01
    property double iconBottomMargin: itemHeight * plasmoid.configuration.iconBottomMargin * 0.01
    property bool enableLabelDropShadow: plasmoid.configuration.enableLabelDropShadow

    property var systemmonitorAvailableSources : []
    property var systemmonitorSourcesToAdd

    property int numberOfParts: temperatureModel.count

    property double parentWidth: parent !== null ? parent.width : 0
    property double parentHeight: parent !== null ? parent.height : 0

    property double widgetWidth: 0
    property double widgetHeight: 0

    Layout.preferredWidth: widgetWidth
    Layout.preferredHeight: widgetHeight

    property bool debugLogging: false

    function dbgprint(msg) {
        if (!debugLogging) {
            return
        }
        print('[thermalMonitor] ' + msg)
    }

    onParentWidthChanged: setWidgetSize()
    onParentHeightChanged: setWidgetSize()
    onNumberOfPartsChanged: setWidgetSize()

    function setWidgetSize() {
        if (!parentHeight) {
            return
        }
        var orientationVertical = false
        if (planar) {
            var contentItemWidth = parentHeight
            var contentWidth = numberOfParts * contentItemWidth + (numberOfParts-1) * itemMargin
            var restrictToWidth = contentWidth / parentWidth > 1
            itemWidth = restrictToWidth ? (parentWidth + itemMargin) / numberOfParts - itemMargin : contentItemWidth
        } else if (vertical) {
            orientationVertical = true
            itemWidth = parentWidth
        } else {
            itemWidth = parentHeight
        }
        itemHeight = itemWidth
        widgetWidth = orientationVertical ? itemWidth : numberOfParts * itemWidth + (numberOfParts-1) * itemMargin
        widgetHeight = orientationVertical ? numberOfParts * itemHeight + (numberOfParts-1) * itemMargin : itemHeight
    }

    FontLoader {
        source: '../fonts/fontawesome-webfont-4.3.0.ttf'
    }

    Image {
        id: noResourceIcon;

        anchors.centerIn: parent

        visible: temperatureModel.count === 0

        height: itemHeight
        width: height

        source: '../images/thermal-monitor.svg'
    }

    ListView {
        id: listView

        anchors.centerIn: parent
        width: widgetWidth
        height: widgetHeight

        orientation: !planar && vertical ? ListView.Vertical : ListView.Horizontal
        spacing: itemMargin

        model: temperatureModel

        delegate: TemperatureItem {}
    }

    /*
     *
     * One object has these properties: temperature, alias and other
     *
     */
    ListModel {
        id: temperatureModel
    }

    Component.onCompleted: {
        plasmoid.setAction('reloadSources', i18n('Reload Temperature Sources'), 'system-reboot');
        reloadAllSources()
        setWidgetSize()
    }

    onBaseWarningTemperatureChanged: {
        tryReloadSources()
    }

    onBaseMeltdownTemperatureChanged: {
        tryReloadSources()
    }

    onConfiguredResourcesChanged: {
        dbgprint('configured resources changed')
        tryReloadSources()
    }

    function tryReloadSources() {
        if (!initialized) {
            dbgprint('applet not initialized -> no reloading sources')
            return
        }
        reloadAllSources()
    }

    function getSystemmonitorAvailableSources() {
        if (!systemmonitorAvailableSources) {
            systemmonitorAvailableSources = systemmonitorDS.sources
        }
        return systemmonitorAvailableSources
    }

    function action_reloadSources() {
        reloadAllSources()
    }

    function reloadAllSources() {

        dbgprint('reloading all sources...')

        var resources = ConfigUtils.getResourcesObjectArray()

        temperatureModel.clear()

        if (!systemmonitorSourcesToAdd) {
            systemmonitorSourcesToAdd = []
        }

        if (systemmonitorDS.connectedSources === undefined) {
            systemmonitorDS.connectedSources = []
        }

        if (udisksDS.connectedSources === undefined) {
            udisksDS.connectedSources = []
        }

        if (nvidiaDS.connectedSources === undefined) {
            nvidiaDS.connectedSources = []
        }

        if (atiDS.connectedSources === undefined) {
            atiDS.connectedSources = []
        }

        systemmonitorSourcesToAdd.length = 0
        systemmonitorDS.connectedSources.length = 0
        udisksDS.connectedSources.length = 0
        udisksDS.cmdSourceBySourceName = {}
        nvidiaDS.connectedSources.length = 0
        atiDS.connectedSources.length = 0

        ModelUtils.initModels(resources, temperatureModel)

        for (var i = 0; i < temperatureModel.count; i++) {
            var tempObj = temperatureModel.get(i)
            var source = tempObj.sourceName

            if (source === 'group-of-sources') {

                dbgprint('adding group: ' + tempObj.alias)

                for (var childSource in tempObj.childSourceObjects) {

                    dbgprint('adding source (for group): ' + childSource)

                    addSourceToDs(childSource)

                }

            } else {

                addSourceToDs(source)

            }
        }

        ModelUtils.rebuildModelIndexByKey(temperatureModel)

        initialized = true

        dbgprint('reloadAllSources() DONE')
    }

    function addSourceToDs(source) {

        if (source.indexOf('udisks/') === 0) {

            var diskLabel = source.substring('udisks/'.length)
            var cmdSource = ModelUtils.getUdisksTemperatureCmd(diskLabel)
            udisksDS.cmdSourceBySourceName[cmdSource] = source

            dbgprint('adding source to udisksDS: ' + cmdSource)

            addToSourcesOfDatasource(udisksDS, cmdSource)

        } else if (source.indexOf('nvidia-') === 0 && nvidiaDS.connectedSources.length === 0) {

            dbgprint('adding source to nvidiaDS')

            addToSourcesOfDatasource(nvidiaDS, nvidiaDS.nvidiaSource)

        } else if (source.indexOf('aticonfig') === 0 && atiDS.connectedSources.length === 0) {

            dbgprint('adding source to atiDS')

            addToSourcesOfDatasource(atiDS, atiDS.atiSource)

        } else {

            dbgprint('adding source to systemmonitorDS: ' + source)

            if (getSystemmonitorAvailableSources().indexOf(source) > -1) {
                dbgprint('adding to connected')
                addToSourcesOfDatasource(systemmonitorDS, source)
            } else {
                dbgprint('adding to sta')
                systemmonitorSourcesToAdd.push(source)
            }

        }

    }

    function addToSourcesOfDatasource(datasource, sourceName) {
        if (datasource.connectedSources.indexOf(sourceName) > -1) {
            // already added
            dbgprint('source already added: ' + sourceName)
            return
        }
        datasource.connectedSources.push(sourceName)
    }

    PlasmaCore.DataSource {
        id: systemmonitorDS
        engine: 'systemmonitor'

        property string lmSensorsStart: 'lmsensors/'
        property string acpiStart: 'acpi/Thermal_Zone/'

        onSourceAdded: {

            if (source.indexOf(lmSensorsStart) === 0 || source.indexOf(acpiStart) === 0) {

                systemmonitorAvailableSources.push(source)
                var staIndex = systemmonitorSourcesToAdd.indexOf(source)
                if (staIndex > -1) {
                    addToSourcesOfDatasource(systemmonitorDS, source)
                    systemmonitorSourcesToAdd.splice(staIndex, 1)
                }

            }

        }

        onNewData: {
            var temperature = 0
            if (data.value === undefined) {
                dbgprint('data for source ' + sourceName + ' not yet available')
            } else {
                temperature = parseFloat(data.value)
            }
            ModelUtils.updateTemperatureModel(temperatureModel, sourceName, temperature)
        }
        interval: updateInterval
    }

    PlasmaCore.DataSource {
        id: udisksDS
        engine: 'executable'

        property var cmdSourceBySourceName

        onNewData: {

            dbgprint('udisks new data - valid: ' + valid + ', stdout: ' + data.stdout)

            var temperature = 0
            if (data['exit code'] > 0) {
                dbgprint('new data error: ' + data.stderr)
            } else {
                temperature = ModelUtils.getCelsiaFromUdisksStdout(data.stdout)
            }

            ModelUtils.updateTemperatureModel(temperatureModel, cmdSourceBySourceName[sourceName], temperature)
        }
        interval: updateInterval
    }

    PlasmaCore.DataSource {
        id: nvidiaDS
        engine: 'executable'

        property string nvidiaSource: 'nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader'

        onNewData: {
            var temperature = 0
            if (data['exit code'] > 0) {
                dbgprint('new data error: ' + data.stderr)
            } else {
                temperature = parseFloat(data.stdout)
            }

            ModelUtils.updateTemperatureModel(temperatureModel, 'nvidia-smi', temperature)
        }
        interval: updateInterval
    }

    PlasmaCore.DataSource {
        id: atiDS
        engine: 'executable'

        property string atiSource: 'aticonfig --od-gettemperature | tail -1 | cut -c 43-44'

        onNewData: {
            var temperature = 0
            if (data['exit code'] > 0) {
                dbgprint('new data error: ' + data.stderr)
            } else {
                temperature = parseFloat(data.stdout)
            }

            ModelUtils.updateTemperatureModel(temperatureModel, 'aticonfig', temperature)
        }
        interval: updateInterval
    }

    Timer {
        interval: updateInterval
        repeat: true
        running: true
        onTriggered: {
            ModelUtils.computeVirtuals(temperatureModel)
        }
    }

}

No comments:

Post a Comment

Blog Archive