Class: OpenHAB::Core::Types::QuantityType

Inherits:
Object
  • Object
show all
Includes:
NumericType
Defined in:
lib/openhab/core/types/quantity_type.rb

Overview

QuantityType extends DecimalType to handle physical unit measurement.

QuantityType is part of the [Units of Measurement](www.openhab.org/docs/concepts/units-of-measurement.html) framework in openHAB. It is represented as a decimal number with a unit. You can construct a QuantityType object by using the pipe operator with any Numeric.

Examples:

QuantityTypes can perform math operations between them.

(50 | "°F") + (-25 | "°F") # => 25.0 °F
(100 | "°F") / (2 | "°F") # => 50
(50 | "°F") - (25 | "°F") # => 25 °F
(50 | "°F") + (50 | "°F") # => 100 °F

If the operand is a number, it will be unit-less, but the result of the operation will have a unit. This only works for multiplication and division.

(50 | "°F") * 2 # => 100 °F
(100 | "°F") / 2 # => 50 °F

If the operand is a dimensioned NumberItem it will automatically be converted to a quantity for the operation.

# NumberF = "2 °F"
# NumberC = "2 °C"
(50 | "°F") + NumberF.state # => 52.0 °F
(50 | "°F") + NumberC.state # => 85.60 °F

If the operand is a non-dimensioned NumberItem it can be used only in multiplication and division operations.

# Number Dimensionless = 2
(50 | "°F") * Dimensionless.state # => 100 °F
(50 | "°F") / Dimensionless.state # => 25 °F

Quantities can be compared, if they have comparable units.

(50 | "°F") >  (25 | "°F")
(50 | "°F") >  (525 | "°F")
(50 | "°F") >= (50 | "°F")
(50 | "°F") == (50 | "°F")
(50 | "°F") <  (25 | "°C")

A Range can be used with QuantityType:

((0 | "°C")..(100 | "°C")).cover?(NumberC)

A Range can also be used in a case statement for a dimensioned item:

description = case NumberC.state
              when (-20 | "°C")...(18 | "°C") then "too cold"
              when (18 | "°C")...(25 | "°C") then "comfortable"
              when (25 | "°C")...(40 | "°C") then "too warm"
              else "out of range"
              end

Dimensioned Number Items can be converted to quantities with other units using the | operator

# NumberC = "23 °C"

# Using a unit
logger.info("In Fahrenheit #{NumberC.state | ImperialUnits::FAHRENHEIT }")

# Using a string
logger.info("In Fahrenheit #{NumberC.state | "°F"}")

Dimensionless Number Items can be converted to quantities with units using the | operator

# Dimensionless = 70

# Using a unit
logger.info("In Fahrenheit #{Dimensionless.state | ImperialUnits::FAHRENHEIT }")

# Using a string
logger.info("In Fahrenheit #{Dimensionless.state | "°F"}")

Dimensioned Number Items automatically use their units and convert automatically for math operations

# Number:Temperature NumberC = 23 °C
# Number:Temperature NumberF = 70 °F
NumberC.state - NumberF.state # => 1.88 °C
NumberF.state + NumberC.state # => 143.40 °F

Dimensionless Number Items can be used for multiplication and division.

# Number Dimensionless = 2
# Number:Temperature NumberF = 70 °F
NumberF.state * Dimensionless.state # => 140.0 °F
NumberF.state / Dimensionless.state # => 35.0 °F
Dimensionless.state * NumberF.state # => 140.0 °F
2 * NumberF.state                   # => 140.0 °F

Comparisons work on dimensioned number items with different, but comparable units.

# Number:Temperature NumberC = 23 °C
# Number:Temperature NumberF = 70 °F
NumberC.state > NumberF.state # => true

For certain unit types, such as temperature, all unit needs to be normalized to the comparator for all operations when combining comparison operators with dimensioned numbers.

(NumberC.state | "°F") - (NumberF.state | "°F") < 4 | "°F"

See Also:

Instance Method Summary collapse

Methods included from NumericType

#+@, #eql?, #to_d, #to_f, #to_i

Instance Method Details

#<=>(other) ⇒ Integer?

Comparison

Comparisons against Numeric and DecimalType are allowed only within a unit block to avoid unit ambiguities. Comparisons against other types may be done if supported by that type’s coercion.

Parameters:

Returns:

  • (Integer, nil)

    -1, 0, +1 depending on whether ‘other` is less than, equal to, or greater than self

    ‘nil` is returned if the two values are incomparable.



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/openhab/core/types/quantity_type.rb', line 134

def <=>(other)
  logger.trace("(#{self.class}) #{self} <=> #{other} (#{other.class})")
  case other
  when self.class
    return unitize(other.unit).compare_to(other) if unit == Units::ONE
    return compare_to(other.unitize(unit)) if other.unit == Units::ONE

    return compare_to(other)
  when Numeric, DecimalType
    if (unit = OpenHAB::DSL.unit(dimension))
      return compare_to(QuantityType.new(other, unit))
    end

    return nil # don't allow comparison with numeric outside a unit block
  end

  return nil unless other.respond_to?(:coerce)

  other.coerce(self)&.then { |lhs, rhs| lhs <=> rhs }
end

#coerce(other) ⇒ Array<(QuantityType, QuantityType)>?

Type Coercion

Coerce object to a OpenHAB::Core::Types::QuantityType

Parameters:

Returns:



163
164
165
166
167
168
# File 'lib/openhab/core/types/quantity_type.rb', line 163

def coerce(other)
  logger.trace("Coercing #{self} as a request from #{other.class}")
  return unless other.respond_to?(:to_d)

  [QuantityType.new(other.to_d.to_java, Units::ONE), self]
end

#to_invertible_unit(unit) ⇒ QuantityType Also known as: |

Convert this OpenHAB::Core::Types::QuantityType into another unit.

Examples:

NumberC.state | ImperialUnits::FAHRENHEIT

Parameters:

  • unit (String, javax.measure.Unit)

Returns:



10
# File 'lib/openhab/core/types/quantity_type.rb', line 10

def to_invertible_unit(unit); end