blob: 3b528901ec9234da026676e0d14865d856d8d61b [file] [log] [blame]
Tomáš Pecka4d7e9092023-03-26 11:07:43 +02001#include <future>
Tomáš Peckad03044f2020-11-12 14:33:10 +01002#include "Factory.h"
Tomáš Pecka45b67f92024-01-11 14:13:05 +01003#include "FspYh.h"
Tomáš Peckad03044f2020-11-12 14:33:10 +01004#include "ietf-hardware/IETFHardware.h"
5#include "ietf-hardware/sysfs/EMMC.h"
6#include "ietf-hardware/sysfs/HWMon.h"
7
8namespace velia::ietf_hardware {
Václav Kubernát281af6b2021-05-14 03:07:29 +02009using velia::ietf_hardware::data_reader::EMMC;
Tomáš Pecka4d7e9092023-03-26 11:07:43 +020010using velia::ietf_hardware::data_reader::Fans;
Václav Kubernát281af6b2021-05-14 03:07:29 +020011using velia::ietf_hardware::data_reader::SensorType;
Tomáš Pecka4d7e9092023-03-26 11:07:43 +020012using velia::ietf_hardware::data_reader::StaticData;
13using velia::ietf_hardware::data_reader::SysfsValue;
Václav Kubernát281af6b2021-05-14 03:07:29 +020014
15void createPower(std::shared_ptr<velia::ietf_hardware::IETFHardware> ietfHardware)
16{
Tomáš Pecka3905e442024-01-11 14:27:31 +010017 auto pdu = std::make_shared<velia::ietf_hardware::FspYhPdu>("/sys/bus/i2c/devices/2-0025/hwmon",
18 "pdu",
19 std::make_shared<TransientI2C>(2, 0x25, "ym2151e"));
Tomáš Pecka4d7e9092023-03-26 11:07:43 +020020 auto psu1 = std::make_shared<velia::ietf_hardware::FspYhPsu>("/sys/bus/i2c/devices/2-0058/hwmon",
21 "psu1",
22 std::make_shared<TransientI2C>(2, 0x58, "ym2151e"));
23 auto psu2 = std::make_shared<velia::ietf_hardware::FspYhPsu>("/sys/bus/i2c/devices/2-0059/hwmon",
24 "psu2",
25 std::make_shared<TransientI2C>(2, 0x59, "ym2151e"));
Václav Kubernát281af6b2021-05-14 03:07:29 +020026
Tomáš Pecka4886db22023-05-10 10:46:15 +020027 struct ParallelPDUReader {
Tomáš Pecka3905e442024-01-11 14:27:31 +010028 std::shared_ptr<velia::ietf_hardware::FspYhPdu> pdu;
Tomáš Pecka4886db22023-05-10 10:46:15 +020029 std::shared_ptr<velia::ietf_hardware::FspYhPsu> psu1;
30 std::shared_ptr<velia::ietf_hardware::FspYhPsu> psu2;
Václav Kubernát281af6b2021-05-14 03:07:29 +020031
Tomáš Pecka3905e442024-01-11 14:27:31 +010032 ParallelPDUReader(std::shared_ptr<velia::ietf_hardware::FspYhPdu> pdu, std::shared_ptr<velia::ietf_hardware::FspYhPsu> psu1, std::shared_ptr<velia::ietf_hardware::FspYhPsu> psu2)
33 : pdu(std::move(pdu))
Tomáš Pecka4886db22023-05-10 10:46:15 +020034 , psu1(std::move(psu1))
35 , psu2(std::move(psu2))
36 {
37 }
38
Tomáš Peckac0991ce2023-12-20 15:46:03 +010039 SensorPollData operator()()
Tomáš Pecka4886db22023-05-10 10:46:15 +020040 {
41 auto psu1Reader = std::async(std::launch::async, [&] { return psu1->readValues(); });
42 auto psu2Reader = std::async(std::launch::async, [&] { return psu2->readValues(); });
Tomáš Pecka3905e442024-01-11 14:27:31 +010043 auto pduReader = std::async(std::launch::async, [&] { return pdu->readValues(); });
Tomáš Pecka4886db22023-05-10 10:46:15 +020044
Tomáš Peckac0991ce2023-12-20 15:46:03 +010045 SensorPollData pollData;
46 pollData.merge(psu1Reader.get());
47 pollData.merge(psu2Reader.get());
48 pollData.merge(pduReader.get());
Tomáš Pecka4886db22023-05-10 10:46:15 +020049
Tomáš Peckac0991ce2023-12-20 15:46:03 +010050 return pollData;
Tomáš Pecka4886db22023-05-10 10:46:15 +020051 }
52 };
53
Tomáš Pecka3905e442024-01-11 14:27:31 +010054 ietfHardware->registerDataReader(ParallelPDUReader(pdu, psu1, psu2));
Václav Kubernát281af6b2021-05-14 03:07:29 +020055}
Tomáš Peckad03044f2020-11-12 14:33:10 +010056
57std::shared_ptr<IETFHardware> create(const std::string& applianceName)
58{
59 auto ietfHardware = std::make_shared<velia::ietf_hardware::IETFHardware>();
60
61 if (applianceName == "czechlight-clearfog") {
62 auto hwmonFans = std::make_shared<velia::ietf_hardware::sysfs::HWMon>("/sys/bus/i2c/devices/1-002e/hwmon/");
63 auto sysfsTempFront = std::make_shared<velia::ietf_hardware::sysfs::HWMon>("/sys/devices/platform/soc/soc:internal-regs/f1011100.i2c/i2c-1/1-002e/hwmon/");
64 auto sysfsTempCpu = std::make_shared<velia::ietf_hardware::sysfs::HWMon>("/sys/devices/virtual/thermal/thermal_zone0/");
65 auto sysfsTempMII0 = std::make_shared<velia::ietf_hardware::sysfs::HWMon>("/sys/devices/platform/soc/soc:internal-regs/f1072004.mdio/mdio_bus/f1072004.mdio-mii/f1072004.mdio-mii:00/hwmon/");
66 auto sysfsTempMII1 = std::make_shared<velia::ietf_hardware::sysfs::HWMon>("/sys/devices/platform/soc/soc:internal-regs/f1072004.mdio/mdio_bus/f1072004.mdio-mii/f1072004.mdio-mii:01/hwmon/");
67 auto emmc = std::make_shared<velia::ietf_hardware::sysfs::EMMC>("/sys/block/mmcblk0/device/");
68
Václav Kubernát6c17d0a2021-03-29 04:55:31 +020069 ietfHardware->registerDataReader(StaticData("ne", std::nullopt, {{"description", "Czechlight project"s}}));
70 ietfHardware->registerDataReader(StaticData("ne:ctrl", "ne", {{"class", "iana-hardware:module"}}));
71 ietfHardware->registerDataReader(Fans("ne:fans", "ne", hwmonFans, 4));
72 ietfHardware->registerDataReader(SysfsValue<SensorType::Temperature>("ne:ctrl:temperature-front", "ne:ctrl", sysfsTempFront, 1));
73 ietfHardware->registerDataReader(SysfsValue<SensorType::Temperature>("ne:ctrl:temperature-cpu", "ne:ctrl", sysfsTempCpu, 1));
74 ietfHardware->registerDataReader(SysfsValue<SensorType::Temperature>("ne:ctrl:temperature-internal-0", "ne:ctrl", sysfsTempMII0, 1));
75 ietfHardware->registerDataReader(SysfsValue<SensorType::Temperature>("ne:ctrl:temperature-internal-1", "ne:ctrl", sysfsTempMII1, 1));
76 ietfHardware->registerDataReader(EMMC("ne:ctrl:emmc", "ne:ctrl", emmc));
Václav Kubernát281af6b2021-05-14 03:07:29 +020077
78 createPower(ietfHardware);
Jan Kundrát01638152021-02-05 19:13:25 +010079 } else if (applianceName == "czechlight-clearfog-g2") {
80 auto fans = std::make_shared<velia::ietf_hardware::sysfs::HWMon>("/sys/bus/i2c/devices/1-0020/hwmon/");
81 auto tempMainBoard = std::make_shared<velia::ietf_hardware::sysfs::HWMon>("/sys/bus/i2c/devices/1-0048/hwmon/");
82 auto tempFans = std::make_shared<velia::ietf_hardware::sysfs::HWMon>("/sys/bus/i2c/devices/1-0049/hwmon/");
83 auto tempCpu = std::make_shared<velia::ietf_hardware::sysfs::HWMon>("/sys/devices/virtual/thermal/thermal_zone0/");
84 auto tempMII0 = std::make_shared<velia::ietf_hardware::sysfs::HWMon>("/sys/devices/platform/soc/soc:internal-regs/f1072004.mdio/mdio_bus/f1072004.mdio-mii/f1072004.mdio-mii:00/hwmon/");
85 auto tempMII1 = std::make_shared<velia::ietf_hardware::sysfs::HWMon>("/sys/devices/platform/soc/soc:internal-regs/f1072004.mdio/mdio_bus/f1072004.mdio-mii/f1072004.mdio-mii:01/hwmon/");
86 auto emmc = std::make_shared<velia::ietf_hardware::sysfs::EMMC>("/sys/block/mmcblk0/device/");
87
88 /* FIXME:
89 * Publish more properties for ne element. We have an EEPROM at the PCB for storing serial numbers (etc.), but it's so far unused. We could also use U-Boot env variables
90 * This will be needed for sdn-roadm-line only. So we should also parse the model from /proc/cmdline here
91 */
Václav Kubernát6c17d0a2021-03-29 04:55:31 +020092 ietfHardware->registerDataReader(StaticData("ne", std::nullopt, {{"description", "Czechlight project"s}}));
Jan Kundrát01638152021-02-05 19:13:25 +010093
Václav Kubernát6c17d0a2021-03-29 04:55:31 +020094 ietfHardware->registerDataReader(StaticData("ne:ctrl", "ne", {{"class", "iana-hardware:module"}}));
Tomáš Pecka8bab0f02023-05-31 14:49:47 +020095 ietfHardware->registerDataReader(Fans("ne:fans",
96 "ne",
97 fans,
98 4,
99 Thresholds<int64_t>{
100 .criticalLow = OneThreshold<int64_t>{3680, 300}, /* 40 % of 9200 RPM */
101 .warningLow = OneThreshold<int64_t>{7360, 300}, /* 80 % of 9200 RPM */
102 .warningHigh = std::nullopt,
103 .criticalHigh = std::nullopt,
104 }));
Václav Kubernát6c17d0a2021-03-29 04:55:31 +0200105 ietfHardware->registerDataReader(SysfsValue<SensorType::Temperature>("ne:ctrl:temperature-front", "ne:ctrl", tempMainBoard, 1));
106 ietfHardware->registerDataReader(SysfsValue<SensorType::Temperature>("ne:ctrl:temperature-cpu", "ne:ctrl", tempCpu, 1));
107 ietfHardware->registerDataReader(SysfsValue<SensorType::Temperature>("ne:ctrl:temperature-rear", "ne:ctrl", tempFans, 1));
108 ietfHardware->registerDataReader(SysfsValue<SensorType::Temperature>("ne:ctrl:temperature-internal-0", "ne:ctrl", tempMII0, 1));
109 ietfHardware->registerDataReader(SysfsValue<SensorType::Temperature>("ne:ctrl:temperature-internal-1", "ne:ctrl", tempMII1, 1));
110 ietfHardware->registerDataReader(EMMC("ne:ctrl:emmc", "ne:ctrl", emmc));
Václav Kubernát97e5ea12021-03-24 00:36:57 +0100111
Václav Kubernát281af6b2021-05-14 03:07:29 +0200112 createPower(ietfHardware);
Tomáš Peckad03044f2020-11-12 14:33:10 +0100113 } else {
114 throw std::runtime_error("Unknown appliance '" + applianceName + "'");
115 }
116
117 return ietfHardware;
118}
119
120}