alula-ruby 2.15.1 → 2.16.1
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/VERSION.md +2 -0
- data/bin/console +1 -0
- data/lib/alula/api_resource.rb +17 -20
- data/lib/alula/dcp/resource_attributes.rb +127 -7
- data/lib/alula/dcp/resource_state.rb +152 -0
- data/lib/alula/dcp/staged_value_methods.rb +50 -0
- data/lib/alula/dcp_resource.rb +119 -70
- data/lib/alula/monkey_patches.rb +27 -1
- data/lib/alula/resource_attributes.rb +12 -5
- data/lib/alula/resources/config_template.rb +49 -0
- data/lib/alula/resources/dcp/config/bus_modules/bus_module.rb +39 -0
- data/lib/alula/resources/dcp/config/bus_modules/dws_bus_module.rb +12 -0
- data/lib/alula/resources/dcp/config/bus_modules/input_bus_module.rb +12 -0
- data/lib/alula/resources/dcp/config/bus_modules/ism_transceiver_bus_module.rb +18 -0
- data/lib/alula/resources/dcp/config/bus_modules/output_bus_module.rb +12 -0
- data/lib/alula/resources/dcp/config/bus_modules/touchpad_bus_module.rb +17 -0
- data/lib/alula/resources/dcp/config/bus_modules/zwave_bus_module.rb +12 -0
- data/lib/alula/resources/dcp/config/bus_modules.rb +21 -0
- data/lib/alula/resources/dcp/config/comm_data/auto_comm_test_interval.rb +24 -0
- data/lib/alula/resources/dcp/config/comm_data/server_heartbeats.rb +25 -0
- data/lib/alula/resources/dcp/config/comm_data/server_keep_alives.rb +25 -0
- data/lib/alula/resources/dcp/config/comm_data.rb +27 -0
- data/lib/alula/resources/dcp/config/panel_options/ac_fail_detect_delay.rb +23 -0
- data/lib/alula/resources/dcp/config/panel_options/event_reporting_delay.rb +24 -0
- data/lib/alula/resources/dcp/config/panel_options/key_fob_button_functions.rb +45 -0
- data/lib/alula/resources/dcp/config/panel_options/minimum_pin_size.rb +23 -0
- data/lib/alula/resources/dcp/config/panel_options/panel_led_brightness.rb +23 -0
- data/lib/alula/resources/dcp/config/panel_options/panel_misc_options.rb +25 -0
- data/lib/alula/resources/dcp/config/panel_options/panel_options.rb +60 -0
- data/lib/alula/resources/dcp/config/panel_options/reportable_event_types_partitions.rb +38 -0
- data/lib/alula/resources/dcp/config/panel_options/reportable_event_types_system.rb +27 -0
- data/lib/alula/resources/dcp/config/panel_options/swinger_threshold.rb +24 -0
- data/lib/alula/resources/dcp/config/panel_options/system_options.rb +45 -0
- data/lib/alula/resources/dcp/config/panel_options/trouble_beep_suppress.rb +37 -0
- data/lib/alula/resources/dcp/config/panel_options/virtual_interface_options.rb +32 -0
- data/lib/alula/resources/dcp/config/panel_options.rb +57 -0
- data/lib/alula/resources/dcp/config/partitions/partition.rb +54 -0
- data/lib/alula/resources/dcp/{users_data/installer_pin.rb → config/partitions.rb} +6 -6
- data/lib/alula/resources/dcp/config/siren_data/siren.rb +59 -0
- data/lib/alula/resources/dcp/config/siren_data.rb +21 -0
- data/lib/alula/resources/dcp/config/synchronize.rb +1 -1
- data/lib/alula/resources/dcp/config/timers/entry_delays.rb +27 -0
- data/lib/alula/resources/dcp/config/timers/exit_delays.rb +27 -0
- data/lib/alula/resources/dcp/config/timers/sensor_supervision_time.rb +27 -0
- data/lib/alula/resources/dcp/config/timers/siren_timeout.rb +24 -0
- data/lib/alula/resources/dcp/config/timers.rb +33 -0
- data/lib/alula/resources/dcp/config/users_data/duress_pin.rb +24 -0
- data/lib/alula/resources/dcp/config/users_data/installer_pin.rb +25 -0
- data/lib/alula/resources/dcp/config/users_data/user.rb +104 -0
- data/lib/alula/resources/dcp/config/users_data.rb +25 -0
- data/lib/alula/resources/dcp/config.rb +10 -1
- data/lib/alula/version.rb +1 -1
- data/lib/alula.rb +66 -5
- metadata +44 -5
- data/lib/alula/resources/dcp/users_data/user.rb +0 -100
- data/lib/alula/resources/dcp/users_data.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f3bf8e3477ce10c3045fe47f7bee7a445749338a08c22e49eec2ff49cb83e5b7
|
4
|
+
data.tar.gz: de5f43338748af6a94922dcbb0eb9dd73bc3565cacbbce1a17f314906c9e97e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6af1c562cce55dc4b361bb3ee2c36200b41e592302c50fbb935d5cd318c4db9aae3903631e8c48b4827016283b1497a437089aca4a17cc63756fc76a3f20402
|
7
|
+
data.tar.gz: 5edda7ca58669ea7343659ffd21474841def738f544e04d3597c133c4409db33fb914aa79b0edd5e4bce7f2170bad8a8aa72ab80943f7cc32584e5d7ffbe0a1f
|
data/VERSION.md
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
| Version | Date | Description |
|
4
4
|
| ------- | ------------| --------------------------------------------------------------------------- |
|
5
|
+
| v2.16.1 | 2025-06-24 | Remove byebug usages |
|
6
|
+
| v2.16.0 | 2025-06-18 | Add API config template and all DCP entities |
|
5
7
|
| v2.15.1 | 2025-07-19 | Rename DCP-synchronizable fields to conform to the schema |
|
6
8
|
| v2.15.0 | 2025-06-10 | Add users relationship to stations |
|
7
9
|
| v2.14.0 | 2025-04-16 | Add camera reboot and format sd card procs |
|
data/bin/console
CHANGED
data/lib/alula/api_resource.rb
CHANGED
@@ -4,7 +4,7 @@ module Alula
|
|
4
4
|
attr_accessor :id, :raw_data, :values, :dirty_attributes, :errors, :links, :link_matchers, :rate_limit
|
5
5
|
|
6
6
|
def self.class_name
|
7
|
-
name.split(
|
7
|
+
name.split('::')[-1]
|
8
8
|
end
|
9
9
|
|
10
10
|
def initialize(id = nil, attributes = {})
|
@@ -89,21 +89,20 @@ module Alula
|
|
89
89
|
# Fetch known attributes out of the object, collected into a Hash in camelCase format
|
90
90
|
# Intended for eventually making its way back up to the API
|
91
91
|
def as_json
|
92
|
-
|
93
|
-
key
|
94
|
-
val =
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
end
|
92
|
+
field_names.each_with_object({}) do |ruby_key, obj|
|
93
|
+
key = Util.camelize(ruby_key)
|
94
|
+
val = send(ruby_key)
|
95
|
+
obj[key] = if date_fields.include?(ruby_key) && ![nil, ''].include?(val)
|
96
|
+
if val.respond_to? :strftime
|
97
|
+
val.strftime('%Y-%m-%dT%H:%M:%S.%L%z')
|
98
|
+
else
|
99
|
+
val.to_s
|
100
|
+
end
|
101
|
+
elsif val.is_a?(Alula::ObjectField) || val.is_a?(Alula::Dcp::ObjectField)
|
102
|
+
val.as_json
|
103
|
+
else
|
104
|
+
val
|
105
|
+
end
|
107
106
|
end
|
108
107
|
end
|
109
108
|
|
@@ -117,7 +116,7 @@ module Alula
|
|
117
116
|
end
|
118
117
|
|
119
118
|
# Remove blank values if creating a new record
|
120
|
-
values = values.
|
119
|
+
values = values.reject { |_k, v| v.nil? } unless persisted?
|
121
120
|
values
|
122
121
|
end
|
123
122
|
|
@@ -135,7 +134,7 @@ module Alula
|
|
135
134
|
def cache_links(links)
|
136
135
|
@links = links
|
137
136
|
|
138
|
-
@link_matchers = links.each_pair.each_with_object([]) do |(
|
137
|
+
@link_matchers = links.each_pair.each_with_object([]) do |(_type, link), collection|
|
139
138
|
data = link['data']
|
140
139
|
next if data.nil?
|
141
140
|
|
@@ -160,8 +159,6 @@ module Alula
|
|
160
159
|
self.class
|
161
160
|
end
|
162
161
|
|
163
|
-
private
|
164
|
-
|
165
162
|
class ModelErrors
|
166
163
|
include Enumerable
|
167
164
|
|
@@ -5,10 +5,21 @@ module Alula
|
|
5
5
|
module ResourceAttributes
|
6
6
|
def self.extended(base)
|
7
7
|
base.class_eval do
|
8
|
+
class << self
|
9
|
+
attr_writer :has_svm
|
10
|
+
|
11
|
+
def has_svm
|
12
|
+
@has_svm ||= false
|
13
|
+
end
|
14
|
+
end
|
8
15
|
@resource_path = nil
|
9
16
|
@type = nil
|
10
17
|
@http_methods = []
|
11
18
|
@fields = {}
|
19
|
+
|
20
|
+
def mark_dirty(field_name, old_value, new_value)
|
21
|
+
@dirty_attributes << field_name if old_value != new_value
|
22
|
+
end
|
12
23
|
end
|
13
24
|
base.include(InstanceMethods)
|
14
25
|
end
|
@@ -49,10 +60,69 @@ module Alula
|
|
49
60
|
def field(field_name, **opts)
|
50
61
|
@fields ||= {}
|
51
62
|
@fields[field_name] = opts
|
63
|
+
return if has_svm && field_name != :index
|
64
|
+
|
65
|
+
json_key = Alula::Util.camelize(field_name)
|
66
|
+
instance_eval do
|
67
|
+
# Reader method for attribute
|
68
|
+
define_method(field_name) do
|
69
|
+
value = @values[json_key]
|
70
|
+
if opts[:type] == :date && ![nil, ''].include?(value)
|
71
|
+
begin
|
72
|
+
DateTime.parse(value)
|
73
|
+
rescue ArgumentError
|
74
|
+
value
|
75
|
+
end
|
76
|
+
elsif opts[:type] == :object && opts[:use] && !value.nil? && value.respond_to?(:each)
|
77
|
+
if opts[:use].superclass == Alula::Dcp::ObjectField
|
78
|
+
opts[:use].new({}, field_name, value)
|
79
|
+
elsif respond_to?(:device_id)
|
80
|
+
opts[:use].new(device_id, value)
|
81
|
+
else
|
82
|
+
opts[:use].new(nil, value)
|
83
|
+
end
|
84
|
+
elsif opts[:type] == :array && opts[:of] && !value.nil? && value.respond_to?(:each)
|
85
|
+
# Array of objects, each object is a new instance of the use class
|
86
|
+
value.each_with_object([]) do |item, collector|
|
87
|
+
collector << opts[:of].new(device_id, item)
|
88
|
+
end
|
89
|
+
elsif opts[:type] == :boolean
|
90
|
+
[true, 'true', 1, '1'].include? value
|
91
|
+
elsif opts[:type] == :number
|
92
|
+
value&.to_i
|
93
|
+
else
|
94
|
+
value
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Setter method
|
99
|
+
define_method("#{field_name}=") do |new_value|
|
100
|
+
#
|
101
|
+
# Coerce 'blank like' fields into a defined blank value
|
102
|
+
# This helps HTML form submissions. A blank text field comes through as an
|
103
|
+
# empty string, instead of a nil as the API validates for.
|
104
|
+
new_value = nil if new_value == ''
|
105
|
+
|
106
|
+
new_value = [true, 'true', 1, '1'].include? new_value if opts[:type] == :boolean
|
107
|
+
|
108
|
+
# Mark the attribute as dirty if the new value is different
|
109
|
+
mark_dirty(field_name, @values[json_key], new_value)
|
110
|
+
#
|
111
|
+
# Assign the new value (always assigned even if a duplicate)
|
112
|
+
@values[json_key] = new_value
|
113
|
+
end
|
114
|
+
end
|
52
115
|
end
|
53
116
|
|
54
117
|
def get_fields
|
55
|
-
|
118
|
+
parent_fields = if superclass.respond_to?(:get_fields)
|
119
|
+
superclass.get_fields
|
120
|
+
else
|
121
|
+
{}
|
122
|
+
end
|
123
|
+
|
124
|
+
@fields ||= {}
|
125
|
+
parent_fields.merge(@fields)
|
56
126
|
end
|
57
127
|
|
58
128
|
def date_fields
|
@@ -79,7 +149,9 @@ module Alula
|
|
79
149
|
end
|
80
150
|
|
81
151
|
def param_key
|
82
|
-
name
|
152
|
+
# return only the last part of the class name, in snake_case
|
153
|
+
# e.g. Alula::Dcp::Config::PanelOptions becomes panel_options
|
154
|
+
Util.underscore(name.split('::')[-1])
|
83
155
|
end
|
84
156
|
|
85
157
|
private
|
@@ -145,8 +217,11 @@ module Alula
|
|
145
217
|
extend ResourceAttributes
|
146
218
|
|
147
219
|
# Assume properties is camel case
|
148
|
-
def initialize(parent_field, properties = nil)
|
220
|
+
def initialize(dirty_attributes, parent_field, properties = nil)
|
221
|
+
@values = properties
|
149
222
|
@parent_field = parent_field
|
223
|
+
@parent_dirty_attributes = dirty_attributes
|
224
|
+
@dirty_attributes = Set.new
|
150
225
|
return unless properties
|
151
226
|
|
152
227
|
valid_fields = self.class.get_fields
|
@@ -154,12 +229,18 @@ module Alula
|
|
154
229
|
ruby_key = Alula::Util.underscore(key.to_s)
|
155
230
|
next unless valid_fields.key?(ruby_key.to_sym)
|
156
231
|
|
157
|
-
|
158
|
-
define_singleton_method(ruby_key) { instance_variable_get("@#{ruby_key}") }
|
159
|
-
define_singleton_method("#{ruby_key}=") { |val| instance_variable_set("@#{ruby_key}", val) }
|
232
|
+
public_send("#{ruby_key}=", value)
|
160
233
|
end
|
161
234
|
end
|
162
235
|
|
236
|
+
def model_name
|
237
|
+
self.class
|
238
|
+
end
|
239
|
+
|
240
|
+
def present?
|
241
|
+
!@values.nil?
|
242
|
+
end
|
243
|
+
|
163
244
|
def as_json
|
164
245
|
field_names.each_with_object({}) do |ruby_key, obj|
|
165
246
|
key = Util.camelize(ruby_key)
|
@@ -170,13 +251,52 @@ module Alula
|
|
170
251
|
end
|
171
252
|
end
|
172
253
|
|
254
|
+
#
|
255
|
+
# Take a hash of attributes and apply them to the model
|
256
|
+
def apply_attributes(attributes, merge_only: false)
|
257
|
+
res = attributes.each do |key, value|
|
258
|
+
next unless field_names.include?(key.to_sym)
|
259
|
+
|
260
|
+
opts = self.class.get_fields[key.to_sym]
|
261
|
+
json_key = Util.camelize(key.to_s)
|
262
|
+
if merge_only
|
263
|
+
# merge the value into the existing value
|
264
|
+
if value.is_a?(Array)
|
265
|
+
value.each_index do |index|
|
266
|
+
send(key)[index].apply_attributes(value[index], merge_only: true)
|
267
|
+
end
|
268
|
+
elsif value.is_a?(Hash) && send(key).respond_to?(:apply_attributes)
|
269
|
+
send(key).apply_attributes(value, merge_only: true)
|
270
|
+
elsif value.is_a?(Hash) && send(key).respond_to?(:each)
|
271
|
+
send("#{key}=", value[key])
|
272
|
+
elsif opts[:type] == :number
|
273
|
+
@values[json_key] = value.to_i
|
274
|
+
elsif opts[:type] == :boolean
|
275
|
+
@values[json_key] = [true, 'true', 1, '1'].include? value
|
276
|
+
else
|
277
|
+
@values[json_key] = value
|
278
|
+
end
|
279
|
+
else
|
280
|
+
send("#{key}=", value)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
return @values if merge_only
|
284
|
+
|
285
|
+
res
|
286
|
+
end
|
287
|
+
|
173
288
|
private
|
174
289
|
|
175
290
|
def parse_value(value, ruby_key)
|
291
|
+
opts = self.class.get_fields[ruby_key.to_sym]
|
176
292
|
if date_fields.include?(ruby_key) && ![nil, ''].include?(value)
|
177
293
|
extract_date(value)
|
178
|
-
elsif value.is_a?
|
294
|
+
elsif value.is_a?(Alula::Dcp::ObjectField) || value.is_a?(Alula::DcpResource)
|
179
295
|
value.as_json
|
296
|
+
elsif opts[:type] == :boolean
|
297
|
+
[true, 'true', 1, '1'].include? value
|
298
|
+
elsif opts[:type] == :number
|
299
|
+
value&.to_i
|
180
300
|
else
|
181
301
|
value
|
182
302
|
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Alula
|
4
|
+
module Dcp
|
5
|
+
class ResourceState
|
6
|
+
attr_reader :key
|
7
|
+
|
8
|
+
def initialize(resource, key)
|
9
|
+
@resource = resource
|
10
|
+
@key = key
|
11
|
+
end
|
12
|
+
|
13
|
+
def model_name
|
14
|
+
@resource.class
|
15
|
+
end
|
16
|
+
|
17
|
+
def apply_attributes(attributes, _opts = {})
|
18
|
+
attributes.each do |key, value|
|
19
|
+
send("#{key}=", value) if respond_to?("#{key}=")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def method_missing(name, *args)
|
26
|
+
field_name = name.to_s.sub(/=$/, '').to_sym
|
27
|
+
klass = get_discriminated_class(@resource.values)
|
28
|
+
if klass.get_fields.key?(field_name)
|
29
|
+
json_key = Util.camelize(field_name.to_s)
|
30
|
+
opts = klass.get_fields[field_name]
|
31
|
+
if name.to_s.end_with?('=')
|
32
|
+
# Setter method
|
33
|
+
define_singleton_method("#{field_name}=") do |new_value|
|
34
|
+
# transform keys inside new_value to camelCase
|
35
|
+
new_value = new_value.transform_keys { |k| Util.camelize(k.to_s) } if new_value.is_a?(Hash)
|
36
|
+
#
|
37
|
+
# Coerce 'blank like' fields into a defined blank value
|
38
|
+
# This helps HTML form submissions. A blank text field comes through as an
|
39
|
+
# empty string, instead of a nil as the API validates for.
|
40
|
+
new_value = nil if new_value == '' && opts[:type] != :string
|
41
|
+
|
42
|
+
new_value = [true, 'true', 1, '1'].include? new_value if opts[:type] == :boolean
|
43
|
+
new_value = new_value.to_i if opts[:type] == :number
|
44
|
+
if opts[:type] == :object && opts[:use]
|
45
|
+
obj_fields = opts[:use].get_fields
|
46
|
+
new_value.each do |k, v|
|
47
|
+
next unless obj_fields.key?(k.to_sym)
|
48
|
+
|
49
|
+
type = obj_fields[k.to_sym][:type]
|
50
|
+
case type
|
51
|
+
when :boolean
|
52
|
+
new_value[k] = [true, 'true', 1, '1'].include? v
|
53
|
+
when :number
|
54
|
+
new_value[k] = v.to_i
|
55
|
+
else
|
56
|
+
# For other types, just assign the value directly
|
57
|
+
new_value[k] = v
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
#
|
62
|
+
# Assign the new value (always assigned even if a duplicate)
|
63
|
+
@resource.values[@key][json_key] = new_value
|
64
|
+
end
|
65
|
+
send("#{field_name}=", *args)
|
66
|
+
else
|
67
|
+
define_singleton_method(field_name) do
|
68
|
+
value = @resource.values[@key][json_key]
|
69
|
+
return nil if value.nil?
|
70
|
+
|
71
|
+
# Regular type handling
|
72
|
+
if opts[:type] == :date && ![nil, ''].include?(value)
|
73
|
+
begin
|
74
|
+
DateTime.parse(value)
|
75
|
+
rescue ArgumentError
|
76
|
+
value
|
77
|
+
end
|
78
|
+
elsif opts[:type] == :object && opts[:use]
|
79
|
+
if opts[:use].superclass == Alula::Dcp::ObjectField
|
80
|
+
opts[:use].new({}, field_name, value)
|
81
|
+
elsif respond_to?(:device_id)
|
82
|
+
opts[:use].new(device_id, value['index'], value)
|
83
|
+
else
|
84
|
+
opts[:use].new(nil, nil, value)
|
85
|
+
end
|
86
|
+
elsif opts[:type] == :array && opts[:of]
|
87
|
+
# Array of objects, each object is a new instance of the use class
|
88
|
+
value.each_with_object([]) do |item, collector|
|
89
|
+
if item.is_a?(Hash) && item['index']
|
90
|
+
collector << opts[:of].new(device_id, item['index'], item)
|
91
|
+
else
|
92
|
+
collector << opts[:of].new(device_id, nil, item)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
elsif opts[:type] == :boolean
|
96
|
+
[true, 'true', 1, '1'].include? value
|
97
|
+
elsif opts[:type] == :number
|
98
|
+
value&.to_i
|
99
|
+
else
|
100
|
+
value
|
101
|
+
end
|
102
|
+
end
|
103
|
+
send(field_name)
|
104
|
+
end
|
105
|
+
else
|
106
|
+
super
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def respond_to_missing?(name, include_private = false)
|
111
|
+
field_name = name.to_s.sub(/=$/, '').to_sym
|
112
|
+
get_discriminated_class(@resource.values).get_fields.key?(field_name) || name == 'param_key' || super
|
113
|
+
end
|
114
|
+
|
115
|
+
def get_discriminated_class(attributes)
|
116
|
+
return @resource.class unless @resource.class.respond_to?(:discriminator) && @resource.class.discriminator
|
117
|
+
|
118
|
+
discriminator_field = @resource.class.discriminator
|
119
|
+
json_key = Util.camelize(discriminator_field.to_s)
|
120
|
+
|
121
|
+
# Try staged first, then value, then raw attributes
|
122
|
+
discriminator_value = if attributes['staged']&.key?(json_key)
|
123
|
+
attributes['staged'][json_key]
|
124
|
+
elsif attributes['value']&.key?(json_key)
|
125
|
+
attributes['value'][json_key]
|
126
|
+
else
|
127
|
+
attributes[json_key]
|
128
|
+
end
|
129
|
+
if discriminator_value && @resource.class.discriminate_by&.key?(discriminator_value)
|
130
|
+
Object.const_get(@resource.class.discriminate_by[discriminator_value])
|
131
|
+
else
|
132
|
+
@resource.class
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def primitive?(resource)
|
137
|
+
resource.class.get_fields[:primitive]
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
class StagedState < ResourceState
|
142
|
+
def initialize(resource)
|
143
|
+
super(resource, 'staged')
|
144
|
+
end
|
145
|
+
end
|
146
|
+
class ValueState < ResourceState
|
147
|
+
def initialize(resource)
|
148
|
+
super(resource, 'value')
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Alula
|
4
|
+
module Dcp
|
5
|
+
module StagedValueMethods
|
6
|
+
def self.included(base)
|
7
|
+
base.class_eval do
|
8
|
+
class << self
|
9
|
+
attr_writer :has_svm
|
10
|
+
|
11
|
+
def has_svm
|
12
|
+
@has_svm ||= true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def staged
|
19
|
+
return nil if values['staged'].nil?
|
20
|
+
|
21
|
+
if primitive?(self)
|
22
|
+
# define setter method for staged value
|
23
|
+
define_singleton_method :staged= do |value|
|
24
|
+
values['staged'] = value
|
25
|
+
end
|
26
|
+
return values['staged']
|
27
|
+
end
|
28
|
+
|
29
|
+
@staged ||= StagedState.new(self)
|
30
|
+
end
|
31
|
+
|
32
|
+
def value
|
33
|
+
return nil if values['value'].nil?
|
34
|
+
if primitive?(self)
|
35
|
+
# define setter method for value
|
36
|
+
define_singleton_method :value= do |value|
|
37
|
+
values['value'] = value
|
38
|
+
end
|
39
|
+
return values['value']
|
40
|
+
end
|
41
|
+
|
42
|
+
@value ||= ValueState.new(self)
|
43
|
+
end
|
44
|
+
|
45
|
+
def primitive?(resource)
|
46
|
+
resource.class.get_fields[:primitive]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|