openhab-jrubyscripting 5.0.0.rc10 → 5.0.0.rc12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/lib/openhab/core/actions/audio.rb +47 -0
  3. data/lib/openhab/core/actions/ephemeris.rb +39 -0
  4. data/lib/openhab/core/actions/exec.rb +51 -0
  5. data/lib/openhab/core/actions/http.rb +80 -0
  6. data/lib/openhab/core/actions/ping.rb +30 -0
  7. data/lib/openhab/core/actions/transformation.rb +32 -0
  8. data/lib/openhab/core/actions/voice.rb +36 -0
  9. data/lib/openhab/core/actions.rb +23 -120
  10. data/lib/openhab/core/{events → dto}/item_channel_link.rb +1 -4
  11. data/lib/openhab/core/{events → dto}/thing.rb +10 -12
  12. data/lib/openhab/core/dto.rb +11 -0
  13. data/lib/openhab/core/entity_lookup.rb +1 -1
  14. data/lib/openhab/core/events/abstract_event.rb +1 -0
  15. data/lib/openhab/core/events/abstract_item_registry_event.rb +36 -0
  16. data/lib/openhab/core/events/abstract_thing_registry_event.rb +40 -0
  17. data/lib/openhab/core/events/item_command_event.rb +1 -1
  18. data/lib/openhab/core/events/item_state_changed_event.rb +6 -6
  19. data/lib/openhab/core/events/item_state_event.rb +6 -6
  20. data/lib/openhab/core/events/thing_status_info_event.rb +8 -6
  21. data/lib/openhab/core/items/date_time_item.rb +3 -2
  22. data/lib/openhab/core/items/generic_item.rb +92 -1
  23. data/lib/openhab/core/items/item.rb +9 -8
  24. data/lib/openhab/core/items/metadata/hash.rb +1 -1
  25. data/lib/openhab/core/items/metadata/namespace_hash.rb +10 -2
  26. data/lib/openhab/core/items/metadata/provider.rb +2 -2
  27. data/lib/openhab/core/items/persistence.rb +99 -21
  28. data/lib/openhab/core/items/player_item.rb +1 -1
  29. data/lib/openhab/core/items/proxy.rb +20 -14
  30. data/lib/openhab/core/items/registry.rb +12 -1
  31. data/lib/openhab/core/items/state_storage.rb +2 -2
  32. data/lib/openhab/core/items.rb +3 -3
  33. data/lib/openhab/core/profile_factory.rb +3 -1
  34. data/lib/openhab/core/proxy.rb +130 -0
  35. data/lib/openhab/core/registry.rb +12 -2
  36. data/lib/openhab/core/rules.rb +1 -1
  37. data/lib/openhab/core/things/links/provider.rb +39 -1
  38. data/lib/openhab/core/things/proxy.rb +8 -0
  39. data/lib/openhab/core/things/registry.rb +4 -0
  40. data/lib/openhab/core/timer.rb +3 -19
  41. data/lib/openhab/core/types/date_time_type.rb +3 -2
  42. data/lib/openhab/core/types/decimal_type.rb +1 -1
  43. data/lib/openhab/core/types/un_def_type.rb +2 -2
  44. data/lib/openhab/core/value_cache.rb +1 -1
  45. data/lib/openhab/core.rb +3 -3
  46. data/lib/openhab/core_ext/ephemeris.rb +53 -0
  47. data/lib/openhab/core_ext/java/class.rb +1 -1
  48. data/lib/openhab/core_ext/java/duration.rb +27 -1
  49. data/lib/openhab/core_ext/java/local_date.rb +17 -7
  50. data/lib/openhab/core_ext/java/local_time.rb +13 -3
  51. data/lib/openhab/core_ext/java/month.rb +1 -1
  52. data/lib/openhab/core_ext/java/month_day.rb +15 -3
  53. data/lib/openhab/core_ext/java/period.rb +1 -1
  54. data/lib/openhab/core_ext/java/temporal_amount.rb +1 -1
  55. data/lib/openhab/core_ext/java/time.rb +5 -1
  56. data/lib/openhab/core_ext/java/zoned_date_time.rb +100 -2
  57. data/lib/openhab/core_ext/ruby/date.rb +4 -2
  58. data/lib/openhab/core_ext/ruby/date_time.rb +1 -0
  59. data/lib/openhab/core_ext/ruby/numeric.rb +6 -1
  60. data/lib/openhab/core_ext/ruby/time.rb +1 -0
  61. data/lib/openhab/dsl/debouncer.rb +259 -0
  62. data/lib/openhab/dsl/items/builder.rb +29 -14
  63. data/lib/openhab/dsl/items/timed_command.rb +31 -13
  64. data/lib/openhab/dsl/rules/automation_rule.rb +30 -44
  65. data/lib/openhab/dsl/rules/builder.rb +404 -39
  66. data/lib/openhab/dsl/rules/guard.rb +12 -54
  67. data/lib/openhab/dsl/rules/name_inference.rb +11 -0
  68. data/lib/openhab/dsl/rules/property.rb +3 -4
  69. data/lib/openhab/dsl/rules/terse.rb +4 -1
  70. data/lib/openhab/dsl/rules/triggers/conditions/duration.rb +5 -6
  71. data/lib/openhab/dsl/rules/triggers/cron/cron.rb +1 -0
  72. data/lib/openhab/dsl/rules/triggers/cron/cron_handler.rb +19 -31
  73. data/lib/openhab/dsl/rules/triggers/watch/watch.rb +1 -0
  74. data/lib/openhab/dsl/rules/triggers/watch/watch_handler.rb +22 -30
  75. data/lib/openhab/dsl/things/builder.rb +1 -1
  76. data/lib/openhab/dsl/thread_local.rb +1 -0
  77. data/lib/openhab/dsl/version.rb +1 -1
  78. data/lib/openhab/dsl.rb +251 -14
  79. data/lib/openhab/rspec/helpers.rb +3 -2
  80. data/lib/openhab/rspec/hooks.rb +6 -2
  81. data/lib/openhab/rspec/karaf.rb +7 -0
  82. data/lib/openhab/rspec/mocks/instance_method_stasher.rb +22 -0
  83. data/lib/openhab/rspec/mocks/space.rb +23 -0
  84. data/lib/openhab/rspec/mocks/timer.rb +33 -0
  85. data/lib/openhab/rspec/openhab/core/actions.rb +16 -4
  86. data/lib/openhab/rspec/openhab/core/items/proxy.rb +1 -13
  87. data/lib/openhab/rspec/suspend_rules.rb +1 -14
  88. data/lib/openhab/rspec.rb +9 -0
  89. data/lib/openhab/yard/base_helper.rb +19 -0
  90. data/lib/openhab/yard/code_objects/group_object.rb +9 -3
  91. data/lib/openhab/yard/coderay.rb +17 -0
  92. data/lib/openhab/yard/handlers/jruby/base.rb +10 -1
  93. data/lib/openhab/yard/handlers/jruby/java_import_handler.rb +3 -0
  94. data/lib/openhab/yard/html_helper.rb +49 -15
  95. data/lib/openhab/yard/markdown_helper.rb +135 -0
  96. data/lib/openhab/yard.rb +6 -0
  97. metadata +36 -4
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "delegate"
4
+ require_relative "../proxy"
4
5
 
