blob: 342b07ba6a543207e8dda5355b61a4ed4fe2aad1 [file] [log] [blame]
Matt Spinlerabf8da32017-04-27 14:08:45 -05001/**
2 * Copyright © 2017 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Matt Spinlerabf8da32017-04-27 14:08:45 -050016#include "fan.hpp"
Matthew Barth177fe982020-05-26 11:05:19 -050017
Matt Spinlerae1f8ef2020-10-14 16:15:51 -050018#include "logging.hpp"
Matthew Barth177fe982020-05-26 11:05:19 -050019#include "sdbusplus.hpp"
Matt Spinlerb0412d02020-10-12 16:53:52 -050020#include "system.hpp"
Matt Spinlerabf8da32017-04-27 14:08:45 -050021#include "types.hpp"
Matt Spinlerb1e18512017-04-27 14:42:33 -050022#include "utility.hpp"
Matthew Barth177fe982020-05-26 11:05:19 -050023
Jay Meyera7aed012020-10-06 14:32:22 -050024#include <fmt/format.h>
25
Matthew Barth177fe982020-05-26 11:05:19 -050026#include <phosphor-logging/log.hpp>
27
28#include <algorithm>
Matt Spinlerabf8da32017-04-27 14:08:45 -050029
30namespace phosphor
31{
32namespace fan
33{
34namespace monitor
35{
36
37using namespace phosphor::logging;
Matt Spinlerb0412d02020-10-12 16:53:52 -050038using namespace sdbusplus::bus::match;
Matt Spinlerabf8da32017-04-27 14:08:45 -050039
Matthew Barth177fe982020-05-26 11:05:19 -050040Fan::Fan(Mode mode, sdbusplus::bus::bus& bus, const sdeventplus::Event& event,
Matt Spinlerb0412d02020-10-12 16:53:52 -050041 std::unique_ptr<trust::Manager>& trust, const FanDefinition& def,
42 System& system) :
Matt Spinlerabf8da32017-04-27 14:08:45 -050043 _bus(bus),
44 _name(std::get<fanNameField>(def)),
45 _deviation(std::get<fanDeviationField>(def)),
Matt Spinlerc39e8592017-09-28 13:13:08 -050046 _numSensorFailsForNonFunc(std::get<numSensorFailsForNonfuncField>(def)),
Matt Spinlerb0412d02020-10-12 16:53:52 -050047 _trustManager(trust),
48#ifdef MONITOR_USE_JSON
49 _monitorDelay(std::get<monitorStartDelayField>(def)),
50 _monitorTimer(event, std::bind(std::mem_fn(&Fan::startMonitor), this)),
51#endif
Matt Spinlerb63aa092020-10-14 09:45:11 -050052 _system(system),
53 _presenceMatch(bus,
54 rules::propertiesChanged(util::INVENTORY_PATH + _name,
55 util::INV_ITEM_IFACE),
56 std::bind(std::mem_fn(&Fan::presenceChanged), this,
Matt Spinler27f6b682020-10-27 08:43:37 -050057 std::placeholders::_1)),
Matt Spinler7d135642021-02-04 12:44:17 -060058 _presenceIfaceAddedMatch(
59 bus,
60 rules::interfacesAdded() +
61 rules::argNpath(0, util::INVENTORY_PATH + _name),
62 std::bind(std::mem_fn(&Fan::presenceIfaceAdded), this,
63 std::placeholders::_1)),
Matt Spinler623635c2021-03-29 13:13:59 -050064 _fanMissingErrorDelay(std::get<fanMissingErrDelayField>(def)),
Matt Spinlera3584bd2021-03-29 15:48:30 -050065 _setFuncOnPresent(std::get<funcOnPresentField>(def))
Matt Spinlerabf8da32017-04-27 14:08:45 -050066{
Matt Spinlerae1f8ef2020-10-14 16:15:51 -050067 // Start from a known state of functional (even if
68 // _numSensorFailsForNonFunc is 0)
Jolie Ku4c3c24f2020-09-09 11:01:46 +080069 updateInventory(true);
70
Matthew Barth0a9fe162018-01-26 12:53:15 -060071 // Setup tach sensors for monitoring
72 auto& sensors = std::get<sensorListField>(def);
73 for (auto& s : sensors)
74 {
Matt Spinler4283c5d2021-03-01 15:56:00 -060075 _sensors.emplace_back(std::make_shared<TachSensor>(
76 mode, bus, *this, std::get<sensorNameField>(s),
77 std::get<hasTargetField>(s), std::get<funcDelay>(def),
78 std::get<targetInterfaceField>(s), std::get<factorField>(s),
79 std::get<offsetField>(s), std::get<methodField>(def),
80 std::get<thresholdField>(s), std::get<timeoutField>(def),
Matt Spinlerfdfcc672021-06-01 14:51:06 -060081 std::get<nonfuncRotorErrDelayField>(def),
82 std::get<countIntervalField>(def), event));
Matthew Barth0a9fe162018-01-26 12:53:15 -060083
Matt Spinler4283c5d2021-03-01 15:56:00 -060084 _trustManager->registerSensor(_sensors.back());
Matthew Barth0a9fe162018-01-26 12:53:15 -060085 }
86
Matt Spinlerb0412d02020-10-12 16:53:52 -050087#ifndef MONITOR_USE_JSON
Matthew Barth0a9fe162018-01-26 12:53:15 -060088 // Check current tach state when entering monitor mode
Matthew Barth6ad28432017-08-22 11:18:19 -050089 if (mode != Mode::init)
90 {
Matt Spinlerb0412d02020-10-12 16:53:52 -050091 _monitorReady = true;
92
Matthew Barth177fe982020-05-26 11:05:19 -050093 // The TachSensors will now have already read the input
94 // and target values, so check them.
Matthew Barth6ad28432017-08-22 11:18:19 -050095 tachChanged();
96 }
Matt Spinlerb0412d02020-10-12 16:53:52 -050097#else
Matt Spinler7d135642021-02-04 12:44:17 -060098 if (_system.isPowerOn())
99 {
100 _monitorTimer.restartOnce(std::chrono::seconds(_monitorDelay));
101 }
Matt Spinlerb0412d02020-10-12 16:53:52 -0500102#endif
Matt Spinlerb63aa092020-10-14 09:45:11 -0500103
Matt Spinler27f6b682020-10-27 08:43:37 -0500104 if (_fanMissingErrorDelay)
105 {
106 _fanMissingErrorTimer = std::make_unique<
107 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>(
108 event, std::bind(&System::fanMissingErrorTimerExpired, &system,
109 std::ref(*this)));
Matt Spinler7d135642021-02-04 12:44:17 -0600110 }
Matt Spinler27f6b682020-10-27 08:43:37 -0500111
Matt Spinler7d135642021-02-04 12:44:17 -0600112 try
113 {
114 _present = util::SDBusPlus::getProperty<bool>(
115 util::INVENTORY_PATH + _name, util::INV_ITEM_IFACE, "Present");
116
117 if (!_present)
Matt Spinler27f6b682020-10-27 08:43:37 -0500118 {
Matt Spinlerac372972021-01-25 15:11:22 -0600119 getLogger().log(
120 fmt::format("On startup, fan {} is missing", _name));
Matt Spinler7d135642021-02-04 12:44:17 -0600121 if (_system.isPowerOn() && _fanMissingErrorTimer)
122 {
123 _fanMissingErrorTimer->restartOnce(
124 std::chrono::seconds{*_fanMissingErrorDelay});
125 }
126 }
127 }
128 catch (const util::DBusServiceError& e)
129 {
130 // This could happen on the first BMC boot if the presence
131 // detect app hasn't started yet and there isn't an inventory
132 // cache yet.
133 }
134}
135
136void Fan::presenceIfaceAdded(sdbusplus::message::message& msg)
137{
138 sdbusplus::message::object_path path;
139 std::map<std::string, std::map<std::string, std::variant<bool>>> interfaces;
140
141 msg.read(path, interfaces);
142
143 auto properties = interfaces.find(util::INV_ITEM_IFACE);
144 if (properties == interfaces.end())
145 {
146 return;
147 }
148
149 auto property = properties->second.find("Present");
150 if (property == properties->second.end())
151 {
152 return;
153 }
154
155 _present = std::get<bool>(property->second);
156
157 if (!_present)
158 {
159 getLogger().log(fmt::format(
160 "New fan {} interface added and fan is not present", _name));
161 if (_system.isPowerOn() && _fanMissingErrorTimer)
162 {
Matt Spinler27f6b682020-10-27 08:43:37 -0500163 _fanMissingErrorTimer->restartOnce(
164 std::chrono::seconds{*_fanMissingErrorDelay});
165 }
166 }
Matt Spinler7d135642021-02-04 12:44:17 -0600167
168 _system.fanStatusChange(*this);
Matt Spinlerb0412d02020-10-12 16:53:52 -0500169}
170
171void Fan::startMonitor()
172{
173 _monitorReady = true;
174
Matt Spinler4283c5d2021-03-01 15:56:00 -0600175 std::for_each(_sensors.begin(), _sensors.end(), [this](auto& sensor) {
176 if (_present)
177 {
178 try
179 {
180 // Force a getProperty call to check if the tach sensor is
181 // on D-Bus. If it isn't, now set it to nonfunctional.
182 // This isn't done earlier so that code watching for
183 // nonfunctional tach sensors doesn't take actions before
184 // those sensors show up on D-Bus.
185 sensor->updateTachAndTarget();
186 tachChanged(*sensor);
187 }
188 catch (const util::DBusServiceError& e)
189 {
190 // The tach property still isn't on D-Bus, ensure
191 // sensor is nonfunctional.
192 getLogger().log(fmt::format(
193 "Monitoring starting but {} sensor value not on D-Bus",
194 sensor->name()));
195
196 sensor->setFunctional(false);
197
198 if (_numSensorFailsForNonFunc)
199 {
200 if (_functional && (countNonFunctionalSensors() >=
201 _numSensorFailsForNonFunc))
202 {
203 updateInventory(false);
204 }
205 }
206
207 _system.fanStatusChange(*this);
208 }
209 }
210 });
Matt Spinlerabf8da32017-04-27 14:08:45 -0500211}
212
Matt Spinlerebaae612017-04-27 14:21:48 -0500213void Fan::tachChanged()
214{
Matt Spinlerb0412d02020-10-12 16:53:52 -0500215 if (_monitorReady)
Matt Spinlerebaae612017-04-27 14:21:48 -0500216 {
Matt Spinlerb0412d02020-10-12 16:53:52 -0500217 for (auto& s : _sensors)
218 {
219 tachChanged(*s);
220 }
Matt Spinlerebaae612017-04-27 14:21:48 -0500221 }
222}
223
Matt Spinlerebaae612017-04-27 14:21:48 -0500224void Fan::tachChanged(TachSensor& sensor)
225{
Matt Spinler7d135642021-02-04 12:44:17 -0600226 if (!_system.isPowerOn() || !_monitorReady)
227 {
228 return;
229 }
230
Matt Spinlerc39e8592017-09-28 13:13:08 -0500231 if (_trustManager->active())
232 {
233 if (!_trustManager->checkTrust(sensor))
234 {
235 return;
236 }
237 }
238
Matt Spinlerfdfcc672021-06-01 14:51:06 -0600239 // If the error checking method is 'count', if a tach change leads
240 // to an out of range sensor the count timer will take over in calling
241 // process() until the sensor is healthy again.
242 if (!sensor.countTimerRunning())
Matt Spinler623635c2021-03-29 13:13:59 -0500243 {
244 process(sensor);
245 }
246}
247
Matt Spinlerfdfcc672021-06-01 14:51:06 -0600248void Fan::countTimerExpired(TachSensor& sensor)
Matt Spinler623635c2021-03-29 13:13:59 -0500249{
Matt Spinlerfdfcc672021-06-01 14:51:06 -0600250 if (_trustManager->active() && !_trustManager->checkTrust(sensor))
Matt Spinler623635c2021-03-29 13:13:59 -0500251 {
Matt Spinlerfdfcc672021-06-01 14:51:06 -0600252 return;
Matt Spinler623635c2021-03-29 13:13:59 -0500253 }
Matt Spinlerfdfcc672021-06-01 14:51:06 -0600254 process(sensor);
Matthew Barthfcb0dbc2021-02-10 14:23:39 -0600255}
256
257void Fan::process(TachSensor& sensor)
258{
Matthew Barth177fe982020-05-26 11:05:19 -0500259 // If this sensor is out of range at this moment, start
260 // its timer, at the end of which the inventory
261 // for the fan may get updated to not functional.
Matt Spinlera4c8f1f2017-04-27 14:38:38 -0500262
Matthew Barth177fe982020-05-26 11:05:19 -0500263 // If this sensor is OK, put everything back into a good state.
Matt Spinlera4c8f1f2017-04-27 14:38:38 -0500264
265 if (outOfRange(sensor))
266 {
Matthew Barthe11cbc62018-02-20 12:11:07 -0600267 if (sensor.functional())
Matt Spinlera4c8f1f2017-04-27 14:38:38 -0500268 {
Jolie Ku69f2f482020-10-21 09:59:43 +0800269 switch (sensor.getMethod())
270 {
271 case MethodMode::timebased:
272 // Start nonfunctional timer if not already running
273 sensor.startTimer(TimerMode::nonfunc);
274 break;
275 case MethodMode::count:
Matt Spinlerfdfcc672021-06-01 14:51:06 -0600276
277 if (!sensor.countTimerRunning())
278 {
279 sensor.startCountTimer();
280 }
Jolie Ku69f2f482020-10-21 09:59:43 +0800281 sensor.setCounter(true);
282 if (sensor.getCounter() >= sensor.getThreshold())
283 {
284 updateState(sensor);
285 }
286 break;
287 }
Matt Spinlera4c8f1f2017-04-27 14:38:38 -0500288 }
289 }
290 else
291 {
Jolie Ku69f2f482020-10-21 09:59:43 +0800292 switch (sensor.getMethod())
Matt Spinlera4c8f1f2017-04-27 14:38:38 -0500293 {
Jolie Ku69f2f482020-10-21 09:59:43 +0800294 case MethodMode::timebased:
295 if (sensor.functional())
296 {
Matthew Barth11b5d8f2021-01-28 14:04:09 -0600297 if (sensor.timerRunning())
298 {
299 sensor.stopTimer();
300 }
Jolie Ku69f2f482020-10-21 09:59:43 +0800301 }
302 else
303 {
304 // Start functional timer if not already running
305 sensor.startTimer(TimerMode::func);
306 }
307 break;
308 case MethodMode::count:
309 sensor.setCounter(false);
Matt Spinlerfdfcc672021-06-01 14:51:06 -0600310 if (sensor.getCounter() == 0)
Jolie Ku69f2f482020-10-21 09:59:43 +0800311 {
Matt Spinlerfdfcc672021-06-01 14:51:06 -0600312 if (!sensor.functional())
313 {
314 updateState(sensor);
315 }
316
317 sensor.stopCountTimer();
Jolie Ku69f2f482020-10-21 09:59:43 +0800318 }
319 break;
Matt Spinlera4c8f1f2017-04-27 14:38:38 -0500320 }
321 }
Matt Spinlerebaae612017-04-27 14:21:48 -0500322}
323
Matthew Barthf552ea52018-01-15 16:22:04 -0600324uint64_t Fan::findTargetSpeed()
Matt Spinlerabf8da32017-04-27 14:08:45 -0500325{
326 uint64_t target = 0;
Matthew Barth177fe982020-05-26 11:05:19 -0500327 // The sensor doesn't support a target,
328 // so get it from another sensor.
Matthew Barthf552ea52018-01-15 16:22:04 -0600329 auto s = std::find_if(_sensors.begin(), _sensors.end(),
Matthew Barth177fe982020-05-26 11:05:19 -0500330 [](const auto& s) { return s->hasTarget(); });
Matt Spinlerabf8da32017-04-27 14:08:45 -0500331
Matthew Barthf552ea52018-01-15 16:22:04 -0600332 if (s != _sensors.end())
Matt Spinlerabf8da32017-04-27 14:08:45 -0500333 {
Matthew Barthf552ea52018-01-15 16:22:04 -0600334 target = (*s)->getTarget();
Matt Spinlerabf8da32017-04-27 14:08:45 -0500335 }
336
337 return target;
338}
339
Matthew Barth7c23a042021-01-26 16:21:45 -0600340size_t Fan::countNonFunctionalSensors()
Matt Spinlerabf8da32017-04-27 14:08:45 -0500341{
Matthew Barth7c23a042021-01-26 16:21:45 -0600342 return std::count_if(_sensors.begin(), _sensors.end(),
343 [](const auto& s) { return !s->functional(); });
Matt Spinlerabf8da32017-04-27 14:08:45 -0500344}
345
Matt Spinlerabf8da32017-04-27 14:08:45 -0500346bool Fan::outOfRange(const TachSensor& sensor)
347{
348 auto actual = static_cast<uint64_t>(sensor.getInput());
Matthew Barth7c23a042021-01-26 16:21:45 -0600349 auto range = sensor.getRange(_deviation);
Matt Spinlerabf8da32017-04-27 14:08:45 -0500350
Matthew Barth7c23a042021-01-26 16:21:45 -0600351 if ((actual < range.first) || (actual > range.second))
Matt Spinlerabf8da32017-04-27 14:08:45 -0500352 {
353 return true;
354 }
355
356 return false;
357}
358
Jolie Ku69f2f482020-10-21 09:59:43 +0800359void Fan::updateState(TachSensor& sensor)
Matt Spinlera9406a72017-04-27 14:29:24 -0500360{
Matthew Barth7c23a042021-01-26 16:21:45 -0600361 auto range = sensor.getRange(_deviation);
Matt Spinler7d135642021-02-04 12:44:17 -0600362
363 if (!_system.isPowerOn())
364 {
365 return;
366 }
367
Matthew Barthe11cbc62018-02-20 12:11:07 -0600368 sensor.setFunctional(!sensor.functional());
Matt Spinlerae1f8ef2020-10-14 16:15:51 -0500369 getLogger().log(
370 fmt::format("Setting tach sensor {} functional state to {}. "
Matthew Barth7c23a042021-01-26 16:21:45 -0600371 "[target = {}, input = {}, allowed range = ({} - {})]",
372 sensor.name(), sensor.functional(), sensor.getTarget(),
373 sensor.getInput(), range.first, range.second));
Matt Spinlerae1f8ef2020-10-14 16:15:51 -0500374
375 // A zero value for _numSensorFailsForNonFunc means we aren't dealing
376 // with fan FRU functional status, only sensor functional status.
377 if (_numSensorFailsForNonFunc)
Matthew Barthe11cbc62018-02-20 12:11:07 -0600378 {
Matthew Barth7c23a042021-01-26 16:21:45 -0600379 auto numNonFuncSensors = countNonFunctionalSensors();
Matt Spinlerae1f8ef2020-10-14 16:15:51 -0500380 // If the fan was nonfunctional and enough sensors are now OK,
Matthew Barthcceffdd2021-05-20 12:17:21 -0500381 // the fan can be set to functional as long as `set_func_on_present` was
382 // not set
383 if (!_setFuncOnPresent && !_functional &&
384 !(numNonFuncSensors >= _numSensorFailsForNonFunc))
Matt Spinlerae1f8ef2020-10-14 16:15:51 -0500385 {
Matthew Barth7c23a042021-01-26 16:21:45 -0600386 getLogger().log(fmt::format("Setting fan {} to functional, number "
387 "of nonfunctional sensors = {}",
388 _name, numNonFuncSensors));
Matt Spinlerae1f8ef2020-10-14 16:15:51 -0500389 updateInventory(true);
390 }
Matt Spinlera9406a72017-04-27 14:29:24 -0500391
Matt Spinlerae1f8ef2020-10-14 16:15:51 -0500392 // If the fan is currently functional, but too many
393 // contained sensors are now nonfunctional, update
Matthew Barth7c23a042021-01-26 16:21:45 -0600394 // the fan to nonfunctional.
395 if (_functional && (numNonFuncSensors >= _numSensorFailsForNonFunc))
Matt Spinlerae1f8ef2020-10-14 16:15:51 -0500396 {
Matthew Barth7c23a042021-01-26 16:21:45 -0600397 getLogger().log(fmt::format("Setting fan {} to nonfunctional, "
398 "number of nonfunctional sensors = {}",
399 _name, numNonFuncSensors));
Matt Spinlerae1f8ef2020-10-14 16:15:51 -0500400 updateInventory(false);
401 }
Matt Spinlerb1e18512017-04-27 14:42:33 -0500402 }
Matt Spinlerb63aa092020-10-14 09:45:11 -0500403
404 _system.fanStatusChange(*this);
Matt Spinlera9406a72017-04-27 14:29:24 -0500405}
406
Matt Spinlerb1e18512017-04-27 14:42:33 -0500407void Fan::updateInventory(bool functional)
408{
Matthew Barth177fe982020-05-26 11:05:19 -0500409 auto objectMap =
410 util::getObjMap<bool>(_name, util::OPERATIONAL_STATUS_INTF,
411 util::FUNCTIONAL_PROPERTY, functional);
Matthew Barth51dd1852017-11-16 15:21:13 -0600412 auto response = util::SDBusPlus::lookupAndCallMethod(
Matthew Barth177fe982020-05-26 11:05:19 -0500413 _bus, util::INVENTORY_PATH, util::INVENTORY_INTF, "Notify", objectMap);
Matt Spinlerb1e18512017-04-27 14:42:33 -0500414 if (response.is_method_error())
415 {
416 log<level::ERR>("Error in Notify call to update inventory");
417 return;
418 }
419
Matthew Barth177fe982020-05-26 11:05:19 -0500420 // This will always track the current state of the inventory.
Matt Spinlerb1e18512017-04-27 14:42:33 -0500421 _functional = functional;
422}
423
Matt Spinlerb63aa092020-10-14 09:45:11 -0500424void Fan::presenceChanged(sdbusplus::message::message& msg)
425{
426 std::string interface;
427 std::map<std::string, std::variant<bool>> properties;
428
429 msg.read(interface, properties);
430
431 auto presentProp = properties.find("Present");
432 if (presentProp != properties.end())
433 {
434 _present = std::get<bool>(presentProp->second);
435
Matt Spinler27f6b682020-10-27 08:43:37 -0500436 getLogger().log(
Matt Spinlerac372972021-01-25 15:11:22 -0600437 fmt::format("Fan {} presence state change to {}", _name, _present));
Matt Spinler27f6b682020-10-27 08:43:37 -0500438
Matt Spinlerb63aa092020-10-14 09:45:11 -0500439 _system.fanStatusChange(*this);
Matt Spinler27f6b682020-10-27 08:43:37 -0500440
Matt Spinlera3584bd2021-03-29 15:48:30 -0500441 if (_present && _setFuncOnPresent)
442 {
443 updateInventory(true);
444 std::for_each(_sensors.begin(), _sensors.end(), [](auto& sensor) {
445 sensor->setFunctional(true);
446 sensor->resetMethod();
447 });
448 }
449
Matt Spinler27f6b682020-10-27 08:43:37 -0500450 if (_fanMissingErrorDelay)
451 {
Matt Spinler7d135642021-02-04 12:44:17 -0600452 if (!_present && _system.isPowerOn())
Matt Spinler27f6b682020-10-27 08:43:37 -0500453 {
454 _fanMissingErrorTimer->restartOnce(
455 std::chrono::seconds{*_fanMissingErrorDelay});
456 }
Matt Spinler7d135642021-02-04 12:44:17 -0600457 else if (_present && _fanMissingErrorTimer->isEnabled())
Matt Spinler27f6b682020-10-27 08:43:37 -0500458 {
459 _fanMissingErrorTimer->setEnabled(false);
460 }
461 }
Matt Spinlerb63aa092020-10-14 09:45:11 -0500462 }
463}
Matt Spinlerf13b42e2020-10-26 15:29:49 -0500464
465void Fan::sensorErrorTimerExpired(const TachSensor& sensor)
466{
Matt Spinler7d135642021-02-04 12:44:17 -0600467 if (_present && _system.isPowerOn())
Matt Spinlerf13b42e2020-10-26 15:29:49 -0500468 {
469 _system.sensorErrorTimerExpired(*this, sensor);
470 }
471}
472
Matt Spinler7d135642021-02-04 12:44:17 -0600473void Fan::powerStateChanged(bool powerStateOn)
474{
475#ifdef MONITOR_USE_JSON
476 if (powerStateOn)
477 {
Matt Spinler7d135642021-02-04 12:44:17 -0600478 _monitorTimer.restartOnce(std::chrono::seconds(_monitorDelay));
479
Matt Spinler4283c5d2021-03-01 15:56:00 -0600480 if (_present)
481 {
482 std::for_each(
483 _sensors.begin(), _sensors.end(), [this](auto& sensor) {
484 try
485 {
486 // Force a getProperty call. If sensor is on D-Bus,
487 // then make sure it's functional.
488 sensor->updateTachAndTarget();
489
490 // If not functional, set it back to functional.
491 if (!sensor->functional())
492 {
493 sensor->setFunctional(true);
494 _system.fanStatusChange(*this, true);
495 }
Matt Spinler623635c2021-03-29 13:13:59 -0500496
497 // Set the counters back to zero
498 if (sensor->getMethod() == MethodMode::count)
499 {
500 sensor->resetMethod();
501 }
Matt Spinler4283c5d2021-03-01 15:56:00 -0600502 }
503 catch (const util::DBusServiceError& e)
504 {
505 // Properties still aren't on D-Bus. Let startMonitor()
506 // deal with it.
507 getLogger().log(fmt::format(
508 "At power on, tach sensor {} value not on D-Bus",
509 sensor->name()));
510 }
511 });
512
513 // If configured to change functional state on the fan itself,
514 // Set it back to true now if necessary.
515 if (_numSensorFailsForNonFunc)
516 {
517 if (!_functional &&
518 (countNonFunctionalSensors() < _numSensorFailsForNonFunc))
519 {
520 updateInventory(true);
521 }
522 }
523 }
524 else
Matt Spinler7d135642021-02-04 12:44:17 -0600525 {
526 getLogger().log(
527 fmt::format("At power on, fan {} is missing", _name));
528
529 if (_fanMissingErrorTimer)
530 {
531 _fanMissingErrorTimer->restartOnce(
532 std::chrono::seconds{*_fanMissingErrorDelay});
533 }
534 }
535 }
536 else
537 {
538 _monitorReady = false;
539
540 if (_monitorTimer.isEnabled())
541 {
542 _monitorTimer.setEnabled(false);
543 }
544
545 if (_fanMissingErrorTimer && _fanMissingErrorTimer->isEnabled())
546 {
547 _fanMissingErrorTimer->setEnabled(false);
548 }
549
550 std::for_each(_sensors.begin(), _sensors.end(), [](auto& sensor) {
551 if (sensor->timerRunning())
552 {
553 sensor->stopTimer();
554 }
Matt Spinler623635c2021-03-29 13:13:59 -0500555
Matt Spinlerfdfcc672021-06-01 14:51:06 -0600556 sensor->stopCountTimer();
557 });
Matt Spinler7d135642021-02-04 12:44:17 -0600558 }
559#endif
560}
561
Matthew Barth177fe982020-05-26 11:05:19 -0500562} // namespace monitor
563} // namespace fan
564} // namespace phosphor