oschii_ruby 0.0.1 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bb0e8b35b66541a40236ea7a4595518d8a9d6727105c2543e74ca5d6fbb8443f
4
- data.tar.gz: 1d9c121b90502130c86056f9818dca4b6a81fe9485734e257e9f261891bbe6f8
3
+ metadata.gz: 578aa88e4dd107c6af19e80da3419deae8fbcc56052cb8272a824f81ceaaddd3
4
+ data.tar.gz: 9f3b0a12310effb1832975cd5edba9846e2a83550b2df0e8ee4554d6175414a2
5
5
  SHA512:
6
- metadata.gz: 8b35574e7713cdc5bf13d0e9710894818bc48c72a7a86ade3c6b8688a4449548a2106b01adeb52ac99585f7356f195b4c90999029a0b2aca3c1c6f3d170fb0c0
7
- data.tar.gz: 57a436a356063c353d9e8f5a5a18014fce3aa2016b689f50b7daef79cf3efcba1a643d6081fb5669a81e0ddcbb8230735575439e3d1db2dba915d8c13dadb106
6
+ metadata.gz: 6558856f498bc70b8fa419aa3bb65f43c1cecd66337a2c1bdd3e5b6e8bd3e49f042751f16280370f5f17ef53e4675d9c656e5a33d28423b3f5e2a0f0ee3c2a89
7
+ data.tar.gz: 1d28d3da39dc9de4326b577d1aa19780ac5d369952ba7274fb441544460714902801f8e3bfaf4fb45d85c24ddf350a9bb89e48877d466259c92128ace69c0bba
data/Gemfile CHANGED
@@ -9,4 +9,5 @@ gemspec
9
9
  group :development do
10
10
  gem 'make_menu'
11
11
  gem 'byebug'
12
+ gem 'bump'
12
13
  end
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- oschii_ruby (0.0.1)
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.parse(raw_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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Oschii
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.6'
3
3
  end
data/lib/oschii.rb CHANGED
@@ -11,8 +11,7 @@ module Oschii
11
11
  ╔═╗┌─┐┌─┐┬ ┬┬┬
12
12
  ║ ║└─┐│ ├─┤││
13
13
  ╚═╝└─┘└─┘┴ ┴┴┴
14
- -- R U B Y ---
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.1
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: