/* * Copyright 2016-2018 Javier Garcia Alonso. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.profesorfalken.jsensors.manager.unix; import com.profesorfalken.jsensors.manager.unix.jna.CSubFeature; import com.profesorfalken.jsensors.manager.unix.jna.CChip; import com.profesorfalken.jsensors.manager.unix.jna.CFeature; import com.profesorfalken.jsensors.manager.unix.jna.CSensors; import com.profesorfalken.jsensors.manager.SensorsManager; import com.profesorfalken.jsensors.util.SensorsUtils; import com.sun.jna.Native; import com.sun.jna.ptr.DoubleByReference; import com.sun.jna.ptr.IntByReference; import java.io.File; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Linux implementation of SensorManager that gets the sensors using JNA and * parses it into a normalized format. * * @author Javier Garcia Alonso */ public class UnixSensorsManager extends SensorsManager { private static final Logger LOGGER = LoggerFactory.getLogger(UnixSensorsManager.class); private static final String LINE_BREAK = "\n"; private final StringBuilder sensorsData = new StringBuilder(); private final StringBuilder sensorsDebugData = new StringBuilder(); @Override public String getSensorsData() { CSensors cSensors = loadDynamicLibrary(); if (cSensors == null) { LOGGER.error("Could not load sensors dynamic library"); return ""; } int init = initCSensors(cSensors); if (init != 0) { LOGGER.error("Cannot initialize sensors"); return ""; } String normalizedData = ""; try { normalizedData = normalizeSensorsData(cSensors); } finally { cSensors.sensors_cleanup(); } return normalizedData; } private CSensors loadDynamicLibrary() { Object jnaProxy; try { jnaProxy = Native.loadLibrary("sensors", CSensors.class); } catch (UnsatisfiedLinkError err) { LOGGER.info("Cannot find library in system, using embedded one"); try { String libPath = SensorsUtils.generateLibTmpPath("/lib/linux/", "libsensors.so.4.4.0"); jnaProxy = Native.loadLibrary(libPath, CSensors.class); new File(libPath).delete(); } catch (UnsatisfiedLinkError err1) { jnaProxy = null; LOGGER.error("Cannot load sensors dinamic library", err1); } } return (CSensors) jnaProxy; } private static int initCSensors(CSensors cSensors) { return cSensors.sensors_init(null); } private void addData(String data) { addData(data, true); } private void addData(String data, boolean newLine) { String endLine = newLine ? LINE_BREAK : ""; sensorsData.append(data).append(endLine); sensorsDebugData.append(data).append(endLine); } private void addDebugData(String debugData) { sensorsDebugData.append(debugData).append(LINE_BREAK); } private String normalizeSensorsData(CSensors cSensors) { List<CChip> chips = detectedChips(cSensors); for (final CChip chip : chips) { addData("[COMPONENT]"); addDebugData(String.format("Type: %d", chip.bus.type)); addDebugData(String.format("Address: %d", chip.addr)); addDebugData(String.format("Path: %s", chip.path)); addDebugData(String.format("Prefix: %s", chip.prefix)); if (chip.bus != null) { switch (chip.bus.type) { case 1: addData("CPU"); break; case 2: addData("GPU"); break; case 4: case 5: addData("DISK"); break; default: addData("UNKNOWN"); } } addData(String.format("Label: %s", cSensors.sensors_get_adapter_name(chip.bus))); List<CFeature> features = features(cSensors, chip); addFeatures(cSensors, chip, features); } if (debugMode) { LOGGER.info(sensorsDebugData.toString()); } return sensorsData.toString(); } private void addFeatures(CSensors cSensors, CChip chip, List<CFeature> features) { for (final CFeature feature : features) { addDebugData(String.format("Feature type: %d", feature.type)); addDebugData(String.format("Feature name: %s", feature.name)); addDebugData(String.format("Feature label: %s", cSensors.sensors_get_label(chip, feature))); if (feature.name.startsWith("temp")) { addData(String.format("Temp %s:", cSensors.sensors_get_label(chip, feature)), false); } else if (feature.name.startsWith("fan")) { addData(String.format("Fan %s:", cSensors.sensors_get_label(chip, feature)), false); } List<CSubFeature> subFeatures = subFeatures(cSensors, chip, feature); addSubFeatures(cSensors, chip, subFeatures); } } private void addSubFeatures(CSensors cSensors, CChip chip, List<CSubFeature> subFeatures) { for (final CSubFeature subFeature : subFeatures) { addDebugData(String.format("SubFeature type: %d", subFeature.type)); addDebugData(String.format("SubFeature name: %s", subFeature.name)); double value = 0.0; DoubleByReference pValue = new DoubleByReference(value); if (cSensors.sensors_get_value(chip, subFeature.number, pValue) == 0) { addDebugData(String.format("SubFeature value: %s", pValue.getValue())); if (subFeature.name.endsWith("_input")) { addData(String.format("%s", pValue.getValue())); break; } } else { addData("Could not retrieve value"); } } } private static List<CChip> detectedChips(CSensors cSensors) { List<CChip> detectedChips = new ArrayList<CChip>(); CChip foundChip; int numSensor = 0; while ((foundChip = cSensors.sensors_get_detected_chips(null, new IntByReference(numSensor))) != null) { detectedChips.add(foundChip); numSensor++; } return detectedChips; } private static List<CFeature> features(CSensors cSensors, CChip chip) { List<CFeature> features = new ArrayList<CFeature>(); CFeature foundFeature; int numFeature = 0; while ((foundFeature = cSensors.sensors_get_features(chip, new IntByReference(numFeature))) != null) { features.add(foundFeature); numFeature++; } return features; } private static List<CSubFeature> subFeatures(CSensors cSensors, CChip chip, CFeature feature) { List<CSubFeature> subFeatures = new ArrayList<CSubFeature>(); CSubFeature foundSubFeature; int numSubFeature = 0; while ((foundSubFeature = cSensors.sensors_get_all_subfeatures(chip, feature, new IntByReference(numSubFeature))) != null) { subFeatures.add(foundSubFeature); numSubFeature++; } return subFeatures; } }