5
6
  module OpenHAB
6
7
  module Core
@@ -11,6 +12,13 @@ module OpenHAB
11
12
  # Not really an Item, but pretends to be
12
13
  # @!parse include Item
13
14
 
15
+ # @!visibility private
16
+ EVENTS = [Events::ItemAddedEvent::TYPE, Events::ItemUpdatedEvent::TYPE, Events::ItemRemovedEvent::TYPE].freeze
17
+ # @!visibility private
18
+ UID_METHOD = :name
19
+
20
+ include Core::Proxy
21
+
14
22
  # @return [String]
15
23
  attr_reader :name
16
24
 
@@ -18,19 +26,15 @@ module OpenHAB
18
26
  # Set the proxy item (called by super)
19
27
  #
20
28
  def __setobj__(item)
21
- @name = item.name
22
- # Convert name to Java version for faster lookups
23
- @java_name = item.name.to_java
29
+ @item = item.is_a?(Item) ? item : nil
30
+ @name ||= item.name if item
24
31
  end
25
32
 
26
33
  #
27
- # Lookup item from item registry
34
+ # @return [Item, nil]
28
35
  #
29
36
  def __getobj__
30
- r = $ir.get(@name)
31
- return yield if r.nil? && block_given?
32
-
33
- r
37
+ @item
34
38
  end
