mushy 0.9.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,283 @@
1
+ module Mushy
2
+
3
+ class SenseHatLedMatrix < SimplePythonProgram
4
+
5
+ def self.details
6
+ {
7
+ name: 'SenseHatLedMatrix',
8
+ description: 'Interface with the LED Matrix.',
9
+ config: Mushy::SimplePythonProgram.default_config.tap do |config|
10
+ config[:get_pixels] = {
11
+ description: 'Specify the pixels you want returned as events. Use "all" to return all 64, 3,3 to return x:3 y:3, or "none" to return none.',
12
+ type: 'text',
13
+ shrink: true,
14
+ value: 'all',
15
+ }
16
+ config[:set_pixel] = {
17
+ description: 'Set a single pixel to the RGB color.',
18
+ type: 'text',
19
+ shrink: true,
20
+ value: '',
21
+ }
22
+ config[:set_pixels] = {
23
+ description: 'An array of multiple pixels to set. The records must have coordinates and rgb values, just like what comes out of the get pixels call.',
24
+ type: 'text',
25
+ shrink: true,
26
+ value: '',
27
+ }
28
+ config[:rgb] = {
29
+ description: 'The RGB value as a comma-delimited list. Leave blank to not set a color.',
30
+ type: 'text',
31
+ shrink: true,
32
+ value: '',
33
+ }
34
+ config[:background_color] = {
35
+ description: 'The RGB of the background, which is used in some API calls.',
36
+ type: 'text',
37
+ shrink: true,
38
+ value: '',
39
+ }
40
+ config[:clear] = {
41
+ description: 'The RGB color to apply to the entire grid.',
42
+ type: 'text',
43
+ shrink: true,
44
+ value: '',
45
+ }
46
+ config[:show_letter] = {
47
+ description: 'Show a single letter on the grid. Uses Rgb and Background Color.',
48
+ type: 'text',
49
+ shrink: true,
50
+ value: '',
51
+ }
52
+ config[:show_message] = {
53
+ description: 'Scroll a message across the grid. Uses Rgb and Background Color.',
54
+ type: 'text',
55
+ shrink: true,
56
+ value: '',
57
+ }
58
+ config[:load_image] = {
59
+ description: 'Load a 8x8 image.',
60
+ type: 'text',
61
+ shrink: true,
62
+ value: '',
63
+ }
64
+ config[:set_rotation] = {
65
+ description: 'Rotate the image by these degrees.',
66
+ type: 'select',
67
+ options: ['', '0', '90', '180', '270'],
68
+ shrink: true,
69
+ value: '',
70
+ }
71
+ config[:redraw] = {
72
+ description: 'Redraw.',
73
+ type: 'boolean',
74
+ shrink: true,
75
+ value: '',
76
+ }
77
+ config[:low_light] = {
78
+ description: 'Use the low light to turn down the brightness.',
79
+ type: 'boolean',
80
+ shrink: true,
81
+ value: '',
82
+ }
83
+ config[:flip_h] = {
84
+ description: 'Flips the image horizontally.',
85
+ type: 'boolean',
86
+ shrink: true,
87
+ value: '',
88
+ }
89
+ config[:flip_v] = {
90
+ description: 'Flips the image vertically.',
91
+ type: 'boolean',
92
+ shrink: true,
93
+ value: '',
94
+ }
95
+ config[:target] = {
96
+ description: 'The target of these commands. "hat" is a SenseHAT plugged into your Raspberry Pi, and "emu" is the SenseHAT emulator. Defaults to "hat".',
97
+ type: 'select',
98
+ options: ['', 'hat' , 'emu'],
99
+ shrink: true,
100
+ value: '',
101
+ }
102
+ end
103
+ }
104
+ end
105
+
106
+ def python_program event, config
107
+
108
+ commands = [
109
+ :set_pixel_code_from,
110
+ :set_pixels_code_from,
111
+ :clear_pixels_code_from,
112
+ :show_letters_code_from,
113
+ :show_message_code_from,
114
+ :load_images_code_from,
115
+ :set_rotation_code_from,
116
+ :low_light_code_from,
117
+ :flip_h_code_from,
118
+ :flip_v_code_from,
119
+ ].map { |x| self.send x, event, config }
120
+ .select { |x| x.to_s != '' }
121
+ .join("\n")
122
+
123
+ hat = config[:target] == 'emu' ? 'sense_emu' : 'sense_hat'
124
+
125
+ <<PYTHON
126
+ from #{hat} import SenseHat
127
+ import json
128
+ sense = SenseHat()
129
+ #{commands}
130
+ value = json.dumps({"all": #{get_pixels_code_from(event, config)}})
131
+ print(value)
132
+ PYTHON
133
+ end
134
+
135
+ def adjust data, event, config
136
+ limit = 8
137
+
138
+ coordinates = coordinates_from config[:get_pixels]
139
+
140
+ records = coordinates ? [data[:all]] : data[:all]
141
+
142
+ results = records.each_with_index.map do |item, index|
143
+ {
144
+ x: index % limit,
145
+ y: index / limit,
146
+ r: item[0],
147
+ g: item[1],
148
+ b: item[2],
149
+ }
150
+ end
151
+
152
+ if coordinates
153
+ results[0][:x] = coordinates[:x]
154
+ results[0][:y] = coordinates[:y]
155
+ end
156
+
157
+ results.each do |record|
158
+ record[:coordinate] = "#{record[:x]},#{record[:y]}"
159
+ record[:rgb] = "#{record[:r]},#{record[:g]},#{record[:b]}"
160
+ end
161
+
162
+ results
163
+ end
164
+
165
+ def rgb_from config
166
+ color_split = config.to_s.split ','
167
+ return nil unless color_split.count == 3
168
+ return [:r, :g, :b].each_with_index
169
+ .reduce({}) { |t, i| t[i[0]] = color_split[i[1]].to_s.to_i ; t}
170
+ end
171
+
172
+ def coordinates_from config
173
+ coordinate_split = config.to_s.split ','
174
+ return nil unless coordinate_split.count == 2
175
+ return [:x, :y].each_with_index
176
+ .reduce({}) { |t, i| t[i[0]] = coordinate_split[i[1]].to_s.to_i ; t}
177
+ end
178
+
179
+ def set_pixel_code_from event, config
180
+ rgb = rgb_from config[:rgb]
181
+ set_pixel_coordinates = coordinates_from config[:set_pixel]
182
+ return '' unless rgb
183
+ return '' unless set_pixel_coordinates
184
+
185
+ turn_these_to_pixels([ {
186
+ coordinate: "#{set_pixel_coordinates[:x]},#{set_pixel_coordinates[:y]}",
187
+ rgb: "#{rgb[:r]},#{rgb[:g]},#{rgb[:b]}",
188
+ } ])
189
+ end
190
+
191
+ def set_pixels_code_from event, config
192
+ return '' unless config[:set_pixels]
193
+ turn_these_to_pixels config[:set_pixels]
194
+ end
195
+
196
+ def turn_these_to_pixels values
197
+ options = [:coordinate, :rgb]
198
+ values.map do |pixel|
199
+ options.reduce({}) { |t, i| t[i] = pixel[i].split(',') ; t}
200
+ end.map do |pixel|
201
+ "sense.set_pixel(#{pixel[:coordinate][0]}, #{pixel[:coordinate][1]}, [#{pixel[:rgb][0]}, #{pixel[:rgb][1]}, #{pixel[:rgb][2]}])"
202
+ end.join("\n")
203
+ end
204
+
205
+ def clear_pixels_code_from event, config
206
+ clear = rgb_from config[:clear]
207
+ return '' unless clear
208
+ "sense.clear(#{clear[:r]}, #{clear[:g]}, #{clear[:b]})"
209
+ end
210
+
211
+ def show_letters_code_from event, config
212
+ return '' if config[:show_letter].to_s == ''
213
+
214
+ rgb = rgb_from config[:rgb]
215
+ background_color = rgb_from config[:background_color]
216
+
217
+ args = ["\"#{config[:show_letter]}\""]
218
+ args << "text_colour=[#{rgb[:r]}, #{rgb[:g]}, #{rgb[:b]}]" if rgb
219
+ args << "back_colour=[#{background_color[:r]}, #{background_color[:g]}, #{background_color[:b]}]" if background_color
220
+ "sense.show_letter(#{args.join(',')})"
221
+ end
222
+
223
+ def show_message_code_from event, config
224
+ return '' if config[:show_message].to_s == ''
225
+
226
+ rgb = rgb_from config[:rgb]
227
+ background_color = rgb_from config[:background_color]
228
+
229
+ args = ["\"#{config[:show_message]}\""]
230
+ args << "text_colour=[#{rgb[:r]}, #{rgb[:g]}, #{rgb[:b]}]" if rgb
231
+ args << "back_colour=[#{background_color[:r]}, #{background_color[:g]}, #{background_color[:b]}]" if background_color
232
+ "sense.show_message(#{args.join(',')})"
233
+ end
234
+
235
+ def load_images_code_from event, config
236
+ return '' if config[:load_image].to_s == ''
237
+
238
+ args = ["\"#{config[:load_image]}\""]
239
+ args << config[:redraw].to_s.capitalize if config[:redraw].to_s != ''
240
+ "sense.load_image(#{args.join(',')})"
241
+ end
242
+
243
+ def set_rotation_code_from event, config
244
+ return '' if config[:set_rotation].to_s == ''
245
+ args = ["#{config[:set_rotation]}"]
246
+ args << config[:redraw].to_s.capitalize if config[:redraw].to_s != ''
247
+ "sense.set_rotation(#{args.join(',')})"
248
+ end
249
+
250
+ def low_light_code_from event, config
251
+ return '' if config[:low_light].to_s == ''
252
+ "sense.low_light = #{config[:low_light].capitalize}"
253
+ end
254
+
255
+ def flip_h_code_from event, config
256
+ return '' unless config[:flip_h].to_s == 'true'
257
+ args = []
258
+ args << config[:redraw].to_s.capitalize if config[:redraw].to_s != ''
259
+ "sense.flip_h(#{args.join(',')})"
260
+ end
261
+
262
+ def flip_v_code_from event, config
263
+ return '' unless config[:flip_v].to_s == 'true'
264
+ args = []
265
+ args << config[:redraw].to_s.capitalize if config[:redraw].to_s != ''
266
+ "sense.flip_v(#{args.join(',')})"
267
+ end
268
+
269
+ def get_pixels_code_from event, config
270
+ get_pixel_coordinates = coordinates_from config[:get_pixels]
271
+
272
+ if get_pixel_coordinates
273
+ "sense.get_pixel(#{get_pixel_coordinates[:x]}, #{get_pixel_coordinates[:y]})"
274
+ elsif config[:get_pixels].to_s.downcase == 'all'
275
+ 'sense.get_pixels()'
276
+ else
277
+ '[]'
278
+ end
279
+ end
280
+
281
+ end
282
+
283
+ end
@@ -0,0 +1,40 @@
1
+ module Mushy
2
+
3
+ class SimplePythonProgram < Bash
4
+
5
+ def self.default_config
6
+ Mushy::Bash.details[:config].tap do |config|
7
+ config.delete :command
8
+ config.delete :directory
9
+ end
10
+ end
11
+
12
+ def self.details
13
+ nil
14
+ end
15
+
16
+ def process event, config
17
+
18
+ lines = python_program(event, config)
19
+ .split('\n')
20
+ .map { |x| x.rstrip }
21
+ .select { |x| x && x != '' }
22
+ .map { |x| x.gsub('"', '\"') }
23
+
24
+ config[:command] = "python -c \"#{lines.join(';')}\""
25
+
26
+ result = super event, config
27
+
28
+ return nil unless result[:success]
29
+
30
+ adjust SymbolizedHash.new(JSON.parse(result[:text])), event, config
31
+
32
+ end
33
+
34
+ def adjust data, event, config
35
+ data
36
+ end
37
+
38
+ end
39
+
40
+ end
@@ -0,0 +1,29 @@
1
+ require 'csv'
2
+
3
+ module Mushy
4
+
5
+ class WriteJson < Flux
6
+
7
+ def self.details
8
+ {
9
+ name: 'WriteJson',
10
+ description: 'Write the incoming event as JSON.',
11
+ config: {
12
+ key: {
13
+ description: 'The key of the outgoing field that will contain the JSON.',
14
+ type: 'text',
15
+ value: 'json',
16
+ },
17
+ },
18
+ }
19
+ end
20
+
21
+ def process event, config
22
+ {
23
+ config[:key] => event.to_json
24
+ }
25
+ end
26
+
27
+ end
28
+
29
+ end
data/lib/mushy.rb CHANGED
@@ -3,9 +3,16 @@ require 'symbolized'
3
3
 
4
4
  Dir[File.dirname(__FILE__) + '/mushy/*.rb'].each { |f| require f }
5
5
 
6
- important_flux_files = ['bash', 'browser'].map { |x| "#{x}.rb" }
6
+ important_flux_files = [
7
+ 'bash',
8
+ 'browser',
9
+ 'simple_python_program',
10
+ ].map { |x| "#{x}.rb" }
11
+
7
12
  Dir[File.dirname(__FILE__) + '/mushy/fluxs/*.rb']
8
- .sort_by { |f| important_flux_files.any? { |x| f.end_with?(x) } ? 0 : 1 }
9
- .each { |f| require f }
13
+ .map { |x| [x, important_flux_files.find_index(x.split("\/")[-1]) || 9999999] }
14
+ .sort_by { |x| x[1] }
15
+ .map { |x| x[0] }
16
+ .each { |f| require f }
10
17
 
11
18
  Dir[File.dirname(__FILE__) + '/mushy/builder/*.rb'].each { |f| require f }
data/lib/site.rb CHANGED
@@ -8,6 +8,11 @@ get '/' do
8
8
  Mushy::Builder::Index.file
9
9
  end
10
10
 
11
+ get '/bulma.css' do
12
+ content_type :css
13
+ Mushy::Builder::Bulma.file
14
+ end
15
+
11
16
  get '/dark.css' do
12
17
  content_type :css
13
18
  Mushy::Builder::Dark.file
data/mushy.gemspec CHANGED
@@ -4,7 +4,7 @@ require 'mushy/version'
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = 'mushy'
7
- s.version = '0.9.0'
7
+ s.version = '0.14.0'
8
8
  s.date = '2020-11-23'
9
9
  s.summary = 'Process streams of work using common modules.'
10
10
  s.description = 'This tool assists in the creation and processing of workflows.'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mushy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Darren Cauthon
@@ -175,6 +175,7 @@ files:
175
175
  - lib/mushy.rb
176
176
  - lib/mushy/builder/api.rb
177
177
  - lib/mushy/builder/axios.rb
178
+ - lib/mushy/builder/bulma.rb
178
179
  - lib/mushy/builder/dark.rb
179
180
  - lib/mushy/builder/index.rb
180
181
  - lib/mushy/builder/vue.rb
@@ -203,10 +204,15 @@ files:
203
204
  - lib/mushy/fluxs/pwd.rb
204
205
  - lib/mushy/fluxs/read_csv.rb
205
206
  - lib/mushy/fluxs/read_file.rb
207
+ - lib/mushy/fluxs/read_json.rb
206
208
  - lib/mushy/fluxs/screenshot.rb
209
+ - lib/mushy/fluxs/sense_hat_environmental_sensors.rb
210
+ - lib/mushy/fluxs/sense_hat_led_matrix.rb
211
+ - lib/mushy/fluxs/simple_python_program.rb
207
212
  - lib/mushy/fluxs/smtp.rb
208
213
  - lib/mushy/fluxs/times.rb
209
214
  - lib/mushy/fluxs/write_file.rb
215
+ - lib/mushy/fluxs/write_json.rb
210
216
  - lib/mushy/masher.rb
211
217
  - lib/mushy/run.rb
212
218
  - lib/mushy/runner.rb