bstick 0.2.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 860d1e7835ee172ba587158584502eddb9b9c48b
4
+ data.tar.gz: 123ef2faa52bb9c4a128159cdfb032c0a2f009ee
5
+ SHA512:
6
+ metadata.gz: c4370a38df2b414f4e929dacc388f13f14554ded32aa9091f842606b662ec680ae350480c52195e8ebc76b45faa9f2e4b55d4e96854c0c617e6ae8a1425eafa5
7
+ data.tar.gz: 933faedc1f7815b69fee2d5966d68bacd407fa730ac57444b788c4216db243d7b156ebafcceaf6ea8fae0f545b84d7da3373b50cb78c49f7f1dc32ee076651a5
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ if !ARGV[0]
4
+ puts 'no argument'
5
+ exit 0
6
+ end
7
+
8
+ def write(state)
9
+ file = File.expand_path("/var/bstick/led.state")
10
+ File.truncate(file, 0)
11
+ File.write(file, state, 0)
12
+ end
13
+
14
+ case ARGV[0]
15
+ when 'on', 'off', 'blink', 'random' then
16
+ write(ARGV[0])
17
+ when 'ping', 'alarm' then
18
+ write("#{ARGV[0]} #{ARGV[1]}")
19
+ when 'run' then
20
+ write('blink')
21
+ system(ARGV.drop(1).join(' '))
22
+ write('off')
23
+ else
24
+ puts 'invalid argument'
25
+ exit 0
26
+ end
27
+ exit 1
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bstick'
4
+ require 'daemons'
5
+
6
+ if ARGV[0] && ARGV[0] == '-v'
7
+ puts Bstick::VERSION
8
+ exit 1
9
+ end
10
+
11
+ Daemons.run_proc('server.rb') do
12
+ Bstick::Server.new.run
13
+ end
@@ -0,0 +1,186 @@
1
+ #https://github.com/arvydas/blinkstick-ruby
2
+
3
+ require "libusb"
4
+ require "color"
5
+
6
+ class BlinkStick
7
+ @@VENDOR_ID = 0X20A0
8
+ @@PRODUCT_ID = 0x41E5
9
+
10
+ def open(device = nil)
11
+ @@usb ||= LIBUSB::Context.new
12
+
13
+ if (device)
14
+ @device = device
15
+ else
16
+ @device = @@usb.devices(:idVendor => @@VENDOR_ID, :idProduct => @@PRODUCT_ID).first
17
+ end
18
+
19
+ @handle = @device.open
20
+ end
21
+
22
+ def self.find_all
23
+ @@usb ||= LIBUSB::Context.new
24
+
25
+ result = []
26
+
27
+ @@usb.devices(:idVendor => @@VENDOR_ID, :idProduct => @@PRODUCT_ID).each { | device |
28
+ b = BlinkStick.new
29
+ b.open(device)
30
+
31
+ result.push(b)
32
+ }
33
+
34
+ result
35
+ end
36
+
37
+ def self.find_by_serial(serial)
38
+ @@usb ||= LIBUSB::Context.new
39
+
40
+ @@usb.devices(:idVendor => @@VENDOR_ID, :idProduct => @@PRODUCT_ID).each { | device |
41
+ if device.serial_number == serial
42
+ b = BlinkStick.new
43
+ b.open(device)
44
+ return b
45
+ end
46
+ }
47
+
48
+ nil
49
+ end
50
+
51
+ def color=(value)
52
+ @handle.control_transfer(:bmRequestType => 0x20, :bRequest => 0x9, :wValue => 0x1, :wIndex => 0x0000, :dataOut => 1.chr + value.red.to_i.chr + value.green.to_i.chr + value.blue.to_i.chr)
53
+ end
54
+
55
+ def color
56
+ result = @handle.control_transfer(:bmRequestType => 0x80 | 0x20, :bRequest => 0x1, :wValue => 0x1, :wIndex => 0x0000, :dataIn => 4)
57
+ Color::RGB.new(result[1].ord, result[2].ord, result[3].ord)
58
+ end
59
+
60
+ def set_color(channel, index, value)
61
+ attempts = 0
62
+ while attempts < 5
63
+ attempts += 1
64
+
65
+ begin
66
+ @handle.control_transfer(:bmRequestType => 0x20,
67
+ :bRequest => 0x9,
68
+ :wValue => 0x5,
69
+ :wIndex => 0x0000,
70
+ :dataOut => 1.chr + channel.to_i.chr + index.to_i.chr + value.red.to_i.chr + value.green.to_i.chr + value.blue.to_i.chr)
71
+ break
72
+ rescue
73
+ if attempts == 5
74
+ raise
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ def set_colors(channel, data)
81
+ report_id = 9
82
+ max_leds = 64
83
+
84
+ if data.size <= 8 * 3
85
+ max_leds = 8
86
+ report_id = 6
87
+ elsif data.size <= 16 * 3
88
+ max_leds = 16
89
+ report_id = 7
90
+ elsif data.size <= 32 * 3
91
+ max_leds = 32
92
+ report_id = 8
93
+ elsif data.size <= 64 * 3
94
+ max_leds = 64
95
+ report_id = 9
96
+ end
97
+
98
+ report = report_id.chr + channel.to_i.chr
99
+
100
+ (0..max_leds * 3 - 1).each do | i |
101
+ if data.size > i
102
+ report += data[i].to_i.chr
103
+ else
104
+ report += 0.chr
105
+ end
106
+ end
107
+
108
+ #Debug code
109
+ #puts report.unpack('U'*report.length).collect {|x| x.to_s 16}.join(" ")
110
+
111
+ attempts = 0
112
+ while attempts < 5
113
+ attempts += 1
114
+
115
+ begin
116
+ @handle.control_transfer(:bmRequestType => 0x20,
117
+ :bRequest => 0x9,
118
+ :wValue => report_id,
119
+ :wIndex => 0,
120
+ :dataOut => report)
121
+ break
122
+ rescue
123
+ if attempts == 5
124
+ raise
125
+ end
126
+ end
127
+ end
128
+ end
129
+
130
+ def off
131
+ self.color = Color::RGB.new(0, 0, 0)
132
+ end
133
+
134
+ def get_info_block(id)
135
+ bytes = @handle.control_transfer(:bmRequestType => 0x80 | 0x20, :bRequest => 0x1, :wValue => id + 1, :wIndex => 0x0000, :dataIn => 33)
136
+
137
+ result = ""
138
+ for i in 1..(bytes.length-1)
139
+ if i == "\x00"
140
+ break
141
+ end
142
+ result += bytes[i]
143
+ end
144
+
145
+ result
146
+ end
147
+
148
+ def set_info_block(id, data)
149
+ data = (id + 1).chr + data
150
+ data = data + 0.chr while data.length < 33
151
+ @handle.control_transfer(:bmRequestType => 0x20, :bRequest => 0x9, :wValue => id + 1, :wIndex => 0x0000, :dataOut => data)
152
+ end
153
+
154
+ def random_color
155
+ r = Random.new
156
+ self.color = Color::RGB.new(r.rand(255), r.rand(255), r.rand(255))
157
+ end
158
+
159
+ def serial
160
+ @device.serial_number
161
+ end
162
+
163
+ def manufacturer
164
+ @device.manufacturer
165
+ end
166
+
167
+ def description
168
+ @device.product
169
+ end
170
+
171
+ def info_block1
172
+ get_info_block(1)
173
+ end
174
+
175
+ def info_block1=(value)
176
+ set_info_block(1, value)
177
+ end
178
+
179
+ def info_block2
180
+ get_info_block(2)
181
+ end
182
+
183
+ def info_block2=(value)
184
+ set_info_block(2, value)
185
+ end
186
+ end
@@ -0,0 +1,146 @@
1
+ require "bstick/version"
2
+ require "net/ping"
3
+ require "logger"
4
+ require_relative "blinkstick.rb"
5
+
6
+ module Bstick
7
+ class Server
8
+ def initialize
9
+ init
10
+ end
11
+
12
+ def init
13
+ system 'sudo mkdir -p /var/bstick'
14
+ system 'sudo chmod 777 /var/bstick'
15
+ system 'sudo touch /var/bstick/led.state'
16
+ system 'sudo chmod 777 /var/bstick/led.state'
17
+ @logger = ::Logger.new('/var/bstick/bstick.log', 1, 1024000)
18
+ @state = ''
19
+ @values = nil
20
+ @b = nil
21
+ end
22
+
23
+ def stick
24
+ @b ||= BlinkStick.find_all.first
25
+ end
26
+
27
+ def black
28
+ @black ||= Color::RGB.from_html("#000000")
29
+ end
30
+
31
+ def green
32
+ @green = Color::RGB.new(0x00, 0xFF, 0x00)
33
+ end
34
+
35
+ def red
36
+ @red = Color::RGB.new(0xFF, 0x00, 0x00)
37
+ end
38
+
39
+ def read_state
40
+ @old_state = @state
41
+ file = File.expand_path("/var/bstick/led.state", __FILE__)
42
+ @file = File.open(file, "a+")
43
+ File.chmod(0777, file)
44
+ @file.seek(0)
45
+ @state = @file.readline.strip rescue 'off'
46
+ @file.close
47
+ end
48
+
49
+ def set_colors(color_1, color_2)
50
+ if stick
51
+ if (color_1 != @color_1 || color_2 != @color_2)
52
+ @logger.info @state
53
+ stick.set_color(0, 0, color_1)
54
+ stick.set_color(0, 1, color_2)
55
+ @color_1 = color_1
56
+ @color_2 = color_2
57
+ end
58
+ else
59
+ @logger.error 'no stick found'
60
+ sleep 10
61
+ init
62
+ end
63
+ end
64
+
65
+ def off_state
66
+ set_colors(black, black)
67
+ end
68
+
69
+ def on_state
70
+ set_colors(green, green)
71
+ end
72
+
73
+ def blink_state
74
+ @values = { green: 0, direction: 20 } if !@values
75
+ color_1 = Color::RGB.new(0xFF - @values[:green], @values[:green], 0x00)
76
+ color_2 = Color::RGB.new(@values[:green], 0xFF - @values[:green], 0x00)
77
+ @values[:green] += @values[:direction]
78
+ if(@values[:green] < 0 || @values[:green] > 0xFF)
79
+ @values[:direction] *= -1
80
+ end
81
+ set_colors(color_1, color_2)
82
+ end
83
+
84
+ def ping_state
85
+ @wait += 1
86
+ return if @wait < 15 * 33
87
+ @wait = 0
88
+ url = @state.split(' ')[1] || "http://www.undefine.io"
89
+ ping = Net::Ping::HTTP.new(url)
90
+ @logger.info "ping #{url} #{ping.ping?}"
91
+ if result = ping.ping?
92
+ set_colors(green, green)
93
+ else
94
+ set_colors(red, red)
95
+ end
96
+ end
97
+
98
+ def random_state
99
+ @wait += 1
100
+ return if @wait < 0.5 * 33
101
+ @wait = 0
102
+ color_1 = Color::RGB.new(rand(0..0xFF), rand(0..0xFF), rand(0..0xFF))
103
+ color_2 = Color::RGB.new(rand(0..0xFF), rand(0..0xFF), rand(0..0xFF))
104
+ set_colors(color_1, color_2)
105
+ end
106
+
107
+ def alarm_state
108
+ time = Time.parse(@state.split(' ')[1])
109
+ if Time.now < time
110
+ on_state
111
+ else
112
+ random_state
113
+ end
114
+ end
115
+
116
+ def handle_state
117
+ if @old_state != @state
118
+ @values = nil
119
+ @wait = 100000000000000
120
+ end
121
+ case @state.split(' ').first
122
+ when 'off' then off_state
123
+ when 'random'then random_state
124
+ when 'on' then on_state
125
+ when 'blink' then blink_state
126
+ when 'ping' then ping_state
127
+ when 'alarm' then alarm_state
128
+ end
129
+ end
130
+
131
+ def run
132
+ @logger.info 'started'
133
+ loop do
134
+ begin
135
+ read_state
136
+ handle_state
137
+ sleep 1/33.0
138
+ rescue => e
139
+ @logger.error e.message
140
+ sleep 10
141
+ init
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,3 @@
1
+ module Bstick
2
+ VERSION = "0.2.0"
3
+ end
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bstick
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - bseverac
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-09-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: color
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.8'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.8'
69
+ - !ruby/object:Gem::Dependency
70
+ name: libusb
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.5'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.5'
83
+ - !ruby/object:Gem::Dependency
84
+ name: net-ping
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '2.0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '2.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: daemons
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.2'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.2'
111
+ description: ''
112
+ email:
113
+ - bseverac@gmail.com
114
+ executables:
115
+ - bstick
116
+ - bstick_server
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - bin/bstick
121
+ - bin/bstick_server
122
+ - lib/blinkstick.rb
123
+ - lib/bstick.rb
124
+ - lib/bstick/version.rb
125
+ homepage: ''
126
+ licenses:
127
+ - MIT
128
+ metadata: {}
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubyforge_project:
145
+ rubygems_version: 2.4.5.1
146
+ signing_key:
147
+ specification_version: 4
148
+ summary: Blinkstick server watching file state and utilities
149
+ test_files: []