From d4946f2c137e71c12d367223a3b5024bbccd7af5 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 25 Dec 2019 03:12:06 +0200 Subject: [PATCH] hddtemp module --- bumblebee/modules/hddtemp.py | 90 +++++++++++++++++++++++++++++++++ tests/modules/test_hddtemp.py | 59 +++++++++++++++++++++ themes/icons/ascii.json | 3 ++ themes/icons/awesome-fonts.json | 3 +- 4 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 bumblebee/modules/hddtemp.py create mode 100644 tests/modules/test_hddtemp.py diff --git a/bumblebee/modules/hddtemp.py b/bumblebee/modules/hddtemp.py new file mode 100644 index 0000000..86800c1 --- /dev/null +++ b/bumblebee/modules/hddtemp.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- + +"""Fetch hard drive temeperature data from a hddtemp daemon +that runs on localhost and default port (7634) +""" + +import socket + +import bumblebee.engine +import bumblebee.output + +HOST = "localhost" +PORT = 7634 + +CHUNK_SIZE = 1024 +RECORD_SIZE = 5 +SEPARATOR = "|" + + +class Module(bumblebee.engine.Module): + def __init__(self, engine, config): + widget = bumblebee.output.Widget(full_text=self.hddtemps) + super(Module, self).__init__(engine, config, widget) + self._hddtemps = self._get_hddtemps() + + def hddtemps(self, __): + return self._hddtemps + + def _fetch_data(self): + """fetch data from hddtemp service""" + try: + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: + sock.connect((HOST, PORT)) + data = "" + while True: + chunk = sock.recv(CHUNK_SIZE) + if chunk: + data += str(chunk) + else: + break + return data + except (AttributeError, socket.error) as e: + pass + + @staticmethod + def _get_parts(data): + """ + split data using | separator and remove first item + (because the first item is empty) + """ + parts = data.split("|")[1:] + return parts + + @staticmethod + def _partition_parts(parts): + """ + partition parts: one device record is five (5) items + """ + per_disk = [parts[i:i+RECORD_SIZE] + for i in range(len(parts))[::RECORD_SIZE]] + return per_disk + + @staticmethod + def _get_name_and_temp(device_record): + """ + get device name (without /dev part, to save space on bar) + and temperature (in °C) as tuple + """ + device_name = device_record[0].split("/")[-1] + device_temp = device_record[2] + return (device_name, device_temp) + + @staticmethod + def _get_hddtemp(device_record): + name, temp = device_record + hddtemp = "{}+{}°C".format(name, temp) + return hddtemp + + def _get_hddtemps(self): + data = self._fetch_data() + if data is None: + return "n/a" + parts = self._get_parts(data) + per_disk = self._partition_parts(parts) + names_and_temps = [self._get_name_and_temp(x) for x in per_disk] + hddtemps = [self._get_hddtemp(x) for x in names_and_temps] + return SEPARATOR.join(hddtemps) + + def update(self, __): + self._hddtemps = self._get_hddtemps() diff --git a/tests/modules/test_hddtemp.py b/tests/modules/test_hddtemp.py new file mode 100644 index 0000000..e8eb9ca --- /dev/null +++ b/tests/modules/test_hddtemp.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- + +import mock +import unittest + +from bumblebee.config import Config +import bumblebee.modules.hddtemp + + +class TestHddtempModule(unittest.TestCase): + def setUp(self): + config = Config() + self.module = bumblebee.modules.hddtemp.Module( + engine=mock.Mock(), config={"config": config}) + self.data_line = "|/dev/sda|TOSHIBA DT01ACA100 �|35|C||/dev/sdb|TOSHIBA DT01ACA100 �|37|C|" + self.expected_parts = [ + "/dev/sda", + "TOSHIBA DT01ACA100 �", + "35", + "C", + "", + "/dev/sdb", + "TOSHIBA DT01ACA100 �", + "37", + "C", + ""] + self.expected_per_disk = [ + ["/dev/sda", + "TOSHIBA DT01ACA100 �", + "35", + "C", + ""], + ["/dev/sdb", + "TOSHIBA DT01ACA100 �", + "37", + "C", + ""]] + self.device_record = self.expected_per_disk[0] + self.expected_name_and_temp = ("sda", "35") + self.expected_hddtemp = "sda+35°C" + + def test_get_parts(self): + self.assertEqual( + self.expected_parts, self.module._get_parts(self.data_line)) + + def test_partition_parts(self): + self.assertEqual( + self.expected_per_disk, + self.module._partition_parts(self.expected_parts)) + + def test_get_name_and_temp(self): + self.assertEqual( + self.expected_name_and_temp, + self.module._get_name_and_temp(self.device_record)) + + def test_get_hddtemp(self): + self.assertEqual( + self.expected_hddtemp, + self.module._get_hddtemp(self.expected_name_and_temp)) diff --git a/themes/icons/ascii.json b/themes/icons/ascii.json index fea74a1..73c6651 100644 --- a/themes/icons/ascii.json +++ b/themes/icons/ascii.json @@ -349,5 +349,8 @@ "off": { "prefix": "pom" }, "paused": { "prefix": "||" }, "on": { "prefix": " >" } + }, + "hddtemp": { + "prefix": "hddtemp" } } diff --git a/themes/icons/awesome-fonts.json b/themes/icons/awesome-fonts.json index 36ef75a..2da5699 100644 --- a/themes/icons/awesome-fonts.json +++ b/themes/icons/awesome-fonts.json @@ -251,5 +251,6 @@ "paused": { "prefix": "" }, "work": { "prefix": "" }, "break": { "prefix": "" } - } + }, + "hddtemp": { "prefix": "" } }