alula-ruby 2.15.1 → 2.16.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/VERSION.md +1 -0
- data/bin/console +1 -0
- data/lib/alula/api_resource.rb +17 -20
- data/lib/alula/dcp/resource_attributes.rb +128 -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: 34cf5c0ab11f5e83c244464f016e809a228e2c404cfd05322fcc3876681ab583
|
4
|
+
data.tar.gz: 702f818c5619c276030cb9b3bc75a780e97a58f3237a887de39c693196d42d2c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3eae60166983ae4dc654739434694b5fa3bbc6e957e605f645763e08ef53caf6926ecc858d92b88804788d95d79316a3d6d8cec682d0d252a055f089342d74bf
|
7
|
+
data.tar.gz: eb340114013a2eebd35aba3794be2e1f6c6f65ea5be3aa691a3feb29bac1737e1be35906980b52f3b7204b8d849eb14c92481e3e89d3c2d10b97dd5b1daef2ac
|
data/VERSION.md
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
| Version | Date | Description |
|
4
4
|
| ------- | ------------| --------------------------------------------------------------------------- |
|
5
|
+
| v2.16.0 | 2025-06-18 | Add API config template and all DCP entities |
|
5
6
|
| v2.15.1 | 2025-07-19 | Rename DCP-synchronizable fields to conform to the schema |
|
6
7
|
| v2.15.0 | 2025-06-10 | Add users relationship to stations |
|
7
8
|
| 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
|
|
@@ -1,14 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'byebug'
|
3
4
|
module Alula
|
4
5
|
module Dcp
|
5
6
|
module ResourceAttributes
|
6
7
|
def self.extended(base)
|
7
8
|
base.class_eval do
|
9
|
+
class << self
|
10
|
+
attr_writer :has_svm
|
11
|
+
|
12
|
+
def has_svm
|
13
|
+
@has_svm ||= false
|
14
|
+
end
|
15
|
+
end
|
8
16
|
@resource_path = nil
|
9
17
|
@type = nil
|
10
18
|
@http_methods = []
|
11
19
|
@fields = {}
|
20
|
+
|
21
|
+
def mark_dirty(field_name, old_value, new_value)
|
22
|
+
@dirty_attributes << field_name if old_value != new_value
|
23
|
+
end
|
12
24
|
end
|
13
25
|
base.include(InstanceMethods)
|
14
26
|
end
|
@@ -49,10 +61,69 @@ module Alula
|
|
49
61
|
def field(field_name, **opts)
|
50
62
|
@fields ||= {}
|
51
63
|
@fields[field_name] = opts
|
64
|
+
return if has_svm && field_name != :index
|
65
|
+
|
66
|
+
json_key = Alula::Util.camelize(field_name)
|
67
|
+
instance_eval do
|
68
|
+
# Reader method for attribute
|
69
|
+
define_method(field_name) do
|
70
|
+
value = @values[json_key]
|
71
|
+
if opts[:type] == :date && ![nil, ''].include?(value)
|
72
|
+
begin
|
73
|
+
DateTime.parse(value)
|
74
|
+
rescue ArgumentError
|
75
|
+
value
|
76
|
+
end
|
77
|
+
elsif opts[:type] == :object && opts[:use] && !value.nil? && value.respond_to?(:each)
|
78
|
+
if opts[:use].superclass == Alula::Dcp::ObjectField
|
79
|
+
opts[:use].new({}, field_name, value)
|
80
|
+
elsif respond_to?(:device_id)
|
81
|
+
opts[:use].new(device_id, value)
|
82
|
+
else
|
83
|
+
opts[:use].new(nil, value)
|
84
|
+
end
|
85
|
+
elsif opts[:type] == :array && opts[:of] && !value.nil? && value.respond_to?(:each)
|
86
|
+
# Array of objects, each object is a new instance of the use class
|
87
|
+
value.each_with_object([]) do |item, collector|
|
88
|
+
collector << opts[:of].new(device_id, item)
|
89
|
+
end
|
90
|
+
elsif opts[:type] == :boolean
|
91
|
+
[true, 'true', 1, '1'].include? value
|
92
|
+
elsif opts[:type] == :number
|
93
|
+
value&.to_i
|
94
|
+
else
|
95
|
+
value
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Setter method
|
100
|
+
define_method("#{field_name}=") do |new_value|
|
101
|
+
#
|
102
|
+
# Coerce 'blank like' fields into a defined blank value
|
103
|
+
# This helps HTML form submissions. A blank text field comes through as an
|
104
|
+
# empty string, instead of a nil as the API validates for.
|
105
|
+
new_value = nil if new_value == ''
|
106
|
+
|
107
|
+
new_value = [true, 'true', 1, '1'].include? new_value if opts[:type] == :boolean
|
108
|
+
|
109
|
+
# Mark the attribute as dirty if the new value is different
|
110
|
+
mark_dirty(field_name, @values[json_key], new_value)
|
111
|
+
#
|
112
|
+
# Assign the new value (always assigned even if a duplicate)
|
113
|
+
@values[json_key] = new_value
|
114
|
+
end
|
115
|
+
end
|
52
116
|
end
|
53
117
|
|
54
118
|
def get_fields
|
55
|
-
|
119
|
+
parent_fields = if superclass.respond_to?(:get_fields)
|
120
|
+
superclass.get_fields
|
121
|
+
else
|
122
|
+
{}
|
123
|
+
end
|
124
|
+
|
125
|
+
@fields ||= {}
|
126
|
+
parent_fields.merge(@fields)
|
56
127
|
end
|
57
128
|
|
58
129
|
def date_fields
|
@@ -79,7 +150,9 @@ module Alula
|
|
79
150
|
end
|
80
151
|
|
81
152
|
def param_key
|
82
|
-
name
|
153
|
+
# return only the last part of the class name, in snake_case
|
154
|
+
# e.g. Alula::Dcp::Config::PanelOptions becomes panel_options
|
155
|
+
Util.underscore(name.split('::')[-1])
|
83
156
|
end
|
84
157
|
|
85
158
|
private
|
@@ -145,8 +218,11 @@ module Alula
|
|
145
218
|
extend ResourceAttributes
|
146
219
|
|
147
220
|
# Assume properties is camel case
|
148
|
-
def initialize(parent_field, properties = nil)
|
221
|
+
def initialize(dirty_attributes, parent_field, properties = nil)
|
222
|
+
@values = properties
|
149
223
|
@parent_field = parent_field
|
224
|
+
@parent_dirty_attributes = dirty_attributes
|
225
|
+
@dirty_attributes = Set.new
|
150
226
|
return unless properties
|
151
227
|
|
152
228
|
valid_fields = self.class.get_fields
|
@@ -154,12 +230,18 @@ module Alula
|
|
154
230
|
ruby_key = Alula::Util.underscore(key.to_s)
|
155
231
|
next unless valid_fields.key?(ruby_key.to_sym)
|
156
232
|
|
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) }
|
233
|
+
public_send("#{ruby_key}=", value)
|
160
234
|
end
|
161
235
|
end
|
162
236
|
|
237
|
+
def model_name
|
238
|
+
self.class
|
239
|
+
end
|
240
|
+
|
241
|
+
def present?
|
242
|
+
!@values.nil?
|
243
|
+
end
|
244
|
+
|
163
245
|
def as_json
|
164
246
|
field_names.each_with_object({}) do |ruby_key, obj|
|
165
247
|
key = Util.camelize(ruby_key)
|
@@ -170,13 +252,52 @@ module Alula
|
|
170
252
|
end
|
171
253
|
end
|
172
254
|
|
255
|
+
#
|
256
|
+
# Take a hash of attributes and apply them to the model
|
257
|
+
def apply_attributes(attributes, merge_only: false)
|
258
|
+
res = attributes.each do |key, value|
|
259
|
+
next unless field_names.include?(key.to_sym)
|
260
|
+
|
261
|
+
opts = self.class.get_fields[key.to_sym]
|
262
|
+
json_key = Util.camelize(key.to_s)
|
263
|
+
if merge_only
|
264
|
+
# merge the value into the existing value
|
265
|
+
if value.is_a?(Array)
|
266
|
+
value.each_index do |index|
|
267
|
+
send(key)[index].apply_attributes(value[index], merge_only: true)
|
268
|
+
end
|
269
|
+
elsif value.is_a?(Hash) && send(key).respond_to?(:apply_attributes)
|
270
|
+
send(key).apply_attributes(value, merge_only: true)
|
271
|
+
elsif value.is_a?(Hash) && send(key).respond_to?(:each)
|
272
|
+
send("#{key}=", value[key])
|
273
|
+
elsif opts[:type] == :number
|
274
|
+
@values[json_key] = value.to_i
|
275
|
+
elsif opts[:type] == :boolean
|
276
|
+
@values[json_key] = [true, 'true', 1, '1'].include? value
|
277
|
+
else
|
278
|
+
@values[json_key] = value
|
279
|
+
end
|
280
|
+
else
|
281
|
+
send("#{key}=", value)
|
282
|
+
end
|
283
|
+
end
|
284
|
+
return @values if merge_only
|
285
|
+
|
286
|
+
res
|
287
|
+
end
|
288
|
+
|
173
289
|
private
|
174
290
|
|
175
291
|
def parse_value(value, ruby_key)
|
292
|
+
opts = self.class.get_fields[ruby_key.to_sym]
|
176
293
|
if date_fields.include?(ruby_key) && ![nil, ''].include?(value)
|
177
294
|
extract_date(value)
|
178
|
-
elsif value.is_a?
|
295
|
+
elsif value.is_a?(Alula::Dcp::ObjectField) || value.is_a?(Alula::DcpResource)
|
179
296
|
value.as_json
|
297
|
+
elsif opts[:type] == :boolean
|
298
|
+
[true, 'true', 1, '1'].include? value
|
299
|
+
elsif opts[:type] == :number
|
300
|
+
value&.to_i
|
180
301
|
else
|
181
302
|
value
|
182
303
|
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
|