sensor: accept single sensor threshold

Currently, sensors require a couple of LC/UC and/or LNC/UNC. However, in
real hardware design, there might be only one of LC, UC, LNC or UNC
available.
This change allows to specify only single sensor threshold.

Tested:
1. Specify only UC threshold for PSU0_Temp sensor
2. root@mtjade:~# ipmitool sensor get PSU0_TEMP
   Locating sensor record...
   Sensor ID              : PSU0_TEMP (0xf3)
    Entity ID             : 30.58
    Sensor Type (Threshold)  : Temperature
    Sensor Reading        : 26 (+/- 0) degrees C
    Status                : ok
    Lower Non-Recoverable : na
    Lower Critical        : na
    Lower Non-Critical    : na
    Upper Non-Critical    : na
    Upper Critical        : 64.000
    Upper Non-Recoverable : na
    Positive Hysteresis   : Unspecified
    Negative Hysteresis   : Unspecified

Signed-off-by: Thang Q. Nguyen <thang@os.amperecomputing.com>
Change-Id: I70fa136c6d96a6edc2ed1a6a65eee85b6ff62e39
diff --git a/thresholds.hpp b/thresholds.hpp
index 8d557fc..fe88977 100644
--- a/thresholds.hpp
+++ b/thresholds.hpp
@@ -127,40 +127,46 @@
 
     auto tLo = env::getEnv(Thresholds<T>::envLo, sensorType, sensorID);
     auto tHi = env::getEnv(Thresholds<T>::envHi, sensorType, sensorID);
-    if (!tLo.empty() && !tHi.empty())
+    if (!tLo.empty() || !tHi.empty())
     {
         static constexpr bool deferSignals = true;
         auto& bus = *std::get<sdbusplus::bus::bus*>(info);
 
         iface = std::make_shared<T>(bus, objPath.c_str(), deferSignals);
-        auto lo = stod(tLo) * std::pow(10, scale);
-        auto hi = stod(tHi) * std::pow(10, scale);
-        (*iface.*Thresholds<T>::setLo)(lo);
-        (*iface.*Thresholds<T>::setHi)(hi);
-        auto alarmLowState = (*iface.*Thresholds<T>::getAlarmLow)();
-        auto alarmHighState = (*iface.*Thresholds<T>::getAlarmHigh)();
-        (*iface.*Thresholds<T>::alarmLo)(value <= lo);
-        (*iface.*Thresholds<T>::alarmHi)(value >= hi);
-        if (alarmLowState != (value <= lo))
+        if (!tLo.empty())
         {
-            if (value <= lo)
+            auto lo = stod(tLo) * std::pow(10, scale);
+            (*iface.*Thresholds<T>::setLo)(lo);
+            auto alarmLowState = (*iface.*Thresholds<T>::getAlarmLow)();
+            (*iface.*Thresholds<T>::alarmLo)(value <= lo);
+            if (alarmLowState != (value <= lo))
             {
-                (*iface.*Thresholds<T>::assertLowSignal)(value);
-            }
-            else
-            {
-                (*iface.*Thresholds<T>::deassertLowSignal)(value);
+                if (value <= lo)
+                {
+                    (*iface.*Thresholds<T>::assertLowSignal)(value);
+                }
+                else
+                {
+                    (*iface.*Thresholds<T>::deassertLowSignal)(value);
+                }
             }
         }
-        if (alarmHighState != (value >= hi))
+        if (!tHi.empty())
         {
-            if (value >= hi)
+            auto hi = stod(tHi) * std::pow(10, scale);
+            (*iface.*Thresholds<T>::setHi)(hi);
+            auto alarmHighState = (*iface.*Thresholds<T>::getAlarmHigh)();
+            (*iface.*Thresholds<T>::alarmHi)(value >= hi);
+            if (alarmHighState != (value >= hi))
             {
-                (*iface.*Thresholds<T>::assertHighSignal)(value);
-            }
-            else
-            {
-                (*iface.*Thresholds<T>::deassertHighSignal)(value);
+                if (value >= hi)
+                {
+                    (*iface.*Thresholds<T>::assertHighSignal)(value);
+                }
+                else
+                {
+                    (*iface.*Thresholds<T>::deassertHighSignal)(value);
+                }
             }
         }
         auto type = Thresholds<T>::type;