oschii_ruby 0.0.1 → 0.0.6
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/Gemfile +1 -0
- data/Gemfile.lock +3 -1
- data/lib/oschii/component.rb +48 -0
- data/lib/oschii/config.rb +183 -0
- data/lib/oschii/device.rb +2 -1
- data/lib/oschii/parser.rb +40 -0
- data/lib/oschii/session.rb +12 -0
- data/lib/oschii/template.rb +96 -0
- data/lib/oschii/version.rb +1 -1
- data/lib/oschii.rb +1 -12
- metadata +5 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 578aa88e4dd107c6af19e80da3419deae8fbcc56052cb8272a824f81ceaaddd3
|
4
|
+
data.tar.gz: 9f3b0a12310effb1832975cd5edba9846e2a83550b2df0e8ee4554d6175414a2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6558856f498bc70b8fa419aa3bb65f43c1cecd66337a2c1bdd3e5b6e8bd3e49f042751f16280370f5f17ef53e4675d9c656e5a33d28423b3f5e2a0f0ee3c2a89
|
7
|
+
data.tar.gz: 1d28d3da39dc9de4326b577d1aa19780ac5d369952ba7274fb441544460714902801f8e3bfaf4fb45d85c24ddf350a9bb89e48877d466259c92128ace69c0bba
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
oschii_ruby (0.0.
|
4
|
+
oschii_ruby (0.0.6)
|
5
5
|
activesupport (~> 7.1.2)
|
6
6
|
faye-websocket (~> 0.11.3)
|
7
7
|
osc-ruby (~> 1.1.4)
|
@@ -24,6 +24,7 @@ GEM
|
|
24
24
|
tzinfo (~> 2.0)
|
25
25
|
base64 (0.2.0)
|
26
26
|
bigdecimal (3.1.5)
|
27
|
+
bump (0.10.0)
|
27
28
|
byebug (11.1.3)
|
28
29
|
concurrent-ruby (1.2.2)
|
29
30
|
connection_pool (2.4.1)
|
@@ -69,6 +70,7 @@ PLATFORMS
|
|
69
70
|
arm64-darwin-21
|
70
71
|
|
71
72
|
DEPENDENCIES
|
73
|
+
bump
|
72
74
|
byebug
|
73
75
|
make_menu
|
74
76
|
oschii_ruby!
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Oschii
|
2
|
+
class Component
|
3
|
+
def initialize(type, config)
|
4
|
+
@type = type
|
5
|
+
@config = config
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :type, :config
|
9
|
+
|
10
|
+
def name
|
11
|
+
@name ||= config['name']
|
12
|
+
end
|
13
|
+
|
14
|
+
def array_name
|
15
|
+
@array_name ||= "#{type.capitalize}s"
|
16
|
+
end
|
17
|
+
|
18
|
+
def reference
|
19
|
+
"#{type}:#{name}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def routes
|
23
|
+
@routes ||= config['routes'] || config['Routes'] || config['subs'] || config['Subs'] || []
|
24
|
+
end
|
25
|
+
|
26
|
+
def targets
|
27
|
+
return @targets if @targets
|
28
|
+
|
29
|
+
@targets = config['targets'] || config['target'] || config['~'] || []
|
30
|
+
@targets = [@targets] if @targets.is_a?(String)
|
31
|
+
|
32
|
+
routes.each do |route|
|
33
|
+
target_refs = route['targets'] || route['target'] || route['~'] || []
|
34
|
+
target_refs = [target_refs] if target_refs.is_a?(String)
|
35
|
+
@targets += target_refs
|
36
|
+
end
|
37
|
+
@targets.map { |ref| ref.split('/').first }.uniq
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
inspect
|
42
|
+
end
|
43
|
+
|
44
|
+
def inspect
|
45
|
+
"#<#{self.class.name} '#{reference}'>"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
require_relative 'component'
|
2
|
+
require_relative 'template'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Oschii
|
6
|
+
# LOGO = '
|
7
|
+
# ╔═╗┌─┐┌─┐┬ ┬┬┬
|
8
|
+
# ║ ║└─┐│ ├─┤││
|
9
|
+
# ╚═╝└─┘└─┘┴ ┴┴┴'
|
10
|
+
|
11
|
+
COMPONENT_TYPES = %w(Sensor Driver Reporter Listener Monitor State Timer Pixel I2C).freeze
|
12
|
+
I2C = 'I2C'.freeze
|
13
|
+
BASIC_COMPONENT_TYPES = COMPONENT_TYPES.reject { |t| t == I2C }.freeze
|
14
|
+
|
15
|
+
TemplateError = Class.new(StandardError)
|
16
|
+
|
17
|
+
class Config
|
18
|
+
def initialize(json)
|
19
|
+
@config = json.is_a?(String) ? JSON.parse(json) : json
|
20
|
+
@components = {}
|
21
|
+
@startups = []
|
22
|
+
@templates = load_templates
|
23
|
+
@sda = -1
|
24
|
+
@scl = -1
|
25
|
+
@clock = 100_000
|
26
|
+
@name = nil
|
27
|
+
@description = nil
|
28
|
+
build
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.from_file(filename)
|
32
|
+
Config.new(File.read(filename))
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_reader :components, :templates, :scl, :sda, :clock,
|
36
|
+
:name, :description, :config, :startups
|
37
|
+
|
38
|
+
def load_templates
|
39
|
+
Dir.glob("./templates/*.json").map do |filename|
|
40
|
+
conf = JSON.parse(File.read(filename))
|
41
|
+
template = Template.new(
|
42
|
+
conf, conf['name'] || filename.gsub('.json', '').split('/').last
|
43
|
+
)
|
44
|
+
[template.name, template]
|
45
|
+
end.to_h
|
46
|
+
end
|
47
|
+
|
48
|
+
def add_component(comp)
|
49
|
+
components[comp.reference] = comp
|
50
|
+
end
|
51
|
+
|
52
|
+
def build
|
53
|
+
|
54
|
+
@name = config['name']
|
55
|
+
@description = config['description']
|
56
|
+
@startups = config['Startups'] || []
|
57
|
+
|
58
|
+
puts inspect
|
59
|
+
|
60
|
+
BASIC_COMPONENT_TYPES.each do |type|
|
61
|
+
config["#{type}s"]&.each do |comp_def|
|
62
|
+
comp = Component.new(type, comp_def)
|
63
|
+
puts " + #{comp}"
|
64
|
+
add_component comp
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
if (i2c = config[I2C])
|
69
|
+
@sda = i2c['sdaPin'] || sda
|
70
|
+
@scl = i2c['sclPin'] || scl
|
71
|
+
@clock = i2c['clock'] || clock
|
72
|
+
i2c['modules']&.each do |comp_def|
|
73
|
+
comp = Component.new(I2C, comp_def)
|
74
|
+
puts " + #{comp}"
|
75
|
+
add_component comp
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Get templates defined within this config
|
80
|
+
config['Templates']&.each do |conf|
|
81
|
+
templates[conf['name']] = Template.new(conf)
|
82
|
+
end
|
83
|
+
|
84
|
+
config['Customs']&.each do |custom_def|
|
85
|
+
build_custom_component custom_def
|
86
|
+
end
|
87
|
+
|
88
|
+
build_missing_targets
|
89
|
+
|
90
|
+
self
|
91
|
+
end
|
92
|
+
|
93
|
+
def build_custom_component(custom_def, name_prefix = '', indent = 0)
|
94
|
+
template = templates[custom_def['template']]
|
95
|
+
|
96
|
+
raise TemplateError, "Custom:#{custom_def['name']} - Template '#{custom_def['template']}' not defined" unless template
|
97
|
+
|
98
|
+
puts "#{' ' * indent} Custom:#{template.name}:#{name_prefix}#{custom_def['name']}"
|
99
|
+
|
100
|
+
template.build_components(custom_def, name_prefix).each do |comp|
|
101
|
+
puts "#{' ' * (indent+1)} + #{comp}"
|
102
|
+
add_component comp
|
103
|
+
end
|
104
|
+
|
105
|
+
@startups += template.startups
|
106
|
+
|
107
|
+
template.embedded_customs&.each do |inner_custom_def|
|
108
|
+
build_custom_component inner_custom_def, "#{custom_def['name']}_", indent + 1
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def build_missing_targets
|
113
|
+
missing_comps = []
|
114
|
+
|
115
|
+
components.each do |ref, comp|
|
116
|
+
comp.targets.each do |target_ref|
|
117
|
+
next unless components[target_ref].nil?
|
118
|
+
|
119
|
+
type, name = target_ref.split(':')
|
120
|
+
puts name
|
121
|
+
name = name.split('/').first
|
122
|
+
unless name.start_with?('*')
|
123
|
+
new_comp = Component.new(type, { 'name' => name, 'warning' => 'Auto-created by Oschii Parser' })
|
124
|
+
missing_comps << new_comp
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
unless missing_comps.empty?
|
129
|
+
puts
|
130
|
+
puts "WARNING: Creating empty components for unresolved target references."
|
131
|
+
puts " Output configuration may not be valid!"
|
132
|
+
puts
|
133
|
+
|
134
|
+
missing_comps.uniq do |comp|
|
135
|
+
next if components[comp.reference]
|
136
|
+
|
137
|
+
puts " + #{comp}"
|
138
|
+
add_component comp
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def to_h
|
144
|
+
conf = {}
|
145
|
+
|
146
|
+
conf[:name] = @name if @name
|
147
|
+
conf[:description] = @description if @description
|
148
|
+
|
149
|
+
conf[:Startup] = startups
|
150
|
+
|
151
|
+
components.each do |_ref, comp|
|
152
|
+
if comp.type == I2C
|
153
|
+
conf[I2C] ||= {
|
154
|
+
sdaPin: sda, sclPin: scl, clock: clock, modules: []
|
155
|
+
}
|
156
|
+
conf[I2C][:modules] << comp.config
|
157
|
+
else
|
158
|
+
array = (conf[comp.array_name] ||= [])
|
159
|
+
array << comp.config
|
160
|
+
end
|
161
|
+
end
|
162
|
+
conf
|
163
|
+
end
|
164
|
+
|
165
|
+
def to_json
|
166
|
+
to_h.to_json
|
167
|
+
end
|
168
|
+
|
169
|
+
def to_pretty_json
|
170
|
+
JSON.pretty_generate to_h
|
171
|
+
end
|
172
|
+
|
173
|
+
def inspect
|
174
|
+
"#<#{self.class} '#{name}'>"
|
175
|
+
end
|
176
|
+
|
177
|
+
def to_s
|
178
|
+
components.collect do |_ref, comp|
|
179
|
+
"#{comp.type}:#{comp.name} => #{comp.config}"
|
180
|
+
end.join "\n"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
data/lib/oschii/device.rb
CHANGED
@@ -6,6 +6,7 @@ require 'faye/websocket'
|
|
6
6
|
require 'eventmachine'
|
7
7
|
require 'byebug'
|
8
8
|
|
9
|
+
require_relative 'config'
|
9
10
|
module Oschii
|
10
11
|
DeviceUnavailable = Class.new(StandardError)
|
11
12
|
NoConnection = Class.new(StandardError)
|
@@ -145,7 +146,7 @@ module Oschii
|
|
145
146
|
end
|
146
147
|
|
147
148
|
def config
|
148
|
-
@config ||= Oschii::Config.
|
149
|
+
@config ||= Oschii::Config.new(raw_config)
|
149
150
|
end
|
150
151
|
|
151
152
|
def clear!
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require_relative 'config'
|
2
|
+
|
3
|
+
puts Oschii::LOGO
|
4
|
+
puts ' P A R S E R'
|
5
|
+
puts
|
6
|
+
|
7
|
+
if ARGV.empty?
|
8
|
+
puts 'Please specify an input file'
|
9
|
+
exit 0
|
10
|
+
end
|
11
|
+
|
12
|
+
input_filename = ARGV[0]
|
13
|
+
input_filename = "#{input_filename}.json" unless input_filename.end_with? '.json'
|
14
|
+
|
15
|
+
unless File.exists? input_filename
|
16
|
+
puts "File '#{input_filename}' not found"
|
17
|
+
exit 0
|
18
|
+
end
|
19
|
+
|
20
|
+
output_filename = ARGV[1] || "#{input_filename.gsub('.json', '')}_output.json"
|
21
|
+
output_filename = "#{output_filename}.json" unless output_filename.end_with? '.json'
|
22
|
+
|
23
|
+
begin
|
24
|
+
puts "Parsing '#{input_filename}'...."
|
25
|
+
puts
|
26
|
+
conf = Oschii::Config.from_file(input_filename)
|
27
|
+
rescue Oschii::TemplateError => e
|
28
|
+
puts
|
29
|
+
puts "ERROR! #{e.message}"
|
30
|
+
puts
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
|
34
|
+
puts
|
35
|
+
puts "Writing '#{output_filename}'...."
|
36
|
+
puts
|
37
|
+
File.write(output_filename, conf.to_pretty_json)
|
38
|
+
|
39
|
+
puts 'OK'
|
40
|
+
puts
|
data/lib/oschii/session.rb
CHANGED
@@ -5,3 +5,15 @@ include Oschii
|
|
5
5
|
if ENV['OSCHII_AUTO_POPULATE']
|
6
6
|
populate
|
7
7
|
end
|
8
|
+
|
9
|
+
if ENV['OSCHII_AUTO_LOOKUP']
|
10
|
+
def method_missing(m, *args, &block)
|
11
|
+
return if @cloud.nil?
|
12
|
+
|
13
|
+
node = cloud.get(m)
|
14
|
+
|
15
|
+
return node unless node.nil?
|
16
|
+
|
17
|
+
raise NameError
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module Oschii
|
2
|
+
class Template
|
3
|
+
def initialize(config, name = nil)
|
4
|
+
@config = config
|
5
|
+
@name = name || config['name']
|
6
|
+
@params = {}
|
7
|
+
@embedded_customs = []
|
8
|
+
@startups = []
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :config, :name, :params, :embedded_customs, :startups
|
12
|
+
|
13
|
+
def fill_params(json)
|
14
|
+
string = json.to_json
|
15
|
+
|
16
|
+
params.each do |name, value|
|
17
|
+
case value
|
18
|
+
when Integer, Float, TrueClass, FalseClass
|
19
|
+
string.gsub! "\"${#{name}}\"", "#{value}"
|
20
|
+
else
|
21
|
+
string.gsub! "${#{name}}", "#{value}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
JSON.parse(string)
|
26
|
+
end
|
27
|
+
|
28
|
+
def build_components(custom_config, name_prefix = '')
|
29
|
+
bind_params custom_config
|
30
|
+
|
31
|
+
@embedded_customs = []
|
32
|
+
|
33
|
+
config["Customs"]&.each do |inner_custom_def|
|
34
|
+
@embedded_customs << fill_params(inner_custom_def)
|
35
|
+
end
|
36
|
+
|
37
|
+
BASIC_COMPONENT_TYPES.map do |type|
|
38
|
+
config["#{type}s"]&.map do |comp|
|
39
|
+
comp_conf = comp.dup
|
40
|
+
|
41
|
+
comp_conf['name'] = "#{name_prefix}#{custom_config['name']}_#{comp['name']}"
|
42
|
+
|
43
|
+
string = comp_conf.to_json
|
44
|
+
|
45
|
+
params.each do |name, value|
|
46
|
+
case value
|
47
|
+
when Integer, Float, TrueClass, FalseClass
|
48
|
+
string.gsub! "\"${#{name}}\"", "#{value}"
|
49
|
+
else
|
50
|
+
string.gsub! "${#{name}}", "#{value}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Expand in-Template Component References
|
55
|
+
string.gsub!(':@', ":#{name_prefix}#{custom_config['name']}_")
|
56
|
+
|
57
|
+
Component.new(type, JSON.parse(string))
|
58
|
+
end
|
59
|
+
end.flatten.compact
|
60
|
+
end
|
61
|
+
|
62
|
+
def param_names
|
63
|
+
config.to_s.scan(/\$\{\w+}/).collect do |tag|
|
64
|
+
tag.gsub('${', '').gsub('}', '')
|
65
|
+
end.uniq
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
def bind_params(custom_config)
|
70
|
+
missing_params = []
|
71
|
+
param_names.each do |param|
|
72
|
+
value = custom_config[param]
|
73
|
+
if value
|
74
|
+
params[param] = value
|
75
|
+
else
|
76
|
+
missing_params << param
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
unless missing_params.empty?
|
81
|
+
missing_params.each do |param|
|
82
|
+
puts "No value for '#{param}'"
|
83
|
+
end
|
84
|
+
raise Oschii::TemplateError, "Custom:#{custom_config['name']}: Missing parameters"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def to_s
|
89
|
+
inspect
|
90
|
+
end
|
91
|
+
|
92
|
+
def inspect
|
93
|
+
"#<#{self.class} '#{name}'>"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/lib/oschii/version.rb
CHANGED
data/lib/oschii.rb
CHANGED
@@ -11,8 +11,7 @@ module Oschii
|
|
11
11
|
╔═╗┌─┐┌─┐┬ ┬┬┬
|
12
12
|
║ ║└─┐│ ├─┤││
|
13
13
|
╚═╝└─┘└─┘┴ ┴┴┴
|
14
|
-
|
15
|
-
#{VERSION.center(14)}
|
14
|
+
#{"ruby gem #{VERSION}".center(14)}
|
16
15
|
|
17
16
|
".freeze
|
18
17
|
|
@@ -40,16 +39,6 @@ module Oschii
|
|
40
39
|
@serial ||= cloud.find_serial
|
41
40
|
end
|
42
41
|
|
43
|
-
def method_missing(m, *args, &block)
|
44
|
-
return if @cloud.nil?
|
45
|
-
|
46
|
-
node = cloud.get(m)
|
47
|
-
|
48
|
-
return node unless node.nil?
|
49
|
-
|
50
|
-
raise NameError
|
51
|
-
end
|
52
|
-
|
53
42
|
def send_osc(ip, address, *values, port: 3333)
|
54
43
|
OSC::Client.new(ip, port).send(OSC::Message.new(address, *values.to_a))
|
55
44
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oschii_ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Barri Mason
|
@@ -104,12 +104,16 @@ files:
|
|
104
104
|
- Gemfile.lock
|
105
105
|
- lib/oschii.rb
|
106
106
|
- lib/oschii/cloud.rb
|
107
|
+
- lib/oschii/component.rb
|
108
|
+
- lib/oschii/config.rb
|
107
109
|
- lib/oschii/device.rb
|
108
110
|
- lib/oschii/http_device.rb
|
109
111
|
- lib/oschii/osc_monitor.rb
|
112
|
+
- lib/oschii/parser.rb
|
110
113
|
- lib/oschii/serial_device.rb
|
111
114
|
- lib/oschii/servlets.rb
|
112
115
|
- lib/oschii/session.rb
|
116
|
+
- lib/oschii/template.rb
|
113
117
|
- lib/oschii/version.rb
|
114
118
|
homepage: https://rubygems.org/gems/oschii_ruby
|
115
119
|
licenses:
|