openhab-scripting 5.27.2 → 5.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/openhab/core/actions/notification.rb +5 -5
- data/lib/openhab/core/entity_lookup.rb +55 -3
- data/lib/openhab/core/events/timer_event.rb +23 -0
- data/lib/openhab/core/types/date_time_type.rb +11 -0
- data/lib/openhab/core_ext/java/instant.rb +138 -2
- data/lib/openhab/core_ext/java/local_date.rb +9 -0
- data/lib/openhab/core_ext/java/local_time.rb +9 -0
- data/lib/openhab/core_ext/java/month.rb +10 -0
- data/lib/openhab/core_ext/java/month_day.rb +9 -0
- data/lib/openhab/core_ext/java/time.rb +2 -0
- data/lib/openhab/core_ext/java/zoned_date_time.rb +54 -6
- data/lib/openhab/core_ext/ruby/date.rb +21 -0
- data/lib/openhab/core_ext/ruby/date_time.rb +6 -0
- data/lib/openhab/core_ext/ruby/time.rb +11 -2
- data/lib/openhab/dsl/items/timed_command.rb +11 -4
- data/lib/openhab/dsl/rules/builder.rb +1 -1
- data/lib/openhab/dsl/sitemaps/builder.rb +12 -3
- data/lib/openhab/dsl/version.rb +1 -1
- data/lib/openhab/dsl.rb +9 -55
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 795ee1035ecfb1a7f38f50243ed0d28af8a578e7d586eedd97c8362d6f4cd03d
|
4
|
+
data.tar.gz: d1785eb66e599bb3b78a3ab473618a080bffa117a53ddaf13c506e298806d8ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3af8371312fdf0dce313b87513db7540545639ef440358c1256f03fe8018768c33636f5aff09bcc1cdceb9a04988492921651fd4ed269f824b18a330feec8088
|
7
|
+
data.tar.gz: 698841f7a0fd45ca777e1561b915e9c695c309ba9ac802d7a319733f6501539959d55ce2d6ddae8fd9cbee4c35d8d089da74d74fa6011c9b6978b68028449b1c
|
@@ -4,14 +4,14 @@ module OpenHAB
|
|
4
4
|
module Core
|
5
5
|
module Actions
|
6
6
|
#
|
7
|
-
# Provides methods for {https://
|
7
|
+
# Provides methods for {https://www.openhab.org/addons/integrations/openhabcloud/#cloud-notification-actions
|
8
8
|
# openHAB Cloud Notification Actions}.
|
9
9
|
#
|
10
10
|
class Notification
|
11
11
|
class << self
|
12
12
|
#
|
13
13
|
# Send a notification using
|
14
|
-
# {https://
|
14
|
+
# {https://www.openhab.org/addons/integrations/openhabcloud/#cloud-notification-actions
|
15
15
|
# openHAB Cloud Notification Action}.
|
16
16
|
#
|
17
17
|
# @param msg [String] The message to send.
|
@@ -27,7 +27,7 @@ module OpenHAB
|
|
27
27
|
# Subsequent notifications using the same reference ID will
|
28
28
|
# update/overwrite the existing notification with the same ID.
|
29
29
|
# @param on_click [String, nil] The action to be performed when the user clicks on the notification.
|
30
|
-
# Specified using the {https://
|
30
|
+
# Specified using the {https://www.openhab.org/addons/integrations/openhabcloud/#action-syntax
|
31
31
|
# action syntax}.
|
32
32
|
# @param attachment [String, Item, nil] The URL of the media attachment to be displayed with the notification.
|
33
33
|
# This can either be a fully qualified URL, prefixed with
|
@@ -36,7 +36,7 @@ module OpenHAB
|
|
36
36
|
# or an image item.
|
37
37
|
# @param buttons [Array<String>, Hash<String, String>, nil] Buttons to include in the notification.
|
38
38
|
# - In array form, each element is specified as `Title=$action`, where `$action` follows the
|
39
|
-
# {https://
|
39
|
+
# {https://www.openhab.org/addons/integrations/openhabcloud/#action-syntax action syntax}.
|
40
40
|
# - In hash form, the keys are the button titles and the values are the actions.
|
41
41
|
#
|
42
42
|
# The maximum number of buttons is 3.
|
@@ -91,7 +91,7 @@ module OpenHAB
|
|
91
91
|
tag ||= severity
|
92
92
|
args.push(msg.to_s, icon&.to_s, tag&.to_s)
|
93
93
|
|
94
|
-
#
|
94
|
+
# @deprecated OH 4.1
|
95
95
|
if Core.version >= Core::V4_2
|
96
96
|
buttons ||= []
|
97
97
|
buttons = buttons.map { |title, action| "#{title}=#{action}" } if buttons.is_a?(Hash)
|
@@ -13,9 +13,6 @@ module OpenHAB
|
|
13
13
|
# it must be replaced with an underscore `_`. So to access `astro:sun:home`, use `astro_sun_home`
|
14
14
|
# as an alternative to `things["astro:sun:home"]`
|
15
15
|
#
|
16
|
-
# @see OpenHAB::DSL.items items[]
|
17
|
-
# @see OpenHAB::DSL.things things[]
|
18
|
-
#
|
19
16
|
# @example Accessing Items and Groups
|
20
17
|
# gAll_Lights # Access the gAll_Lights group. It is the same as items["gAll_Lights"]
|
21
18
|
# Kitchen_Light.on # The openHAB object for the Kitchen_Light item and send an ON command
|
@@ -66,6 +63,61 @@ module OpenHAB
|
|
66
63
|
end
|
67
64
|
end
|
68
65
|
|
66
|
+
#
|
67
|
+
# Fetches all items from the item registry
|
68
|
+
#
|
69
|
+
# @return [Core::Items::Registry]
|
70
|
+
#
|
71
|
+
# The examples all assume the following items exist.
|
72
|
+
#
|
73
|
+
# ```xtend
|
74
|
+
# Dimmer DimmerTest "Test Dimmer"
|
75
|
+
# Switch SwitchTest "Test Switch"
|
76
|
+
# ```
|
77
|
+
#
|
78
|
+
# @example
|
79
|
+
# logger.info("Item Count: #{items.count}") # Item Count: 2
|
80
|
+
# logger.info("Items: #{items.map(&:label).sort.join(', ')}") # Items: Test Dimmer, Test Switch'
|
81
|
+
# logger.info("DimmerTest exists? #{items.key?('DimmerTest')}") # DimmerTest exists? true
|
82
|
+
# logger.info("StringTest exists? #{items.key?('StringTest')}") # StringTest exists? false
|
83
|
+
#
|
84
|
+
# @example
|
85
|
+
# rule 'Use dynamic item lookup to increase related dimmer brightness when switch is turned on' do
|
86
|
+
# changed SwitchTest, to: ON
|
87
|
+
# triggered { |item| items[item.name.gsub('Switch','Dimmer')].brighten(10) }
|
88
|
+
# end
|
89
|
+
#
|
90
|
+
# @example
|
91
|
+
# rule 'search for a suitable item' do
|
92
|
+
# on_load
|
93
|
+
# triggered do
|
94
|
+
# # Send ON to DimmerTest if it exists, otherwise send it to SwitchTest
|
95
|
+
# (items['DimmerTest'] || items['SwitchTest'])&.on
|
96
|
+
# end
|
97
|
+
# end
|
98
|
+
#
|
99
|
+
def items
|
100
|
+
Core::Items::Registry.instance
|
101
|
+
end
|
102
|
+
|
103
|
+
#
|
104
|
+
# Get all things known to openHAB
|
105
|
+
#
|
106
|
+
# @return [Core::Things::Registry] all Thing objects known to openHAB
|
107
|
+
#
|
108
|
+
# @example
|
109
|
+
# things.each { |thing| logger.info("Thing: #{thing.uid}")}
|
110
|
+
# logger.info("Thing: #{things['astro:sun:home'].uid}")
|
111
|
+
# homie_things = things.select { |t| t.thing_type_uid == "mqtt:homie300" }
|
112
|
+
# zwave_things = things.select { |t| t.binding_id == "zwave" }
|
113
|
+
# homeseer_dimmers = zwave_things.select { |t| t.thing_type_uid.id == "homeseer_hswd200_00_000" }
|
114
|
+
# things['zwave:device:512:node90'].uid.bridge_ids # => ["512"]
|
115
|
+
# things['mqtt:topic:4'].uid.bridge_ids # => []
|
116
|
+
#
|
117
|
+
def things
|
118
|
+
Core::Things::Registry.instance
|
119
|
+
end
|
120
|
+
|
69
121
|
#
|
70
122
|
# Automatically looks up openHAB items and things in appropriate registries
|
71
123
|
#
|
@@ -34,6 +34,29 @@ module OpenHAB
|
|
34
34
|
payload&.[](:itemName)&.then { |item_name| EntityLookup.lookup_item(item_name) }
|
35
35
|
end
|
36
36
|
|
37
|
+
#
|
38
|
+
# @!attribute [r] time_only?
|
39
|
+
# @return [Boolean]
|
40
|
+
# `true` when this event was triggered by a {Core::Items::DateTimeItem DateTimeItem} with `timeOnly` set.
|
41
|
+
# `false` when this event wasn't triggered by a DateTimeItem or the `timeOnly` flag is not set.
|
42
|
+
# @see DSL::Rules::BuilderDSL::every #every trigger
|
43
|
+
# @see DSL::Rules::BuilderDSL::at #at trigger
|
44
|
+
# @since openHAB 4.3
|
45
|
+
#
|
46
|
+
def time_only?
|
47
|
+
!!payload&.[](:timeOnly)
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# @!attribute [r] offset
|
52
|
+
# @return [Duration, nil] The offset from the configured time for this DateTime trigger event.
|
53
|
+
# `nil` when this event wasn't triggered by a DateTime trigger.
|
54
|
+
# @since openHAB 4.3
|
55
|
+
#
|
56
|
+
def offset
|
57
|
+
payload&.[](:offset)&.seconds
|
58
|
+
end
|
59
|
+
|
37
60
|
#
|
38
61
|
# @!attribute [r] time
|
39
62
|
# @return [LocalTime, nil] The configured time for this TimeOfDay trigger event.
|
@@ -51,6 +51,17 @@ module OpenHAB
|
|
51
51
|
zoned_date_time
|
52
52
|
end
|
53
53
|
|
54
|
+
# @!visibility private
|
55
|
+
def to_instant(_context = nil)
|
56
|
+
# @deprecated OH 3.4 getInstant() was added in OH 4.0
|
57
|
+
return get_instant if respond_to?(:get_instant)
|
58
|
+
|
59
|
+
zoned_date_time.to_instant
|
60
|
+
end
|
61
|
+
|
62
|
+
# @!method to_instant
|
63
|
+
# @return [Instant]
|
64
|
+
|
54
65
|
# act like a Ruby Time
|
55
66
|
def_delegator :zoned_date_time, :month_value, :month
|
56
67
|
def_delegator :zoned_date_time, :day_of_month, :mday
|
@@ -1,12 +1,148 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "forwardable"
|
4
|
+
|
5
|
+
require_relative "time"
|
6
|
+
|
3
7
|
module OpenHAB
|
4
8
|
module CoreExt
|
5
9
|
module Java
|
6
|
-
|
10
|
+
Instant = java.time.Instant
|
7
11
|
|
8
12
|
# Extensions to {java.time.Instant}
|
9
|
-
class Instant < java.lang.Object
|
13
|
+
class Instant < java.lang.Object
|
14
|
+
extend Forwardable
|
15
|
+
include Time
|
16
|
+
include Between
|
17
|
+
|
18
|
+
class << self # rubocop:disable Lint/EmptyClass
|
19
|
+
# @!scope class
|
20
|
+
|
21
|
+
# @!attribute [r] now
|
22
|
+
# @return [Instant]
|
23
|
+
|
24
|
+
# @!method parse(text, formatter = nil)
|
25
|
+
# Parses a string into an Instant object.
|
26
|
+
#
|
27
|
+
# @param [String] text The text to parse.
|
28
|
+
# @param [java.time.format.DateTimeFormatter] formatter The formatter to use.
|
29
|
+
# @return [Instant]
|
30
|
+
end
|
31
|
+
|
32
|
+
# @!scope instance
|
33
|
+
|
34
|
+
# @!method to_local_time
|
35
|
+
# @return [LocalTime]
|
36
|
+
# @!method to_local_date
|
37
|
+
# @return [LocalDate]
|
38
|
+
# @!method to_month_day
|
39
|
+
# @return [MonthDay]
|
40
|
+
# @!method to_date
|
41
|
+
# @return [Date]
|
42
|
+
# @!method to_month
|
43
|
+
# @return [Month]
|
44
|
+
# @!method yesterday?
|
45
|
+
# (see OpenHAB::CoreExt::Java::ZonedDateTime#yesterday?)
|
46
|
+
# @!method today?
|
47
|
+
# (see OpenHAB::CoreExt::Java::ZonedDateTime#today?)
|
48
|
+
# @!method tomorrow?
|
49
|
+
# (see OpenHAB::CoreExt::Java::ZonedDateTime#tomorrow?)
|
50
|
+
def_delegators :to_zoned_date_time,
|
51
|
+
:to_local_time,
|
52
|
+
:to_local_date,
|
53
|
+
:to_date,
|
54
|
+
:to_month_day,
|
55
|
+
:to_month,
|
56
|
+
:yesterday?,
|
57
|
+
:today?,
|
58
|
+
:tomorrow?
|
59
|
+
|
60
|
+
# @param [TemporalAmount, #to_instant, #to_zoned_date_time, Numeric] other
|
61
|
+
# If other is a Numeric, it's interpreted as seconds.
|
62
|
+
# @return [Duration] If other responds to #to_zoned_date_time
|
63
|
+
# @return [Instant] If other is a TemporalAmount
|
64
|
+
def -(other)
|
65
|
+
if other.is_a?(Instant)
|
66
|
+
java.time.Duration.between(other, self)
|
67
|
+
elsif other.respond_to?(:to_instant)
|
68
|
+
java.time.Duration.between(other.to_instant, self)
|
69
|
+
elsif other.respond_to?(:to_zoned_date_time)
|
70
|
+
java.time.Duration.between(other.to_zoned_date_time.to_instant, self)
|
71
|
+
elsif other.is_a?(Numeric)
|
72
|
+
minus(other.seconds)
|
73
|
+
else
|
74
|
+
minus(other)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# @param [TemporalAmount, Numeric] other
|
79
|
+
# If other is a Numeric, it's interpreted as seconds.
|
80
|
+
# @return [Instant]
|
81
|
+
def +(other)
|
82
|
+
return plus(other.seconds) if other.is_a?(Numeric)
|
83
|
+
|
84
|
+
plus(other)
|
85
|
+
end
|
86
|
+
|
87
|
+
#
|
88
|
+
# The number of seconds since the Unix epoch.
|
89
|
+
# @return [Integer]
|
90
|
+
#
|
91
|
+
def to_i
|
92
|
+
epoch_second
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
# The number of seconds since the Unix epoch.
|
97
|
+
# @return [Float]
|
98
|
+
#
|
99
|
+
def to_f
|
100
|
+
((epoch_second * 1_000_000_000) + nano).fdiv(1_000_000_000.0)
|
101
|
+
end
|
102
|
+
|
103
|
+
# This comes from JRuby
|
104
|
+
|
105
|
+
# @!method to_time
|
106
|
+
# @return [Time]
|
107
|
+
|
108
|
+
# @return [Integer, nil]
|
109
|
+
def <=>(other)
|
110
|
+
logger.trace { "(#{self.class}) #{self} <=> #{other} (#{other.class})" }
|
111
|
+
# compare instants, otherwise it will differ by timezone, which we don't want
|
112
|
+
# (use eql? if you care about that)
|
113
|
+
if other.respond_to?(:to_instant)
|
114
|
+
logger.trace { "Comparing #{self} to #{other.to_instant}" }
|
115
|
+
compare_to(other.to_instant(to_zoned_date_time))
|
116
|
+
elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(self))
|
117
|
+
lhs <=> rhs
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# @param [ZonedDateTime, nil] context A {ZonedDateTime} used to match the zone id. Defaults to UTC.
|
122
|
+
# @return [ZonedDateTime]
|
123
|
+
def to_zoned_date_time(context = nil)
|
124
|
+
zone = context&.zone || java.time.ZoneOffset::UTC
|
125
|
+
at_zone(zone)
|
126
|
+
end
|
127
|
+
|
128
|
+
# @!visibility private
|
129
|
+
def to_instant(_context = nil)
|
130
|
+
self
|
131
|
+
end
|
132
|
+
|
133
|
+
#
|
134
|
+
# Converts `other` to {Instant}, if possible
|
135
|
+
#
|
136
|
+
# @param [#to_instant] other
|
137
|
+
# @return [Array, nil]
|
138
|
+
#
|
139
|
+
def coerce(other)
|
140
|
+
logger.trace { "Coercing #{self} as a request from #{other.class}" }
|
141
|
+
return [other.to_instant(to_zoned_date_time), self] if other.respond_to?(:to_instant)
|
142
|
+
|
143
|
+
[other.to_zoned_date_time(zoned_date_time).to_instant, self] if other.respond_to?(:to_zoned_date_time)
|
144
|
+
end
|
145
|
+
end
|
10
146
|
end
|
11
147
|
end
|
12
148
|
end
|
@@ -96,6 +96,15 @@ module OpenHAB
|
|
96
96
|
zone = context&.zone || java.time.ZoneId.system_default
|
97
97
|
at_start_of_day(zone)
|
98
98
|
end
|
99
|
+
|
100
|
+
# @param [ZonedDateTime, nil] context
|
101
|
+
# A {ZonedDateTime} used to fill in missing fields
|
102
|
+
# during conversion. {ZonedDateTime.now} is assumed if not given.
|
103
|
+
# @return [Instant]
|
104
|
+
def to_instant(context = nil)
|
105
|
+
zone = context&.zone || java.time.ZoneOffset::UTC
|
106
|
+
at_start_of_day(zone).to_instant
|
107
|
+
end
|
99
108
|
end
|
100
109
|
end
|
101
110
|
end
|
@@ -111,6 +111,15 @@ module OpenHAB
|
|
111
111
|
context ||= ZonedDateTime.now
|
112
112
|
context.with(self)
|
113
113
|
end
|
114
|
+
|
115
|
+
# @param [ZonedDateTime, nil] context
|
116
|
+
# A {ZonedDateTime} used to fill in missing fields
|
117
|
+
# during conversion. {ZonedDateTime.now} is assumed if not given.
|
118
|
+
# @return [Instant]
|
119
|
+
def to_instant(context = nil)
|
120
|
+
context ||= Instant.now.to_zoned_date_time
|
121
|
+
to_zoned_date_time(context).to_instant
|
122
|
+
end
|
114
123
|
end
|
115
124
|
end
|
116
125
|
end
|
@@ -62,6 +62,16 @@ module OpenHAB
|
|
62
62
|
def to_zoned_date_time(context = nil)
|
63
63
|
to_local_date(context).to_zoned_date_time(context)
|
64
64
|
end
|
65
|
+
|
66
|
+
# @param [ZonedDateTime, nil] context
|
67
|
+
# A {ZonedDateTime} used to fill in the year during conversion,
|
68
|
+
# with the date set to the first day of the month.
|
69
|
+
# {Instant.now} is assumed if not given.
|
70
|
+
# @return [Instant]
|
71
|
+
def to_instant(context = nil)
|
72
|
+
context ||= Instant.now.to_zoned_date_time
|
73
|
+
to_local_date(context).to_instant
|
74
|
+
end
|
65
75
|
end
|
66
76
|
end
|
67
77
|
end
|
@@ -112,6 +112,15 @@ module OpenHAB
|
|
112
112
|
def to_zoned_date_time(context = nil)
|
113
113
|
to_local_date(context).to_zoned_date_time(context)
|
114
114
|
end
|
115
|
+
|
116
|
+
# @param [ZonedDateTime, nil] context
|
117
|
+
# A {ZonedDateTime} used to fill in missing year during conversion,
|
118
|
+
# {ZonedDateTime.now} is assumed if not given.
|
119
|
+
# @return [Instant]
|
120
|
+
def to_instant(context = nil)
|
121
|
+
context ||= Instant.now.to_zoned_date_time
|
122
|
+
to_local_date(context).to_instant
|
123
|
+
end
|
115
124
|
end
|
116
125
|
end
|
117
126
|
end
|
@@ -38,6 +38,7 @@ module OpenHAB
|
|
38
38
|
# less than, equal to, or greater than self
|
39
39
|
#
|
40
40
|
def <=>(other)
|
41
|
+
logger.trace { "(#{self.class}) #{self} <=> #{other} (#{other.class})" }
|
41
42
|
if other.is_a?(self.class)
|
42
43
|
compare_to(other)
|
43
44
|
elsif other.respond_to?(:coerce)
|
@@ -50,6 +51,7 @@ module OpenHAB
|
|
50
51
|
# Convert `other` to this class, if possible
|
51
52
|
# @return [Array, nil]
|
52
53
|
def coerce(other)
|
54
|
+
logger.trace { "Coercing #{self} as a request from #{other.class}" }
|
53
55
|
coercion_method = self.class.coercion_method
|
54
56
|
return unless other.respond_to?(coercion_method)
|
55
57
|
return [other.send(coercion_method), self] if other.method(coercion_method).arity.zero?
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "forwardable"
|
4
|
+
|
3
5
|
require_relative "time"
|
4
6
|
|
5
7
|
module OpenHAB
|
@@ -9,6 +11,7 @@ module OpenHAB
|
|
9
11
|
|
10
12
|
# Extensions to {java.time.ZonedDateTime}
|
11
13
|
class ZonedDateTime
|
14
|
+
extend Forwardable
|
12
15
|
include Time
|
13
16
|
include Between
|
14
17
|
|
@@ -60,20 +63,20 @@ module OpenHAB
|
|
60
63
|
end
|
61
64
|
|
62
65
|
#
|
66
|
+
# @!method to_i
|
63
67
|
# The number of seconds since the Unix epoch.
|
64
68
|
#
|
65
69
|
# @return [Integer]
|
66
|
-
|
67
|
-
to_instant.epoch_second
|
68
|
-
end
|
70
|
+
#
|
69
71
|
|
70
72
|
#
|
73
|
+
# @!method to_f
|
71
74
|
# The number of seconds since the Unix epoch.
|
72
75
|
#
|
73
76
|
# @return [Float]
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
+
#
|
78
|
+
|
79
|
+
delegate %i[to_i to_f] => :to_instant
|
77
80
|
|
78
81
|
# @return [Date]
|
79
82
|
def to_date
|
@@ -103,6 +106,36 @@ module OpenHAB
|
|
103
106
|
self
|
104
107
|
end
|
105
108
|
|
109
|
+
#
|
110
|
+
# Returns true if the date, converted to the system time zone, is yesterday.
|
111
|
+
#
|
112
|
+
# @return [true, false]
|
113
|
+
#
|
114
|
+
def yesterday?
|
115
|
+
with_zone_same_instant(ZoneId.system_default).to_local_date == LocalDate.now - 1
|
116
|
+
end
|
117
|
+
|
118
|
+
#
|
119
|
+
# Returns true if the date, converted to the system time zone, is today.
|
120
|
+
#
|
121
|
+
# This is the equivalent of checking if the current datetime is between midnight and end of the day
|
122
|
+
# of the system time zone.
|
123
|
+
#
|
124
|
+
# @return [true, false]
|
125
|
+
#
|
126
|
+
def today?
|
127
|
+
with_zone_same_instant(ZoneId.system_default).to_local_date == LocalDate.now
|
128
|
+
end
|
129
|
+
|
130
|
+
#
|
131
|
+
# Returns true if the date, converted to the system time zone, is tomorrow.
|
132
|
+
#
|
133
|
+
# @return [true, false]
|
134
|
+
#
|
135
|
+
def tomorrow?
|
136
|
+
with_zone_same_instant(ZoneId.system_default).to_local_date == LocalDate.now + 1
|
137
|
+
end
|
138
|
+
|
106
139
|
# @group Ephemeris Methods
|
107
140
|
# (see CoreExt::Ephemeris)
|
108
141
|
|
@@ -196,6 +229,20 @@ module OpenHAB
|
|
196
229
|
end
|
197
230
|
end
|
198
231
|
|
232
|
+
# @!visibility private
|
233
|
+
alias_method :raw_to_instant, :to_instant
|
234
|
+
|
235
|
+
# @!visibility private
|
236
|
+
def to_instant(_context = nil)
|
237
|
+
raw_to_instant
|
238
|
+
end
|
239
|
+
|
240
|
+
#
|
241
|
+
# @!method to_instant
|
242
|
+
# Converts this object to an {Instant}
|
243
|
+
# @return [Instant]
|
244
|
+
#
|
245
|
+
|
199
246
|
#
|
200
247
|
# Converts `other` to {ZonedDateTime}, if possible
|
201
248
|
#
|
@@ -203,6 +250,7 @@ module OpenHAB
|
|
203
250
|
# @return [Array, nil]
|
204
251
|
#
|
205
252
|
def coerce(other)
|
253
|
+
logger.trace { "Coercing #{self} as a request from #{other.class}" }
|
206
254
|
[other.to_zoned_date_time(self), self] if other.respond_to?(:to_zoned_date_time)
|
207
255
|
end
|
208
256
|
end
|
@@ -1,9 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "forwardable"
|
3
4
|
require "date"
|
4
5
|
|
5
6
|
# Extensions to Date
|
6
7
|
class Date
|
8
|
+
extend Forwardable
|
7
9
|
include OpenHAB::CoreExt::Between
|
8
10
|
include OpenHAB::CoreExt::Ephemeris
|
9
11
|
|
@@ -53,6 +55,14 @@ class Date
|
|
53
55
|
java.time.MonthDay.of(month, day)
|
54
56
|
end
|
55
57
|
|
58
|
+
# @!method yesterday?
|
59
|
+
# (see OpenHAB::CoreExt::Java::ZonedDateTime#yesterday?)
|
60
|
+
# @!method today?
|
61
|
+
# (see OpenHAB::CoreExt::Java::ZonedDateTime#today?)
|
62
|
+
# @!method tomorrow?
|
63
|
+
# (see OpenHAB::CoreExt::Java::ZonedDateTime#tomorrow?)
|
64
|
+
def_delegators :to_zoned_date_time, :yesterday?, :today?, :tomorrow?
|
65
|
+
|
56
66
|
# @param [ZonedDateTime, nil] context
|
57
67
|
# A {ZonedDateTime} used to fill in missing fields during conversion.
|
58
68
|
# {OpenHAB::CoreExt::Java::ZonedDateTime.now ZonedDateTime.now} is assumed
|
@@ -62,6 +72,16 @@ class Date
|
|
62
72
|
to_local_date.to_zoned_date_time(context)
|
63
73
|
end
|
64
74
|
|
75
|
+
# @param [ZonedDateTime, nil] context
|
76
|
+
# A {ZonedDateTime} used to fill in missing fields during conversion.
|
77
|
+
# {OpenHAB::CoreExt::Java::ZonedDateTime.now ZonedDateTime.now} is assumed
|
78
|
+
# if not given.
|
79
|
+
# @return [Instant]
|
80
|
+
def to_instant(context = nil)
|
81
|
+
context ||= Instant.now.to_zoned_date_time
|
82
|
+
to_zoned_date_time(context).to_instant
|
83
|
+
end
|
84
|
+
|
65
85
|
# @return [Integer, nil]
|
66
86
|
def compare_with_coercion(other)
|
67
87
|
return compare_without_coercion(other) if other.is_a?(self.class)
|
@@ -84,6 +104,7 @@ class Date
|
|
84
104
|
# @return [Array, nil]
|
85
105
|
#
|
86
106
|
def coerce(other)
|
107
|
+
logger.trace { "Coercing #{self} as a request from #{other.class}" }
|
87
108
|
return nil unless other.respond_to?(:to_date)
|
88
109
|
return [other.to_date, self] if other.method(:to_date).arity.zero?
|
89
110
|
|
@@ -45,8 +45,14 @@ class DateTime < Date
|
|
45
45
|
to_java(ZonedDateTime)
|
46
46
|
end
|
47
47
|
|
48
|
+
# @return [Instant]
|
49
|
+
def to_instant(_context = nil)
|
50
|
+
to_java(Instant)
|
51
|
+
end
|
52
|
+
|
48
53
|
# (see Time#coerce)
|
49
54
|
def coerce(other)
|
55
|
+
logger.trace { "Coercing #{self} as a request from #{other.class}" }
|
50
56
|
return unless other.respond_to?(:to_zoned_date_time)
|
51
57
|
|
52
58
|
zdt = to_zoned_date_time
|
@@ -84,6 +84,14 @@ class Time
|
|
84
84
|
java.time.MonthDay.of(month, day)
|
85
85
|
end
|
86
86
|
|
87
|
+
# @!method yesterday?
|
88
|
+
# (see OpenHAB::CoreExt::Java::ZonedDateTime#yesterday?)
|
89
|
+
# @!method today?
|
90
|
+
# (see OpenHAB::CoreExt::Java::ZonedDateTime#today?)
|
91
|
+
# @!method tomorrow?
|
92
|
+
# (see OpenHAB::CoreExt::Java::ZonedDateTime#tomorrow?)
|
93
|
+
def_delegators :to_zoned_date_time, :yesterday?, :today?, :tomorrow?
|
94
|
+
|
87
95
|
# @param [ZonedDateTime, nil] context
|
88
96
|
# A {ZonedDateTime} used to fill in missing fields
|
89
97
|
# during conversion. Not used in this class.
|
@@ -92,8 +100,8 @@ class Time
|
|
92
100
|
to_java(java.time.ZonedDateTime)
|
93
101
|
end
|
94
102
|
|
95
|
-
# @return [
|
96
|
-
def to_instant
|
103
|
+
# @return [Instant]
|
104
|
+
def to_instant(_context = nil)
|
97
105
|
to_java(java.time.Instant)
|
98
106
|
end
|
99
107
|
|
@@ -105,6 +113,7 @@ class Time
|
|
105
113
|
# @return [Array, nil]
|
106
114
|
#
|
107
115
|
def coerce(other)
|
116
|
+
logger.trace { "Coercing #{self} as a request from #{other.class}" }
|
108
117
|
return unless other.respond_to?(:to_zoned_date_time)
|
109
118
|
|
110
119
|
zdt = to_zoned_date_time
|
@@ -85,7 +85,11 @@ module OpenHAB
|
|
85
85
|
# @return [void]
|
86
86
|
#
|
87
87
|
def resume
|
88
|
-
|
88
|
+
if expired?
|
89
|
+
logger.warn "Cannot resume a timed command that has expired. Use reschedule instead."
|
90
|
+
else
|
91
|
+
self.resolution = nil
|
92
|
+
end
|
89
93
|
end
|
90
94
|
end
|
91
95
|
|
@@ -216,22 +220,25 @@ module OpenHAB
|
|
216
220
|
DSL.after(duration) do
|
217
221
|
timed_command_details.mutex.synchronize do
|
218
222
|
logger.trace "Timed command expired - #{timed_command_details}"
|
223
|
+
DSL.rules[timed_command_details.rule_uid].disable
|
219
224
|
timed_command_details.resolution = :expired
|
220
225
|
case timed_command_details.on_expire
|
221
226
|
when Proc
|
222
227
|
logger.trace "Invoking block #{timed_command_details.on_expire} after timed command for #{name} expired"
|
223
228
|
timed_command_details.on_expire.call(timed_command_details)
|
224
|
-
if timed_command_details.resolution.nil?
|
225
|
-
logger.trace { "Block rescheduled the timer to #{timed_command_details.timer.execution_time}" }
|
226
|
-
end
|
227
229
|
when Core::Types::UnDefType
|
228
230
|
update(timed_command_details.on_expire)
|
229
231
|
else
|
230
232
|
command(timed_command_details.on_expire)
|
231
233
|
end
|
234
|
+
# The on_expire block can call timed_command_details.reschedule, which sets resolution to nil
|
235
|
+
# to prevent removal of the timed command
|
232
236
|
if timed_command_details.resolution
|
233
237
|
DSL.rules.remove(timed_command_details.rule_uid)
|
234
238
|
TimedCommand.timed_commands.delete(timed_command_details.item)
|
239
|
+
else
|
240
|
+
DSL.rules[timed_command_details.rule_uid].enable
|
241
|
+
logger.trace { "Block rescheduled the timer to #{timed_command_details.timer.execution_time}" }
|
235
242
|
end
|
236
243
|
end
|
237
244
|
end
|
@@ -1403,7 +1403,7 @@ module OpenHAB
|
|
1403
1403
|
@ruby_triggers << [:every, value, { at: at }]
|
1404
1404
|
|
1405
1405
|
if value == :day && at.is_a?(Item)
|
1406
|
-
#
|
1406
|
+
# @deprecated OH 3.4 - attachments are supported in OH 4.0+
|
1407
1407
|
if Core.version <= Core::V4_0 && !attach.nil?
|
1408
1408
|
raise ArgumentError, "Attachments are not supported with dynamic datetime triggers in openHAB 3.x"
|
1409
1409
|
end
|
@@ -127,7 +127,12 @@ module OpenHAB
|
|
127
127
|
# One or more value color rules (see {#value_color})
|
128
128
|
# @param icon_color [String, Hash<String, String>, Hash<Array<String>, String>, nil]
|
129
129
|
# One or more icon color rules (see {#icon_color})
|
130
|
-
# @param visibility [String,
|
130
|
+
# @param visibility [String,
|
131
|
+
# Core::Types::State,
|
132
|
+
# Array<String>,
|
133
|
+
# Array<Core::Types::State>,
|
134
|
+
# Array<Array<String>>,
|
135
|
+
# nil]
|
131
136
|
# One or more visibility rules (see {#visibility})
|
132
137
|
# @!visibility private
|
133
138
|
def initialize(type,
|
@@ -286,8 +291,12 @@ module OpenHAB
|
|
286
291
|
supports_and_conditions = SitemapBuilder.factory.respond_to?(:create_condition)
|
287
292
|
|
288
293
|
Array.wrap(conditions).each do |c|
|
294
|
+
c = c.to_s if c.is_a?(Core::Types::State)
|
295
|
+
unless c.is_a?(String) || c.is_a?(Symbol)
|
296
|
+
raise ArgumentError, "#{c.inspect} is not a valid condition data type for #{inspect}"
|
297
|
+
end
|
289
298
|
unless (match = CONDITION_PATTERN.match(c))
|
290
|
-
raise ArgumentError, "Syntax error in condition #{c.inspect}"
|
299
|
+
raise ArgumentError, "Syntax error in condition #{c.inspect} for #{inspect}"
|
291
300
|
end
|
292
301
|
|
293
302
|
condition = supports_and_conditions ? SitemapBuilder.factory.create_condition : container
|
@@ -1206,7 +1215,7 @@ module OpenHAB
|
|
1206
1215
|
REQUIRED_BUTTON_ARGS = %i[row column click].freeze
|
1207
1216
|
private_constant :REQUIRED_BUTTON_ARGS
|
1208
1217
|
|
1209
|
-
#
|
1218
|
+
# @deprecated OH 4.1 in OH 4.1, Buttongrid is not a LinkableWidget.
|
1210
1219
|
# Pretend that the buttons property is its children so we can add to it in LinkableWidgetBuilder#build
|
1211
1220
|
if (Core::V4_1...Core::V4_2).cover?(Core.version)
|
1212
1221
|
java_import org.openhab.core.model.sitemap.sitemap.Buttongrid
|
data/lib/openhab/dsl/version.rb
CHANGED
data/lib/openhab/dsl.rb
CHANGED
@@ -51,6 +51,8 @@ module OpenHAB
|
|
51
51
|
|
52
52
|
@debouncers = java.util.concurrent.ConcurrentHashMap.new
|
53
53
|
|
54
|
+
module_function :items, :things
|
55
|
+
|
54
56
|
module_function
|
55
57
|
|
56
58
|
# @!group Rule Creation
|
@@ -229,6 +231,13 @@ module OpenHAB
|
|
229
231
|
|
230
232
|
# @!group Object Access
|
231
233
|
|
234
|
+
# @!parse
|
235
|
+
# # (see Core::EntityLookup#items)
|
236
|
+
# def items; end
|
237
|
+
#
|
238
|
+
# # (see Core::EntityLookup#things)
|
239
|
+
# def things; end
|
240
|
+
|
232
241
|
#
|
233
242
|
# (see Core::ValueCache)
|
234
243
|
#
|
@@ -249,66 +258,11 @@ module OpenHAB
|
|
249
258
|
Core::Rules::Registry.instance
|
250
259
|
end
|
251
260
|
|
252
|
-
#
|
253
|
-
# Fetches all items from the item registry
|
254
|
-
#
|
255
|
-
# @return [Core::Items::Registry]
|
256
|
-
#
|
257
|
-
# The examples all assume the following items exist.
|
258
|
-
#
|
259
|
-
# ```xtend
|
260
|
-
# Dimmer DimmerTest "Test Dimmer"
|
261
|
-
# Switch SwitchTest "Test Switch"
|
262
|
-
# ```
|
263
|
-
#
|
264
|
-
# @example
|
265
|
-
# logger.info("Item Count: #{items.count}") # Item Count: 2
|
266
|
-
# logger.info("Items: #{items.map(&:label).sort.join(', ')}") # Items: Test Dimmer, Test Switch'
|
267
|
-
# logger.info("DimmerTest exists? #{items.key?('DimmerTest')}") # DimmerTest exists? true
|
268
|
-
# logger.info("StringTest exists? #{items.key?('StringTest')}") # StringTest exists? false
|
269
|
-
#
|
270
|
-
# @example
|
271
|
-
# rule 'Use dynamic item lookup to increase related dimmer brightness when switch is turned on' do
|
272
|
-
# changed SwitchTest, to: ON
|
273
|
-
# triggered { |item| items[item.name.gsub('Switch','Dimmer')].brighten(10) }
|
274
|
-
# end
|
275
|
-
#
|
276
|
-
# @example
|
277
|
-
# rule 'search for a suitable item' do
|
278
|
-
# on_load
|
279
|
-
# triggered do
|
280
|
-
# # Send ON to DimmerTest if it exists, otherwise send it to SwitchTest
|
281
|
-
# (items['DimmerTest'] || items['SwitchTest'])&.on
|
282
|
-
# end
|
283
|
-
# end
|
284
|
-
#
|
285
|
-
def items
|
286
|
-
Core::Items::Registry.instance
|
287
|
-
end
|
288
|
-
|
289
261
|
# @return [Core::Sitemaps::Provider]
|
290
262
|
def sitemaps
|
291
263
|
Core::Sitemaps::Provider.instance
|
292
264
|
end
|
293
265
|
|
294
|
-
#
|
295
|
-
# Get all things known to openHAB
|
296
|
-
#
|
297
|
-
# @return [Core::Things::Registry] all Thing objects known to openHAB
|
298
|
-
#
|
299
|
-
# @example
|
300
|
-
# things.each { |thing| logger.info("Thing: #{thing.uid}")}
|
301
|
-
# logger.info("Thing: #{things['astro:sun:home'].uid}")
|
302
|
-
# homie_things = things.select { |t| t.thing_type_uid == "mqtt:homie300" }
|
303
|
-
# zwave_things = things.select { |t| t.binding_id == "zwave" }
|
304
|
-
# homeseer_dimmers = zwave_things.select { |t| t.thing_type_uid.id == "homeseer_hswd200_00_000" }
|
305
|
-
# things['zwave:device:512:node90'].uid.bridge_ids # => ["512"]
|
306
|
-
# things['mqtt:topic:4'].uid.bridge_ids # => []
|
307
|
-
#
|
308
|
-
def things
|
309
|
-
Core::Things::Registry.instance
|
310
|
-
end
|
311
|
-
|
312
266
|
#
|
313
267
|
# Provides access to timers created by {after after}
|
314
268
|
#
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openhab-scripting
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.29.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian O'Connell
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2024-09-
|
13
|
+
date: 2024-09-19 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -490,7 +490,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
490
490
|
- !ruby/object:Gem::Version
|
491
491
|
version: '0'
|
492
492
|
requirements: []
|
493
|
-
rubygems_version: 3.5.
|
493
|
+
rubygems_version: 3.5.19
|
494
494
|
signing_key:
|
495
495
|
specification_version: 4
|
496
496
|
summary: JRuby Helper Libraries for openHAB Scripting
|