-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
persistence.rb
123 lines (110 loc) · 4.48 KB
/
persistence.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# frozen_string_literal: true
module OpenHAB
module DSL
module MonkeyPatch
module Items
#
# Persistence extension for Items
#
module Persistence
java_import Java::OrgOpenhabCoreTypesUtil::UnitUtils
# A wrapper for OpenHAB's HistoricItem that returns the state directly
class HistoricState < SimpleDelegator
attr_reader :timestamp, :state
def initialize(state, timestamp)
@state = state
@timestamp = timestamp
super(@state)
end
end
# All persistence methods that could return a Quantity
QUANTITY_METHODS = %i[average_since
delta_since
deviation_since
sum_since
variance_since].freeze
# All persistence methods that require a timestamp
PERSISTENCE_METHODS = (QUANTITY_METHODS +
%i[changed_since
evolution_rate
historic_state
maximum_since
minimum_since
updated_since]).freeze
%i[persist last_update].each do |method|
define_method(method) do |service = nil|
service ||= persistence_service
PersistenceExtensions.public_send(method, self, service&.to_s)
end
end
#
# Return the previous state of the item
#
# @param skip_equal [Boolean] if true, skips equal state values and
# searches the first state not equal the current state
# @param service [String] the name of the PersistenceService to use
#
# @return the previous state or nil if no previous state could be found,
# or if the default persistence service is not configured or
# does not refer to a valid service
#
def previous_state(service = nil, skip_equal: false)
service ||= persistence_service
result = PersistenceExtensions.previous_state(self, skip_equal, service&.to_s)
HistoricState.new(quantify(result.state), result.timestamp)
end
PERSISTENCE_METHODS.each do |method|
define_method(method) do |timestamp, service = nil|
service ||= persistence_service
result = PersistenceExtensions.public_send(method, self, to_zdt(timestamp), service&.to_s)
if result.is_a? Java::OrgOpenhabCorePersistence::HistoricItem
return HistoricState.new(quantify(result.state), result.timestamp)
end
QUANTITY_METHODS.include?(method) ? quantify(result) : result
end
end
private
#
# Convert timestamp to ZonedDateTime if it's a TemporalAmount
#
# @param [Object] timestamp to convert
#
# @return [ZonedDateTime]
#
def to_zdt(timestamp)
if timestamp.is_a? Java::JavaTimeTemporal::TemporalAmount
logger.trace("Converting #{timestamp} (#{timestamp.class}) to ZonedDateTime")
Java::JavaTime::ZonedDateTime.now.minus(timestamp)
else
timestamp
end
end
#
# Convert value to Quantity if it is a DecimalType and a unit is defined
#
# @param [Object] value The value to convert
#
# @return [Object] Quantity or the original value
#
def quantify(value)
if value.is_a?(Java::OrgOpenhabCoreLibraryTypes::DecimalType) && state_description&.pattern
item_unit = UnitUtils.parse_unit(state_description.pattern)
logger.trace("Unitizing #{value} with unit #{item_unit}")
Quantity.new(Java::OrgOpenhabCoreLibraryTypes::QuantityType.new(value.to_big_decimal, item_unit))
else
value
end
end
#
# Get the specified persistence service from the current thread local variable
#
# @return [Object] Persistence service name as String or Symbol, or nil if not set
#
def persistence_service
Thread.current.thread_variable_get(:persistence_service)
end
end
end
end
end
end