Skip to content

Commit

Permalink
feat(persistence): convert HistoricItem methods to directly return it…
Browse files Browse the repository at this point in the history
…s state
  • Loading branch information
jimtng committed Mar 11, 2021
1 parent 7a7f411 commit 942d7ea
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 25 deletions.
51 changes: 29 additions & 22 deletions docs/usage/misc/persistence.md
Expand Up @@ -11,31 +11,31 @@ grand_parent: Usage

[Persistence](https://www.openhab.org/docs/configuration/persistence.html) functions can be accessed through the item object. The following methods related to persistence are available:

| Method | Parameters | Example |
| ----------------- | ------------------------------------- | --------------------------------------------------------------- |
| `persist` | service | `Item1.persist` |
| `last_update` | service | `Item1.last_update` |
| `previous_state` | skip_equal: (default: false), service | `Item1.previous_state` `Item1.previous_state(skip_equal: true)` |
| `average_since` | timestamp, service | `Item1.average_since(-1.hours, :influxdb)` |
| `changed_since` | timestamp, service | |
| `delta_since` | timestamp, service | |
| `deviation_since` | timestamp, service | |
| `evolution_rate` | timestamp, service | |
| `historic_state` | timestamp, service | |
| `maximum_since` | timestamp, service | |
| `minimum_since` | timestamp, service | |
| `sum_since` | timestamp, service | |
| `updated_since` | timestamp, service | |
| `variance_since` | timestamp, service | |
| Method | Parameters | Return Value | Example |
| ----------------- | ------------------------------------- | ----------------------- | --------------------------------------------------------------- |
| `persist` | service | Nil | `Item1.persist` |
| `last_update` | service | ZonedDateTime | `Item1.last_update` |
| `previous_state` | skip_equal: (default: false), service | item state | `Item1.previous_state` `Item1.previous_state(skip_equal: true)` |
| `average_since` | timestamp, service | DecimalType or Quantity | `Item1.average_since(-1.hours, :influxdb)` |
| `changed_since` | timestamp, service | boolean | |
| `delta_since` | timestamp, service | DecimalType or Quantity | |
| `deviation_since` | timestamp, service | DecimalType or Quantity | |
| `evolution_rate` | timestamp, service | DecimalType | |
| `historic_state` | timestamp, service | HistoricState | |
| `maximum_since` | timestamp, service | HistoricState | |
| `minimum_since` | timestamp, service | HistoricState | |
| `sum_since` | timestamp, service | DecimalType or Quantity | |
| `updated_since` | timestamp, service | boolean | |
| `variance_since` | timestamp, service | DecimalType or Quantity | |

* The `timestamp` parameter accepts a java ZonedDateTime or a [Duration](../duration/) object that specifies how far back in time.
* The `service` optional parameter accepts the name of the persistence service to use, as a String or Symbol. When not specified, the system's default persistence service will be used.
* The return value of the following persistence methods is a [Quantity](../../items/number/#quantities) when the corresponding item is a dimensioned NumberItem:
* `average_since`
* `delta_since`
* `deviation_since`
* `sum_since`
* `variance_since`
* Dimensioned NumberItems will return a [Quantity](../../items/number/#quantities) object
* `HistoricState` holds the item state and the timestamp data from OpenHAB's [HistoricItem](https://openhab.org/javadoc/latest/org/openhab/core/persistence/historicitem). It contains the following properties:
* `timestamp` - a ZonedDateTime object indicating the timestamp of the persisted data
* `state` - the state of the item persisted at the timestamp above. This will be a Quantity for dimensioned NumberItem. It is not necessary to access the `state` property, as the HistoricState itself will return the state. See the example below.



### Examples:

Expand Down Expand Up @@ -64,6 +64,13 @@ if Power_Usage.average_since(15.minutes) > '5 kW'
end
```
HistoricState
```ruby
max = Power_Usage.maximum_since(24.hours)
logger.info("Max power usage: #{max}, at: #{max.timestamp})
```

## Persistence Block

A persistence block can group multiple persistence operations together under a single service. For example, instead of:
Expand Down
25 changes: 23 additions & 2 deletions features/persistence.feature
Expand Up @@ -77,8 +77,8 @@ Feature: persistence
| Number:Power | Max_Power | Max Power | %.1f kW | MAX |

And items:
| type | name | label | pattern | state | groups |
| Number:Power | Number_Power | Power | %.1f kW | 0 kW | Max_Power |
| type | name | label | pattern | state | groups |
| Number:Power | Number_Power | Power | %.1f kW | 0 kW | Max_Power |

And code in a rules file:
"""
Expand All @@ -95,3 +95,24 @@ Feature: persistence
When I deploy the rule
Then It should log 'Average: 3 kW' within 10 seconds
And It should log 'Average Max: 3 kW' within 10 seconds

Scenario: Check that HistoricState directly returns a state
Given items:
| type | name | label | pattern | state |
| Number:Power | Number_Power | Power | %.1f kW | 0 kW |

And code in a rules file:
"""
rule 'Check HistoricState' do
on_start
run { Number_Power.update "3 kW" }
delay 3.second
run do
max = Number_Power.maximum_since(10.seconds, :mapdb)
logger.info("Max time: #{max.timestamp}") # If this caused an error, the next line won't execute
logger.info("Max: #{max}") if max == max.state
end
end
"""
When I deploy the rule
Then It should log 'Max: 3 kW' within 10 seconds
19 changes: 18 additions & 1 deletion lib/openhab/dsl/monkey_patch/items/persistence.rb
Expand Up @@ -9,6 +9,18 @@ module 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
Expand Down Expand Up @@ -45,13 +57,18 @@ module Persistence
#
def previous_state(service = nil, skip_equal: false)
service ||= persistence_service
PersistenceExtensions.previous_state(self, skip_equal, service&.to_s)
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
Expand Down

0 comments on commit 942d7ea

Please sign in to comment.