openhab-scripting 5.27.2 → 5.29.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|