35
39
 
36
40
  # @return [Module]
@@ -88,9 +92,9 @@ module OpenHAB
88
92
  # @return [GroupItem::Members]
89
93
  # @raise [NoMethodError] if item is not a GroupItem, or a dummy.
90
94
  def members
91
- return super unless __getobj__.nil?
95
+ return GroupItem::Members.new(self) if __getobj__.nil?
92
96
 
93
- GroupItem::Members.new(self)
97
+ __getobj__.members
94
98
  end
95
99
 
96
100
  # @return [String]
@@ -112,15 +116,17 @@ module OpenHAB
112
116
  end
113
117
 
114
118
  # needs to return `false` if we know we're not a {GroupItem}
115
- def respond_to?(method, *)
116
- return __getobj__.nil? if method.to_sym == :members
119
+ def respond_to?(method, *args)
120
+ obj = __getobj__
121
+ return obj.respond_to?(method, *args) if method.to_sym == :members && !obj.nil?
117
122
 
118
123
  super
119
124
  end
120
125
 
121
126
  # needs to return `false` if we know we're not a {GroupItem}
122
- def respond_to_missing?(method, *)
123
- return __getobj__.nil? if method.to_sym == :members
127
+ def respond_to_missing?(method, *args)
128
+ obj = __getobj__
129
+ return obj.respond_to_missing?(method, *args) if method.to_sym == :members && !obj.nil?
124
130
 
125
131
  super
126
132
  end
@@ -48,6 +48,8 @@ module OpenHAB
48
48
  # @yield Block executed in the context of a {DSL::Items::Builder}
49
49
  # @return [Object] The return value of the block.
50
50
  #
51
+ # (see Items::Builder)
52
+ #
51
53
  def build(preferred_provider = nil, &block)
52
54
  DSL::Items::BaseBuilderDSL.new(preferred_provider).instance_eval_with_dummy_items(&block)
53
55
  end
@@ -57,16 +59,25 @@ module OpenHAB
57
59
  #
58
60
  # The item must be a managed item (typically created by Ruby or in the UI).
59
61
  #
62
+ # Any associated metadata or channel links are also removed.
63
+ #
60
64
  # @param [String, Item] item_name
61
65
  # @param recursive [true, false] Remove the item's members if it's a group
62
66
  # @return [Item, nil] The removed item, if found.
63
67
  def remove(item_name, recursive: false)
64
68
  item_name = item_name.name if item_name.is_a?(Item)
65
69
  provider = Provider.registry.provider_for(item_name)
66
- unless provider.is_a?(org.openhab.core.common.registry.ManagedProvider)
70
+ unless provider.is_a?(ManagedProvider)
67
71
  raise "Cannot remove item #{item_name} from non-managed provider #{provider.inspect}"
68
72
  end
69
73
 
74
+ Metadata::Provider.registry.providers.grep(ManagedProvider).each do |managed_provider|
75
+ managed_provider.remove_item_metadata(item_name)
76
+ end
77
+
78
+ Things::Links::Provider.registry.providers.grep(ManagedProvider).each do |managed_provider|
79
+ managed_provider.remove_links_for_item(item_name)
80
+ end
70
81
  provider.remove(item_name, recursive)
71
82
  end
72
83
  end
@@ -12,13 +12,13 @@ module OpenHAB
12
12
  #
13
13
  # Create a StateStorage object that stores the states of the given items
14
14
  #
15
- # @param [Array<Item>] items A list of items
15
+ # @param [Item] items A list of items
16
16
  #
17
17
  # @return [StateStorage] A state storage object
18
18
  #
19
19
  # @!visibility private
20
20
  def self.from_items(*items)
21
- StateStorage.new($events.store_states(*items).to_h)
21
+ StateStorage.new($events.store_states(*items.map(&:to_java)).to_h)
22
22
  end
23
23
 
24
24
  #
@@ -62,9 +62,9 @@ module OpenHAB
62
62
 
63
63
  logger.trace("Defining #{klass}##{command} for #{value}")
64
64
  klass.class_eval <<~RUBY, __FILE__, __LINE__ + 1
65
- def #{command}(for: nil, on_expire: nil, &block) # def on(for: nil, on_expire: nil, &block )
66
- command(#{value}, for: binding.local_variable_get(:for), on_expire: on_expire, &block) # command(ON, for: nil, expire: nil, &block)
67
- end # end
65
+ ruby2_keywords def #{command}(*args, &block) # ruby2_keywords def on(*args, &block)
66
+ command(#{value}, *args, &block) # command(ON, *args, &block)
67
+ end # end
68
68
  RUBY
69
69
 
70
70
  logger.trace("Defining Enumerable##{command} for #{value}")
@@ -69,10 +69,12 @@ module OpenHAB
69
69
 
70
70
  params[:callback] = @callback
71
71
  params[:context] = @context
72
- params[:config] = @context.configuration
72
+ params[:configuration] = @context.configuration.properties
73
73
  params[:link] = @callback.link
74
74
  params[:item] = @callback.link.item
75
75
  params[:channel_uid] = @callback.link.linked_uid
76
+ params[:state] ||= nil
77
+ params[:command] ||= nil
76
78
 
77
79
  kwargs = {}
78
80
  @block.parameters.each do |(param_type, name)|
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "singleton"
4
+ require "weakref"
5
+
6
+ require_relative "script_handling"
7
+
8
+ module OpenHAB
9
+ module Core
10
+ #
11
+ # Contains the infrastructure necessary to listen for events when objects are
12
+ # added/removed from their registry, and keep Proxy objects up-to-date with
13
+ # their underlying object.
14
+ #
15
+ # The including class must meet a few requirements:
16
+ # * Have an `EVENTS` constant that is an Array<String> of the events to
17
+ # listen for
18
+ # * The _last_ entry in the `EVENTS` array must be the "removed" event
19
+ # * It must have a sibling class called `Provider`, with a `.registry`
20
+ # method
21
+ # * It's parent module, downcased and with trailing "s" stripped, must be
22
+ # the method name to retrieve an object from one of the incoming events
23
+ #
24
+ # @!visibility private
25
+ #
26
+ module Proxy
27
+ #
28
+ # Registers and listens to openHAB bus events for objects getting
29
+ # added/updated/removed, and updates references from proxy objects
30
+ # to real objects.
31
+ #
32
+ # Proxies are tracked (via a WeakRef), and their underlying object is
33
+ # if it has changed.
34
+ #
35
+ class EventSubscriber
36
+ include Singleton
37
+ include org.openhab.core.events.EventSubscriber
38
+
39
+ def initialize
40
+ @proxies = java.util.concurrent.ConcurrentHashMap.new
41
+ @parent_module = Object.const_get(self.class.name.split("::")[0..-3].join("::"), false)
42
+ @object_type = @parent_module.name.split("::").last.downcase[0..-2].to_sym
43
+
44
+ @event_types = @parent_module::Proxy::EVENTS
45
+ @uid_method = @parent_module::Proxy::UID_METHOD
46
+ @registry = @parent_module::Provider.registry
47
+ @registration = OSGi.register_service(self, "event.topics": "openhab/*")
48
+ ScriptHandling.script_unloaded { @registration.unregister }
49
+ end
50
+
51
+ #
52
+ # @!attribute [r] subscribed_event_types
53
+ # @return [Set<String>]
54
+ #
55
+ def subscribed_event_types
56
+ @event_types.to_set
57
+ end
58
+
59
+ # @return [org.openhab.core.events.EventFilter, nil]
60
+ def event_filter
61
+ nil
62
+ end
63
+
64
+ #
65
+ # @param [Events::AbstractEvent] event
66
+ # @return [void]
67
+ #
68
+ def receive(event)
69
+ uid = event.__send__(@object_type).__send__(@uid_method)
70
+ object = @registry.get(uid) unless event.class.simple_name == @event_types.last
71
+
72
+ @proxies.compute_if_present(uid) do |_, proxy_ref|
73
+ proxy = resolve_ref(proxy_ref)
74
+ next nil unless proxy
75
+
76
+ proxy.__setobj__(object)
77
+ proxy_ref
78
+ end
79
+ end
80
+
81
+ #
82
+ # Get or create a Proxy for the given raw openHAB object.
83
+ #
84
+ def fetch(object)
85
+ result = nil
86
+
87
+ @proxies.compute(object.__send__(@uid_method)) do |_k, proxy_ref|
88
+ result = resolve_ref(proxy_ref)
89
+ proxy_ref = nil unless result
90
+ result ||= yield
91
+
92
+ proxy_ref || WeakRef.new(result)
93
+ end
94
+
95
+ result
96
+ end
97
+
98
+ private
99
+
100
+ def resolve_ref(proxy_ref)
101
+ proxy_ref.__getobj__ if proxy_ref&.weakref_alive?
102
+ rescue WeakRef::RefError
103
+ nil
104
+ end
105
+ end
106
+
107
+ # @!visibility private
108
+ module ClassMethods
109
+ # Intercepts calls to create new proxies, and returns the already
110
+ # existing (and tracked) proxy if it exists. Otherwise it does create
111
+ # a new instance of Proxy.
112
+ def new(object)
113
+ self::EventSubscriber.instance.fetch(object) { super }
114
+ end
115
+ end
116
+
117
+ # @!visibility private
118
+ def self.included(klass)
119
+ klass.singleton_class.prepend(ClassMethods)
120
+ # define a sub-class of EventSubscriber as a child class of the including class
121
+ klass.const_set(:EventSubscriber, Class.new(EventSubscriber))
122
+ end
123
+
124
+ # @!visibility private
125
+ def to_java
126
+ __getobj__
127
+ end
128
+ end
129
+ end
130
+ end
@@ -4,7 +4,7 @@ module OpenHAB
4
4
  module Core
5
5
  Registry = org.openhab.core.common.registry.AbstractRegistry
6
6
 
7
- Registry.field_reader :elementToProvider, :elementReadLock, :identifierToElement
7
+ Registry.field_reader :elementToProvider, :elementReadLock, :identifierToElement, :providerToElements
8
8
 
9
9
  # @abstract
10
10
  #
@@ -19,12 +19,22 @@ module OpenHAB
19
19
  #
20
20
  def provider_for(key)
21
21
  elementReadLock.lock
22
- return nil unless (element = identifierToElement[key])
22
+ if key.is_a?(org.openhab.core.common.registry.Identifiable)
23
+ element = key
24
+ else
25
+ return nil unless (element = identifierToElement[key])
26
+ end
23
27
 
24
28
  elementToProvider[element]
25
29
  ensure
26
30
  elementReadLock.unlock
27
31
  end
32
+
33
+ # @!attribute [r] providers
34
+ # @return [Enumerable<org.openhab.core.common.registry.Provider>]
35
+ def providers
36
+ providerToElements.keys
37
+ end
28
38
  end
29
39
  end
30
40
  end
@@ -13,7 +13,7 @@ module OpenHAB
13
13
 
14
14
  class << self
15
15
  #
16
- # @!attribute [r] rule_manager
16
+ # @!attribute [r] manager
17
17
  # @return [org.openhab.core.automation.RuleManager] The openHAB rule manager/engine
18
18
  #
19
19
  def manager
@@ -17,7 +17,7 @@ module OpenHAB
17
17
  #
18
18
  # The ItemChannelLink registry
19
19
  #
20
- # @return [org.openhab.core.thing.link.ItemChanneLinkRegistry]
20
+ # @return [org.openhab.core.thing.link.ItemChannelLinkRegistry]
21
21
  #
22
22
  def registry
23
23
  @registry ||= OSGi.service("org.openhab.core.thing.link.ItemChannelLinkRegistry")
@@ -33,6 +33,44 @@ module OpenHAB
33
33
  current.add(link)
34
34
  end
35
35
  end
36
+
37
+ #
38
+ # Removes all links to a given item.
39
+ #
40
+ # @param [String] item_name
41
+ # @return [Integer] how many links were removed
42
+ #
43
+ def remove_links_for_item(item_name)
44
+ count = 0
45
+ @elements.delete_if do |_k, v|
46
+ next unless v.item_name == item_name
47
+
48
+ count += 1
49
+ notify_listeners_about_removed_element(v)
50
+ true
51
+ end
52
+ count
53
+ end
54
+ alias_method :removeLinksForItem, :remove_links_for_item
55
+
56
+ #
57
+ # Removes all links to a given thing.
58
+ #
59
+ # @param [ThingUID] thing_uid
60
+ # @return [Integer] how many links were removed
61
+ #
62
+ def remove_links_for_thing(thing_uid)
63
+ count = 0
64
+ @elements.delete_if do |_k, v|
65
+ next unless v.linked_uid.thing_uid == thing_uid
66
+
67
+ count += 1
68
+ notify_listeners_about_removed_element(v)
69
+ true
70
+ end
71
+ count
72
+ end
73
+ alias_method :removeLinksForThing, :remove_links_for_thing
36
74
  end
37
75
  end
38
76
  end
@@ -12,6 +12,14 @@ module OpenHAB
12
12
  extend Forwardable
13
13
  def_delegators :__getobj__, :class, :is_a?, :kind_of?
14
14
 
15
+ # @!visibility private
16
+ EVENTS = [Events::ThingAddedEvent::TYPE, Events::ThingUpdatedEvent::TYPE,
17
+ Events::ThingRemovedEvent::TYPE].freeze
18
+ # @!visibility private
19
+ UID_METHOD = :uid
20
+
21
+ include Core::Proxy
22
+
15
23
  # Returns the list of channels associated with this Thing
16
24
  #
17
25
  # @note This is defined on this class, and not on {Thing}, because
@@ -61,6 +61,10 @@ module OpenHAB
61
61
  raise "Cannot remove thing #{thing_uid} from non-managed provider #{provider.inspect}"
62
62
  end
63
63
 
64
+ Links::Provider.registry.providers.grep(ManagedProvider).each do |managed_provider|
65
+ managed_provider.remove_links_for_thing(thing_uid)
66
+ end
67
+
64
68
  provider.remove(thing_uid)
65
69
  end
66
70
  end
@@ -28,7 +28,7 @@ module OpenHAB
28
28
  # @return [true,false]
29
29
 
30
30
  def_delegator :@timer, :has_terminated, :terminated?
31
- def_delegators :@timer, :active?, :cancelled?, :running?
31
+ def_delegators :@timer, :active?, :cancelled?, :running?, :execution_time
32
32
 
33
33
  # @return [Object, nil]
34
34
  attr_accessor :id
@@ -49,19 +49,7 @@ module OpenHAB
49
49
  @id = id
50
50
  @thread_locals = thread_locals
51
51
  @block = block
52
- @timer = if defined?(ScriptExecution)
53
- ScriptExecution.create_timer(1.minute.from_now) { execute }
54
- else # DEPRECATED: openHAB 3.4.0
55
- org.openhab.core.model.script.actions.ScriptExecution.create_timer(
56
- # create it far enough in the future so it won't execute until we finish setting it up
57
- 1.minute.from_now,
58
- # when running in rspec, it may have troubles finding this class
59
- # for auto-conversion of block to interface, so use .impl
60
- org.eclipse.xtext.xbase.lib.Procedures::Procedure0.impl { execute }
61
- )
62
- end
63
- # DEPRECATED: openHAB 3.4.0.M6
64
- @timer.class.field_reader :future unless @timer.respond_to?(:future)
52
+ @timer = ScriptExecution.create_timer(1.minute.from_now) { execute }
65
53
  reschedule(@time)
66
54
  end
67
55
 
@@ -79,11 +67,7 @@ module OpenHAB
79
67
  alias_method :to_s, :inspect
80
68
 
81
69
  # @!attribute [r] execution_time
82
- # @return [ZonedDateTime, nil] the scheduled execution time, or `nil` if the timer was cancelled
83
- def execution_time
84
- # DEPRECATED: openHAB 3.4.0.M6 (just remove the entire method)
85
- @timer.future.scheduled_time
86
- end
70
+ # @return [ZonedDateTime, nil] the scheduled execution time, or `nil` if the timer was cancelled
87
71
 
88
72
  #
89
73
  # Reschedule timer
@@ -33,7 +33,7 @@ module OpenHAB
33
33
 
34
34
  class << self
35
35
  #
36
- # Parses a String representing a time into an {java.time.DateTimeType}. First tries to parse it
36
+ # Parses a String representing a time into a {DateTimeType}. First tries to parse it
37
37
  # using Java's parser, then falls back to the Ruby `Time.parse`.
38
38
  #
39
39
  # @param [String] time_string
@@ -46,7 +46,7 @@ module OpenHAB
46
46
  rescue java.lang.StringIndexOutOfBoundsException, java.lang.IllegalArgumentException => e
47
47
  # Try Ruby's Time.parse if DateTimeType parser fails
48
48
  begin
49
- ::Time.parse(time_string).to_zoned_date_time
49
+ DateTimeType.new(::Time.parse(time_string).to_zoned_date_time)
50
50
  rescue ArgumentError
51
51
  raise ArgumentError, e.message
52
52
  end
@@ -71,6 +71,7 @@ module OpenHAB
71
71
  def_delegator :zoned_date_time, :to_epoch_second, :to_i
72
72
  def_delegator :zoned_date_time, :to_time
73
73
 
74
+ # @!visibility private
74
75
  alias_method :day, :mday
75
76
 
76
77
  #
@@ -11,7 +11,7 @@ module OpenHAB
11
11
  DecimalType = org.openhab.core.library.types.DecimalType
12
12
 
13
13
  #
14
- # {DecimalType} uses a {java.lang.BigDecimal} internally and thus can be
14
+ # {DecimalType} uses a {java.math.BigDecimal} internally and thus can be
15
15
  # used for integers, longs and floating point numbers alike.
16
16
  #
17
17
  # @example DecimalType can be used in case statements with ranges
@@ -21,11 +21,11 @@ module OpenHAB
21
21
  # Undef State
22
22
 
23
23
  # @!method null?
24
- # Check if `self == NULL`
24
+ # Check if `self` == {NULL}
25
25
  # @return [true,false]
26
26
 
27
27
  # @!method undef?
28
- # Check if `self == UNDEF`
28
+ # Check if `self` == {UNDEF}
29
29
  # @return [true,false]
30
30
  end
31
31
  end
@@ -26,7 +26,7 @@ module OpenHAB
26
26
  #
27
27
  # @note Only the {OpenHAB::DSL.shared_cache sharedCache} is exposed in Ruby.
28
28
  # For a private cache, simply use an instance variable. See
29
- # {file:docs/ruby-basics.md#Variables Instance Variables}.
29
+ # {file:docs/ruby-basics.md#variables Instance Variables}.
30
30
  #
31
31
  # @note Because every script or UI rule gets it own JRuby engine instance,
32
32
  # you cannot rely on being able to access Ruby objects between them. Only
data/lib/openhab/core.rb CHANGED
@@ -3,12 +3,12 @@
3
3
  module OpenHAB
4
4
  # Contains classes and modules that wrap actual openHAB objects
5
5
  module Core
6
- # The openHAB Version. >= 3.3.0 is required.
6
+ # The openHAB Version. >= 3.4.0 is required.
7
7
  # @return [String]
8
8
  VERSION = org.openhab.core.OpenHAB.version.freeze
9
9
 
10
- unless Gem::Version.new(VERSION) >= Gem::Version.new("3.3.0")
11
- raise "`openhab-jrubyscripting` requires openHAB >= 3.3.0"
10
+ unless Gem::Version.new(VERSION) >= Gem::Version.new("3.4.0")
11
+ raise "`openhab-jrubyscripting` requires openHAB >= 3.4.0"
12
12
  end
13
13
 
14
14
  # @return [Integer] Number of seconds to wait between checks for automation manager
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenHAB
4
+ module CoreExt
5
+ #
6
+ # Forwards ephemeris helper methods to `#to_zoned_date_time` provided by
7
+ # the mixed-in class.
8
+ #
9
+ # @note openHAB's built-in holiday definitions are based on _bank_
10
+ # holidays, so may give some unexpected results. For example, 2022-12-25
11
+ # is _not_ Christmas in England because it lands on a Sunday that year,
12
+ # so Christmas is considered to be 2022-12-26. See
13
+ # [the source](https://github.com/svendiedrichsen/jollyday/tree/master/src/main/resources/holidays)
14
+ # for exact definitions. You can always provide your own holiday
15
+ # definitions with {OpenHAB::DSL.holiday_file holiday_file} or
16
+ # {OpenHAB::DSL.holiday_file! holiday_file!}.
17
+ #
18
+ # @see https://www.openhab.org/docs/configuration/actions.html#ephemeris Ephemeris Action
19
+ # @see Core::Actions::Ephemeris.holiday_name Ephemeris.holiday_name
20
+ #
21
+ module Ephemeris
22
+ # (see Java::ZonedDateTime#holiday)
23
+ def holiday(holiday_file = nil)
24
+ to_zoned_date_time.holiday(holiday_file)
25
+ end
26
+
27
+ # (see Java::ZonedDateTime#holiday?)
28
+ def holiday?(holiday_file = nil)
29
+ to_zoned_date_time.holiday?(holiday_file)
30
+ end
31
+
32
+ # (see Java::ZonedDateTime#next_holiday)
33
+ def next_holiday(holiday_file = nil)
34
+ to_zoned_date_time.next_holiday(holiday_file)
35
+ end
36
+
37
+ # (see Java::ZonedDateTime#weekend?)
38
+ def weekend?
39
+ to_zoned_date_time.weekend?
40
+ end
41
+
42
+ # (see Java::ZonedDateTime#in_dayset?)
43
+ def in_dayset?(set)
44
+ to_zoned_date_time.in_dayset?(set)
45
+ end
46
+
47
+ # (see Java::ZonedDateTime#days_until)
48
+ def days_until(holiday, holiday_file = nil)
49
+ to_zoned_date_time.days_until(holiday, holiday_file)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -21,7 +21,7 @@ module OpenHAB
21
21
  #
22
22
  # `self`, all superclasses and interfaces, recursively.
23
23
  #
24
- # @return [Array<java.reflect.Type>]
24
+ # @return [Array<java.lang.reflect.Type>]
25
25
  #
26
26
  def generic_ancestors
27
27
  ancestors.flat_map do |klass|
@@ -5,13 +5,37 @@ module OpenHAB
5
5
  module Java
6
6
  Duration = java.time.Duration
7
7
 
8
- # Extensions to Duration
8
+ # Extensions to {java.time.Duration Java Duration}
9
9
  class Duration
10
10
  include Between
11
11
  # @!parse include TemporalAmount
12
12
 
13
+ #
14
+ # Convert to integer number of seconds
15
+ #
16
+ # @return [Integer]
17
+ #
13
18
  alias_method :to_i, :seconds
14
19
 
20
+ #
21
+ # @!method zero?
22
+ # @return [true,false] Returns true if the duration is zero length.
23
+ #
24
+
25
+ #
26
+ # @!method negative?
27
+ # @return [true,false] Returns true if the duration is less than zero.
28
+ #
29
+
30
+ unless instance_methods.include?(:positive?)
31
+ #
32
+ # @return [true, false] Returns true if the duration is greater than zero.
33
+ #
34
+ def positive?
35
+ self > 0 # rubocop:disable Style/NumericPredicate
36
+ end
37
+ end
38
+
15
39
  #
16
40
  # Convert to number of seconds
17
41
  #
@@ -28,6 +52,8 @@ module OpenHAB
28
52
  return to_f <=> other if other.is_a?(Numeric)
29
53
 
30
54
  super
55
+ rescue TypeError
56
+ nil
31
57
  end
32
58
 
33
59
  #