lirc 0.3.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f48efe7d977a6031e1408e0871541883aa0ed929f2479f7962e4870aff22ec6a
4
+ data.tar.gz: 6f5746e35b5828d76f8422b66140f672c2b2c2f880159fc2f800a498a9d06fd5
5
+ SHA512:
6
+ metadata.gz: aaf93ac913656b7255e14b52b972950ed9309d941fe41aa0bec65c4c278cf0444b210445c47b100d950e5ba905780096600e7e9dfb308917d932598c5dad3400
7
+ data.tar.gz: 0c6d9f2d0b7b126d476e234823affa52b2feb472f04483bd2343edb3b05475b52ab3810415c9abb688cf557fefc944f2d6b270d144c811789dcf7a8e41188aa4
@@ -0,0 +1,36 @@
1
+ on:
2
+ push:
3
+ tags:
4
+ - 'v*'
5
+
6
+ name: Build & release gem
7
+ jobs:
8
+ release:
9
+ name: Build & release gem
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v2
13
+ - uses: ruby/setup-ruby@v1
14
+ with:
15
+ ruby-version: 2.5
16
+ bundler-cache: true
17
+ - run: bundle exec bin/release-check
18
+ - run: bundle exec bin/extract-changelog > release.md
19
+ - run: gem build lirc.gemspec
20
+ - uses: actions/create-release@v1
21
+ env:
22
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
23
+ with:
24
+ tag_name: ${{ github.ref }}
25
+ release_name: Release ${{ github.ref }}
26
+ draft: false
27
+ prerelease: false
28
+ body_path: release.md
29
+ - name: Publish to RubyGems
30
+ run: |
31
+ mkdir -p "$HOME/.gem"
32
+ printf -- "---\n:rubygems_api_key: $RUBYGEMS_API_KEY\n" > "$HOME/.gem/credentials"
33
+ chmod 0600 "$HOME/.gem/credentials"
34
+ gem push *.gem
35
+ env:
36
+ RUBYGEMS_API_KEY: ${{secrets.RUBYGEMS_AUTH_TOKEN}}
@@ -0,0 +1,47 @@
1
+ ---
2
+
3
+ name: Run tests
4
+ on:
5
+ - push
6
+ - pull_request
7
+
8
+ jobs:
9
+ rspec:
10
+ name: RSpec
11
+ runs-on: ${{ matrix.os }}
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ ruby:
16
+ - ruby-2.5
17
+ - ruby-2.6
18
+ - ruby-2.7
19
+ os:
20
+ - macos-latest
21
+ - ubuntu-latest
22
+ steps:
23
+ - uses: actions/checkout@v2
24
+ - uses: ruby/setup-ruby@v1
25
+ with:
26
+ ruby-version: ${{ matrix.ruby }}
27
+ bundler-cache: true
28
+ - run: bundle exec rspec
29
+ test-build:
30
+ name: Test building the gem
31
+ runs-on: ${{ matrix.os }}
32
+ strategy:
33
+ matrix:
34
+ ruby:
35
+ - ruby-2.5
36
+ - ruby-2.6
37
+ - ruby-2.7
38
+ os:
39
+ - macos-latest
40
+ - ubuntu-latest
41
+ steps:
42
+ - uses: actions/checkout@v2
43
+ - uses: ruby/setup-ruby@v1
44
+ with:
45
+ ruby-version: ${{ matrix.ruby }}
46
+ bundler-cache: true
47
+ - run: bundle exec gem build lirc.gemspec
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ *.gem
11
+ # rspec failure tracking
12
+ .rspec_status
data/.mutant.yml ADDED
@@ -0,0 +1,5 @@
1
+ integration: rspec
2
+ includes:
3
+ - lib
4
+ requires:
5
+ - lirc
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format Fuubar
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,25 @@
1
+ # The behavior of RuboCop can be controlled via the .rubocop.yml
2
+ # configuration file. It makes it possible to enable/disable
3
+ # certain cops (checks) and to alter their behavior if they accept
4
+ # any parameters. The file can be placed either in your home
5
+ # directory or in some project directory.
6
+ #
7
+ # RuboCop will start looking for the configuration file in the directory
8
+ # where the inspected file is and continue its way up to the root directory.
9
+ #
10
+ # See https://docs.rubocop.org/rubocop/configuration
11
+ #
12
+
13
+ AllCops:
14
+ TargetRubyVersion: "2.4"
15
+
16
+ Style/StringLiterals:
17
+ EnforcedStyle: double_quotes
18
+
19
+ Style/TrailingCommaInArrayLiteral:
20
+ EnforcedStyleForMultiline: trailing_comma
21
+ Style/TrailingCommaInHashLiteral:
22
+ EnforcedStyleForMultiline: trailing_comma
23
+
24
+ Metrics/LineLength:
25
+ Max: 80
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.7.0
6
+ before_install: gem install bundler -v 2.1.2
data/CHANGELOG.md ADDED
@@ -0,0 +1,44 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
5
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [0.3.0] - 2021-01-17
8
+
9
+ ### Added
10
+ - Finally got round to writing a changelog.
11
+ - Released to rubygems.org
12
+ - First version released to Github releases
13
+ - 100% mutation coverage
14
+ - Note: Versions prior to 0.3.0 were never tagged, built, nor released.
15
+
16
+ ### Changed
17
+ - Correctly specified rubies supported for the first time.
18
+ - Dropped support for Ruby 2.4
19
+
20
+ ### Fixed
21
+ - Fixed issue where `LIRC::Messages::ResponseParser#parse_line` could return
22
+ `ArgumentError` instead of `ParseError` in rare circumstances.
23
+
24
+
25
+ ## [0.2.0] - 2020-ish [YANKED]
26
+
27
+ ### Added
28
+
29
+ - `irsend` executable in `bin` dir, as an example for usage
30
+ - `LIRC::Protocol`, including response parsing and command-sending.
31
+ `#send_command` returns an `EM::Deferrable` that succeeds/fails after the LIRC
32
+ server responds.
33
+
34
+
35
+ ## [0.1.0] - 2020-ish [YANKED]
36
+
37
+ ### Added
38
+
39
+ - Sketch of project structure
40
+ - Note: A 0.1.0 release was never made (nor a tag) - so it has been marked as
41
+ [YANKED] above.
42
+
43
+
44
+ [0.3.0]: https://github.com/telyn/ruby-lirc/releases/v0.3.0
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,25 @@
1
+ hey! Thanks for considering contributing. I'm happy to receive any issues you
2
+ have, or even better any PRs for features you may want.
3
+
4
+ For issues please try to describe as comprehensively as you can what you were
5
+ doing / what you want to do so I can reproduce the bug or design in the feature
6
+ you want. Even better if you could add in code snippets, and for bugs you're
7
+ raising due to unexpected errors, please include the full error message and all
8
+ backtrace :-)
9
+
10
+ Some guidelines for PRs:
11
+
12
+ Please use RuboCop. It doesn't have to be perfect, but do try to match the
13
+ general style I've got going on.
14
+
15
+ Tests are mandatory for any new stuff! Please fix any tests you break. If you
16
+ break any tests inside a `describe "internals"` block, just change it to an
17
+ `xdescribe` block.
18
+
19
+ IMO the ResponseParser is only in charge of splitting the command, success &
20
+ data sections of a response. If you're adding additional parsing (e.g. parsing a
21
+ `LIST <remote>` response to get remote names) - that parser should be separate
22
+ and called manually on the `Response`. I'm happy for `Response` to grow a
23
+ `#parse` method which chooses the parser based on the command though :)
24
+
25
+ Have fun!
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+ source 'https://oss:N16UPtnejBEApoTDzs7SZsJyjsXSINhZ@gem.mutant.dev' do
5
+ gem 'mutant-license', require: false
6
+ end
7
+
8
+ # Specify your gem's dependencies in lirc.gemspec
9
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,117 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ lirc (0.3.0)
5
+ eventmachine (~> 1.2)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ remote: https://oss:N16UPtnejBEApoTDzs7SZsJyjsXSINhZ@gem.mutant.dev/
10
+ specs:
11
+ ast (2.4.1)
12
+ coderay (1.1.3)
13
+ concurrent-ruby (1.1.7)
14
+ diff-lcs (1.4.4)
15
+ eventmachine (1.2.7)
16
+ faker (2.15.1)
17
+ i18n (>= 1.6, < 2)
18
+ ffi (1.14.2)
19
+ formatador (0.2.5)
20
+ fuubar (2.5.1)
21
+ rspec-core (~> 3.0)
22
+ ruby-progressbar (~> 1.4)
23
+ guard (2.16.2)
24
+ formatador (>= 0.2.4)
25
+ listen (>= 2.7, < 4.0)
26
+ lumberjack (>= 1.0.12, < 2.0)
27
+ nenv (~> 0.1)
28
+ notiffany (~> 0.0)
29
+ pry (>= 0.9.12)
30
+ shellany (~> 0.0)
31
+ thor (>= 0.18.1)
32
+ guard-compat (1.2.1)
33
+ guard-rspec (4.7.3)
34
+ guard (~> 2.1)
35
+ guard-compat (~> 1.1)
36
+ rspec (>= 2.99.0, < 4.0)
37
+ i18n (1.8.7)
38
+ concurrent-ruby (~> 1.0)
39
+ listen (3.4.1)
40
+ rb-fsevent (~> 0.10, >= 0.10.3)
41
+ rb-inotify (~> 0.9, >= 0.9.10)
42
+ lumberjack (1.2.8)
43
+ method_source (1.0.0)
44
+ mutant (0.10.26)
45
+ diff-lcs (~> 1.3)
46
+ parser (~> 3.0.0)
47
+ regexp_parser (~> 2.0, >= 2.0.3)
48
+ unparser (~> 0.6.0)
49
+ mutant-license (0.1.1.2.2047963385231461769331476801441011296942.1)
50
+ mutant-rspec (0.10.26)
51
+ mutant (= 0.10.26)
52
+ rspec-core (>= 3.8.0, < 4.0.0)
53
+ nenv (0.3.0)
54
+ notiffany (0.1.3)
55
+ nenv (~> 0.1)
56
+ shellany (~> 0.0)
57
+ parallel (1.20.1)
58
+ parser (3.0.0.0)
59
+ ast (~> 2.4.1)
60
+ pry (0.13.1)
61
+ coderay (~> 1.1)
62
+ method_source (~> 1.0)
63
+ rainbow (3.0.0)
64
+ rake (12.3.3)
65
+ rb-fsevent (0.10.4)
66
+ rb-inotify (0.10.1)
67
+ ffi (~> 1.0)
68
+ regexp_parser (2.0.3)
69
+ rexml (3.2.4)
70
+ rspec (3.10.0)
71
+ rspec-core (~> 3.10.0)
72
+ rspec-expectations (~> 3.10.0)
73
+ rspec-mocks (~> 3.10.0)
74
+ rspec-core (3.10.1)
75
+ rspec-support (~> 3.10.0)
76
+ rspec-expectations (3.10.1)
77
+ diff-lcs (>= 1.2.0, < 2.0)
78
+ rspec-support (~> 3.10.0)
79
+ rspec-mocks (3.10.1)
80
+ diff-lcs (>= 1.2.0, < 2.0)
81
+ rspec-support (~> 3.10.0)
82
+ rspec-support (3.10.1)
83
+ rubocop (1.8.1)
84
+ parallel (~> 1.10)
85
+ parser (>= 3.0.0.0)
86
+ rainbow (>= 2.2.2, < 4.0)
87
+ regexp_parser (>= 1.8, < 3.0)
88
+ rexml
89
+ rubocop-ast (>= 1.2.0, < 2.0)
90
+ ruby-progressbar (~> 1.7)
91
+ unicode-display_width (>= 1.4.0, < 3.0)
92
+ rubocop-ast (1.4.0)
93
+ parser (>= 2.7.1.5)
94
+ ruby-progressbar (1.11.0)
95
+ shellany (0.0.1)
96
+ thor (1.0.1)
97
+ unicode-display_width (2.0.0)
98
+ unparser (0.6.0)
99
+ diff-lcs (~> 1.3)
100
+ parser (>= 3.0.0)
101
+
102
+ PLATFORMS
103
+ ruby
104
+
105
+ DEPENDENCIES
106
+ faker (~> 2.14)
107
+ fuubar (~> 2.5)
108
+ guard-rspec (~> 4.7)
109
+ lirc!
110
+ mutant-license!
111
+ mutant-rspec (~> 0.10.21)
112
+ rake (~> 12.0)
113
+ rspec (~> 3.0)
114
+ rubocop (~> 1.2)
115
+
116
+ BUNDLED WITH
117
+ 2.1.2
data/Guardfile ADDED
@@ -0,0 +1,70 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ ## Uncomment and set this to only include directories you want to watch
5
+ # directories %w(app lib config test spec features) \
6
+ # .select{|d| Dir.exist?(d) ? d : UI.warning("Directory #{d} does not exist")}
7
+
8
+ ## Note: if you are using the `directories` clause above and you are not
9
+ ## watching the project directory ('.'), then you will want to move
10
+ ## the Guardfile to a watched dir and symlink it back, e.g.
11
+ #
12
+ # $ mkdir config
13
+ # $ mv Guardfile config/
14
+ # $ ln -s config/Guardfile .
15
+ #
16
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
17
+
18
+ # Note: The cmd option is now required due to the increasing number of ways
19
+ # rspec may be run, below are examples of the most common uses.
20
+ # * bundler: 'bundle exec rspec'
21
+ # * bundler binstubs: 'bin/rspec'
22
+ # * spring: 'bin/rspec' (This will use spring if running and you have
23
+ # installed the spring binstubs per the docs)
24
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
25
+ # * 'just' rspec: 'rspec'
26
+
27
+ guard :rspec, cmd: "bundle exec rspec" do
28
+ require "guard/rspec/dsl"
29
+ dsl = Guard::RSpec::Dsl.new(self)
30
+
31
+ # Feel free to open issues for suggestions and improvements
32
+
33
+ # RSpec files
34
+ rspec = dsl.rspec
35
+ watch(rspec.spec_helper) { rspec.spec_dir }
36
+ watch(rspec.spec_support) { rspec.spec_dir }
37
+ watch(rspec.spec_files)
38
+
39
+ # Ruby files
40
+ ruby = dsl.ruby
41
+ dsl.watch_spec_files_for(ruby.lib_files)
42
+
43
+ # Rails files
44
+ rails = dsl.rails(view_extensions: %w(erb haml slim))
45
+ dsl.watch_spec_files_for(rails.app_files)
46
+ dsl.watch_spec_files_for(rails.views)
47
+
48
+ watch(rails.controllers) do |m|
49
+ [
50
+ rspec.spec.call("routing/#{m[1]}_routing"),
51
+ rspec.spec.call("controllers/#{m[1]}_controller"),
52
+ rspec.spec.call("acceptance/#{m[1]}")
53
+ ]
54
+ end
55
+
56
+ # Rails config changes
57
+ watch(rails.spec_helper) { rspec.spec_dir }
58
+ watch(rails.routes) { "#{rspec.spec_dir}/routing" }
59
+ watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
60
+
61
+ # Capybara features specs
62
+ watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") }
63
+ watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") }
64
+
65
+ # Turnip features and steps
66
+ watch(%r{^spec/acceptance/(.+)\.feature$})
67
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
68
+ Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
69
+ end
70
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Telyn Z.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # Lirc
2
+
3
+ I promise I'll write proper instructions on usage eventually, but for now I'm
4
+ using it in
5
+ [ps2bootlink](https://github.com/telyn/ps2client-rb/blob/master/bin/ps2bootlink)
6
+ from my [ps2client-rb](https://github.com/telyn/ps2client-rb) repo - so take a
7
+ look there for how I'm using it
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'lirc'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle install
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install lirc
24
+
25
+ ## Usage
26
+
27
+ TODO: Write usage instructions here
28
+
29
+ ## Development
30
+
31
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
32
+
33
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
34
+
35
+ ## Contributing
36
+
37
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/lirc.
38
+
39
+
40
+ ## License
41
+
42
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "lirc"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "lirc"
5
+
6
+ version_number = LIRC::VERSION.gsub('.', '\\.')
7
+
8
+ state = :waiting_for_version
9
+ File.open('CHANGELOG.md', 'r').each_line do |line|
10
+ case state
11
+ when :waiting_for_version
12
+ if line =~ /\A## \[(.+?)\]/
13
+ latest_version = Regexp.last_match[1]
14
+ if latest_version == LIRC::VERSION
15
+ puts line
16
+ state = :reading_changelog
17
+ else
18
+ raise "Expected latest version in changelog to be '#{LIRC::VERSION}', was '#{latest_version}'"
19
+ end
20
+ end
21
+ when :reading_changelog
22
+ if line =~ /\A## /
23
+ state = :done
24
+ else
25
+ puts line
26
+ end
27
+ end
28
+ break if state == :done
29
+ end
30
+ if state != :done
31
+ raise "Got to end of file in #{state} state?"
32
+ end
data/bin/irsend ADDED
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "eventmachine"
5
+ require "lirc/protocol"
6
+ require "lirc/commands"
7
+
8
+ server = ENV["LIRCD_SERVER"]
9
+ port = ENV["LIRCD_PORT"].to_i || 8765
10
+ if server.nil? || port == 0
11
+ puts "LIRCD_SERVER or LIRCD_PORT env var missing"
12
+ end
13
+
14
+ unless ARGV.size == 3
15
+ puts "Usage: irsend <remote> <button> <repeat count>"
16
+ exit 1
17
+ end
18
+
19
+ remote, button, repeats = ARGV[0,3]
20
+ repeats = repeats.to_i
21
+
22
+ command_to_send = LIRC::Commands::SendOnce.new(remote, button, repeats)
23
+
24
+ exit_code = 0;
25
+
26
+ class IRSendConn < EventMachine::Connection
27
+ include LIRC::Protocol
28
+
29
+ def initialize(command_to_send, *args)
30
+ @awaiting_response_for = command_to_send.serialize
31
+ super(*args)
32
+ end
33
+
34
+ def receive_message(message)
35
+ return unless message.is_a? LIRC::Messages::Response
36
+
37
+ if message.command == @awaiting_response_for
38
+ if message.success
39
+ puts "#{@awaiting_response_for.split(" ").first} succeeded!"
40
+ exit
41
+ else
42
+ puts "Command failed!"
43
+ exit(1)
44
+ end
45
+ else
46
+ puts "got an irrelevant message"
47
+ puts message.inspect
48
+ end
49
+ end
50
+
51
+ def exit(code = 0)
52
+ exit_code = code
53
+ EventMachine.stop
54
+ end
55
+ end
56
+
57
+ puts "attempting to connect to #{server}:#{port}"
58
+ EventMachine.run do
59
+ EventMachine.connect(server, port, IRSendConn, command_to_send) do |connection|
60
+ connection.send_command(command_to_send)
61
+ end
62
+ end
63
+
64
+ exit(exit_code)
data/bin/release-check ADDED
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ tag = `git describe --tag`.chomp
4
+ unless $?.success?
5
+ raise "git tag could not run - release check fails"
6
+ end
7
+
8
+ unless tag =~ /\Av([\d\.]+)\z/
9
+ raise "git tag (#{tag}) is not a valid version tag - release check fails"
10
+ exit 1
11
+ end
12
+
13
+
14
+ tag_version = Regexp.last_match[1]
15
+
16
+ require "bundler/setup"
17
+ unless tag_version.eql?(LIRC::VERSION)
18
+ raise "version from git tag (#{tag}) does not match LIRC::VERSION (#{LIRC::VERSION}) - release check fails"
19
+ end
20
+
21
+ puts "version from git tag (#{tag_version}) matches LIRC::VERSION"
22
+ puts "release check succeeds - proceed with building gem"
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/faker/lirc.rb ADDED
@@ -0,0 +1,52 @@
1
+ module Faker
2
+ # LIRC-related faker stuff
3
+ class LIRC < Base
4
+ class << self
5
+ ##
6
+ # Produces a random LIRC response type
7
+ #
8
+ # @return [String]
9
+ #
10
+ # @example
11
+ # Faker::LIRC.button_name #=> "KEY_GREEN"
12
+ def button_name
13
+ fetch('lirc.button_name')
14
+ end
15
+
16
+ ##
17
+ # Produces a random LIRC response type
18
+ #
19
+ # @return [String]
20
+ #
21
+ # @example
22
+ # Faker::LIRC.remote_name #=> "RMT-V189-KARAOKE"
23
+ def remote_name
24
+ fetch('lirc.remote_name')
25
+ end
26
+
27
+ ##
28
+ # Produces a random LIRC response type
29
+ #
30
+ # @return [String]
31
+ #
32
+ # @example
33
+ # Faker::LIRC.reply_type #=> "SEND_ONCE"
34
+ def reply_type
35
+ fetch('lirc.reply_type')
36
+ end
37
+
38
+ ##
39
+ # Produces a random LIRC response success
40
+ #
41
+ # @return [String]
42
+ #
43
+ # @example
44
+ # Faker::LIRC.reply_type #=> "SUCCESS"
45
+ def reply_success
46
+ fetch('lirc.reply_success')
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ I18n.load_path += ::Dir[::File.join(__dir__, '*.yml')]
@@ -0,0 +1,103 @@
1
+ en:
2
+ faker:
3
+ lirc:
4
+ reply_success:
5
+ - SUCCESS
6
+ - ERROR
7
+ reply_type:
8
+ - SEND_ONCE
9
+ - SEND_START
10
+ - SEND_STOP
11
+ - LIST
12
+ - SET_INPUTLOG
13
+ - DRV_OPTION
14
+ - SIMULATE
15
+ - SET_TRANSMITTERS
16
+ - VERSION
17
+ button_name:
18
+ - KEY_POWER
19
+ - KEY_BACK
20
+ - KEY_MENU
21
+ - KEY_LEFT
22
+ - KEY_RIGHT
23
+ - KEY_UP
24
+ - KEY_DOWN
25
+ - KEY_OK
26
+ - KEY_F11
27
+ - KEY_SEARCH
28
+ - KEY_GREEN
29
+ - KEY_BLUE
30
+ - KEY_YELLOW
31
+ - X_KEY_ORANGE
32
+ - X_KEY_PURPLE
33
+ - KEY_PLAY
34
+ - KEY_VOLUMEUP
35
+ - KEY_VOLUMEDOWN
36
+ - KEY_HOME
37
+ remote_name:
38
+ - SONY-TV
39
+ - Sharp
40
+ - RMT-V189-KARAOKE
41
+ - nVidia_UR88A
42
+ - CDP-790
43
+ - ComPro_VideoMate-K300
44
+ - Panasonic_VSQS1480
45
+ - Motorola_IRC442-2
46
+ - Akai_RC-C79
47
+ - Viewsonic_N3200w
48
+ - rm
49
+ - Cambridge_Audio_RC-340AC/540AC/640AC_RC5
50
+ - Daas_Color_RCS_9085
51
+ - RC2000
52
+ - Robot_Kit
53
+ - ONKYO_RC-50
54
+ - MAXY1708
55
+ - Tevion_MD81302
56
+ - Toshiba_RM-614Q
57
+ - Elite_9361-3EL
58
+ - DM_7000
59
+ - Xoro_DVB_210_T
60
+ - RT111_101
61
+ - Foxtel_Digital_Cable_STB
62
+ - SHARP_G1014BMSA
63
+ - Schneider_RC-193
64
+ - DLink_DSM-10
65
+ - Tivo_S2_VOL
66
+ - Toshiba_SE-R0031
67
+ - Onkyo_RC-146T
68
+ - rc-c003
69
+ - iMON-PAD
70
+ - Asus_RC1974502_00
71
+ - RM-SE7AV
72
+ - SVEN_HT-475
73
+ - Kaon_KTF-100CO
74
+ - Philips_PM335_0324
75
+ - VI77760
76
+ - RC-6051
77
+ - RMT-D157P-VOL-BUTTONS
78
+ - rm-d29m
79
+ - Samsung_SV-411X
80
+ - YAMAHA_VM70300
81
+ - RM-RXUA4
82
+ - TV
83
+ - vcr
84
+ - Sony_RM-SV236_12
85
+ - Lenco
86
+ - Samsung_BN59-00869A
87
+ - RP_35
88
+ - Kenwood_RC-R0614
89
+ - NokiaVC620
90
+ - HUMAX
91
+ - SkyDigital
92
+ - Sony_RMT-V501A
93
+ - toshiba
94
+ - Sony_RMT-V181N
95
+ - Sony-RMT-256A-VCR
96
+ - Now_Broadband_TV
97
+ - DAV-309
98
+ - EUR643804
99
+ - Hauppauge_MVP
100
+ - universum-0000
101
+ - JVC_RM-RK60
102
+ - DAT
103
+ - RMT2
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LIRC
4
+ module Commands
5
+ def self.all_commands
6
+ constants.keep_if do |x|
7
+ const_get(x).instance_of?(Class)
8
+ end.map(&public_method(:serialize_command_name))
9
+ end
10
+
11
+ def self.serialize_command_name(klass)
12
+ klass = klass.to_s.split(":").fetch(-1)
13
+ rest = klass[1..-1].gsub(/[A-Z]/) do |chr|
14
+ "_#{chr}"
15
+ end
16
+ "#{klass[0]}#{rest.upcase}"
17
+ end
18
+
19
+ module Base
20
+ def serialize
21
+ return serialize_type unless respond_to?(:members)
22
+
23
+ "#{serialize_type} #{serialize_args}"
24
+ end
25
+
26
+ private
27
+
28
+ def serialize_type
29
+ Commands.serialize_command_name(self.class)
30
+ end
31
+
32
+ def serialize_args
33
+ members.map(&public_method(:send)).compact.join(" ")
34
+ end
35
+ end
36
+
37
+ SendOnce = Struct.new(:remote, :button, :repeats) { include Base }
38
+ SendStart = Struct.new(:remote, :button) { include Base }
39
+ SendStop = Struct.new(:remote, :button) { include Base }
40
+ List = Struct.new(:remote) { include Base }
41
+ SetInputlog = Struct.new(:path) { include Base }
42
+ DrvOption = Struct.new(:key, :value) { include Base }
43
+ Simulate = Struct.new(:key, :data) { include Base }
44
+ SetTransmitters = Struct.new(:transmitter, :mask) { include Base }
45
+ Version = Class.new { include Base }
46
+ end
47
+ end
@@ -0,0 +1,130 @@
1
+ require "lirc/messages"
2
+ require "lirc/commands"
3
+
4
+ module LIRC
5
+ module Messages
6
+ class ResponseParser
7
+ STATES = %i[waiting_begin
8
+ waiting_command
9
+ waiting_success
10
+ waiting_data
11
+ waiting_data_length
12
+ reading_data
13
+ valid].freeze
14
+
15
+ PARSER_METHOD_FOR = {
16
+ waiting_begin: :parse_begin,
17
+ waiting_command: :parse_command,
18
+ waiting_success: :parse_success,
19
+ waiting_data: :parse_data,
20
+ waiting_data_length: :parse_data_length,
21
+ reading_data: :read_data,
22
+ waiting_end: :parse_end,
23
+ valid: :raise_already_valid,
24
+ }.freeze
25
+
26
+ attr_reader :message
27
+
28
+ def initialize(state = :waiting_begin)
29
+ @state = state
30
+ @message = Response.new
31
+ end
32
+
33
+ # returns true when #message is ready
34
+ def valid?
35
+ @state.equal?(:valid)
36
+ end
37
+
38
+ def parse_line(line)
39
+ line = line.chomp
40
+
41
+ __send__(PARSER_METHOD_FOR.fetch(@state), line)
42
+ end
43
+
44
+ private
45
+
46
+ def parse_begin(line)
47
+ unless line.eql?("BEGIN")
48
+ raise ParseError, "unexpected line, expecting BEGIN, got #{line}"
49
+ end
50
+
51
+ @state = :waiting_command
52
+ end
53
+
54
+ def parse_command(line)
55
+ if Commands.all_commands.include?(line.split.first)
56
+ message.command = line
57
+ @state = :waiting_success
58
+ elsif line.eql?("SIGHUP")
59
+ message.command = line
60
+ @state = :waiting_end
61
+ else
62
+ raise ParseError,
63
+ "invalid command #{line}, expecting first word to be one of " \
64
+ "LIRC::Commands.all_commands, or SIGHUP"
65
+ end
66
+ end
67
+
68
+ def parse_success(line)
69
+ unless %w[SUCCESS ERROR].include?(line)
70
+ raise ParseError, "Expecting SUCCESS or ERROR, got #{line}"
71
+ end
72
+
73
+ message.success = line.eql?("SUCCESS")
74
+ @state = :waiting_data
75
+ end
76
+
77
+ def parse_data(line)
78
+ case line
79
+ when "DATA"
80
+ @state = :waiting_data_length
81
+ when "END"
82
+ @state = :valid
83
+ else
84
+ raise ParseError, "Expecting DATA or END, got #{line}"
85
+ end
86
+ end
87
+
88
+ def parse_data_length(line)
89
+ if line =~ /[^0-9]/
90
+ raise ParseError, "Expecting a number, got #{line}"
91
+ end
92
+
93
+ @data_lines_to_read = Integer(line)
94
+ message.data = []
95
+ @state = :reading_data
96
+ end
97
+
98
+ def parse_end(line)
99
+ unless line.eql?("END")
100
+ raise ParseError, "Expecting END, got #{line}"
101
+ end
102
+
103
+ @state = :valid
104
+ end
105
+
106
+ def read_data(line)
107
+ if @data_lines_to_read.zero?
108
+ unless line.eql?("END")
109
+ raise ParseError, "Expecting END, got more data: '#{line}'"
110
+ end
111
+
112
+ message.data = message.data&.join("\n").freeze
113
+ @state = :valid
114
+ return
115
+ end
116
+
117
+ message.data ||= []
118
+
119
+ @data_lines_to_read -= 1
120
+ message.data << line
121
+ end
122
+
123
+ def raise_already_valid(line)
124
+ raise ParseError,
125
+ "Response was successfully parsed, " \
126
+ "but #parse was called again with #{line}"
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,43 @@
1
+ module LIRC
2
+ # LIRC has three kinds of messages.
3
+ #
4
+ # ButtonPresses are sent by LIRCD to a LIRC client - these notify the client
5
+ # that LIRCD has received an IR button press from some remote.
6
+ #
7
+ # Commands are sent by a LIRC client to LIRCD to get it to do something (e.g.
8
+ # transmit an IR button press, or send back a Response containing a list of
9
+ # remotes it supports)
10
+ #
11
+ # Responses are sent by LIRCD to a LIRC client - usually in response to a
12
+ # Command (hence the name), but there is a special type - SIGHUP - which is
13
+ # sent whenever the LIRCD process receives a SIGHUP
14
+ #
15
+ # To make life easier (if not the conceptual model of this library) - the
16
+ # Messages module deals with ButtonPresses and Responses (things received from
17
+ # LIRCD), but Commands live in their own LIRC::Commands module
18
+ module Messages
19
+ class ParseError < StandardError; end
20
+
21
+ # Responses are received over the socket in response to Commands
22
+ Response = Struct.new(:command, :success, :data)
23
+
24
+ # code is the hex code sent by the remote
25
+ # button is the name of the button (if found in lircd.conf)
26
+ # remote is the name of the remote (if found)
27
+ ButtonPress = Struct.new(:code, :repeat_count, :button, :remote) do
28
+ def self.parse(line)
29
+ bits = line.split(" ")
30
+ if bits[0] =~ /[^0-9a-fA-F]/ || bits[1] =~ /[^0-9]/
31
+ raise ParseError, "invalid button press message '#{line}'"
32
+ end
33
+
34
+ # convert hex chars to an integer
35
+ bits[0] = bits[0].to_i(16)
36
+ bits[1] = bits[1].to_i
37
+ new(*bits)
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ require "lirc/messages/response_parser"
@@ -0,0 +1,74 @@
1
+ require "lirc/messages/response_parser"
2
+ require "logger"
3
+ require "eventmachine"
4
+
5
+ module LIRC
6
+ DEFAULT_PORT = 8765
7
+ # EventMachine Protocol for LIRC.
8
+ #
9
+ # Internally relies on Messages for parsing.
10
+ # Can send Commands to LIRC with send_command.
11
+ module Protocol
12
+ include EventMachine::Protocols::LineProtocol
13
+
14
+ def self.connect!(server:, port: DEFAULT_PORT, &block)
15
+ EventMachine.connect(server, port, self, &block)
16
+ end
17
+
18
+ def initialize(*args, logger: Logger.new(STDERR), **kwargs)
19
+ @logger = logger
20
+
21
+ super(*args, **kwargs)
22
+ end
23
+
24
+ def send_command(command)
25
+ send_data "#{command.serialize}\n"
26
+ response_deferrables[command.serialize] ||= EM::DefaultDeferrable.new
27
+ end
28
+
29
+ def receive_line(line)
30
+ line = line.chomp
31
+ if @response_parser
32
+ parse_message_line(line)
33
+ elsif line.eql?("BEGIN")
34
+ parse_message_line(line)
35
+ elsif line =~ /^[0-9a-f]/
36
+ receive_message(Messages::ButtonPress.parse(line))
37
+ else
38
+ logger.warn "Received unknown line from lirc: #{line}"
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def parse_message_line(line)
45
+ @response_parser ||= Messages::ResponseParser.new
46
+ @response_parser.parse_line(line)
47
+ if @response_parser.valid?
48
+ msg = @response_parser.message
49
+ resolve_response(msg)
50
+ receive_message(msg) if respond_to?(:receive_message)
51
+ @response_parser = nil
52
+ end
53
+ end
54
+
55
+ # resolve here means like Promises - Deferrables are pretty much promises
56
+ def resolve_response(response)
57
+ deferrable = response_deferrables[response.command]
58
+ return if deferrable.nil?
59
+
60
+ if response.success
61
+ deferrable.succeed(response)
62
+ else
63
+ deferrable.fail(response)
64
+ end
65
+ response_deferrables.delete(response.command)
66
+ end
67
+
68
+ def response_deferrables
69
+ @response_deferrables ||= {}
70
+ end
71
+
72
+ attr_reader :logger
73
+ end
74
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LIRC
4
+ VERSION = "0.3.0"
5
+ end
data/lib/lirc.rb ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lirc/version"
4
+ require "lirc/protocol"
5
+ require "lirc/commands"
6
+
7
+ module LIRC
8
+ # Your code goes here...
9
+ end
data/lirc.gemspec ADDED
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/lirc/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "lirc"
7
+ spec.version = LIRC::VERSION
8
+ spec.authors = ["Telyn Z."]
9
+ spec.email = ["175827+telyn@users.noreply.github.com"]
10
+
11
+ spec.summary = "lirc client library (focused on sending ir signals"
12
+ spec.homepage = "https://github.com/telyn/ruby-lirc"
13
+ spec.license = "MIT"
14
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
15
+
16
+ spec.metadata["homepage_uri"] = spec.homepage
17
+ spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/master/CONTRIBUTING.md"
18
+ spec.metadata["bug_tracker_uri"] = "#{spec.homepage}/issues"
19
+ spec.metadata["source_code_uri"] = "https://github.com/telyn/ruby-lirc"
20
+
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
24
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
+ end
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_dependency "eventmachine", "~> 1.2"
31
+
32
+ spec.add_development_dependency "faker", "~> 2.14"
33
+ spec.add_development_dependency "fuubar", "~> 2.5"
34
+ spec.add_development_dependency "guard-rspec", "~> 4.7"
35
+ spec.add_development_dependency "mutant-rspec", "~> 0.10.21"
36
+ spec.add_development_dependency "rake", "~> 12.0"
37
+ spec.add_development_dependency "rspec", "~> 3.0"
38
+ spec.add_development_dependency "rubocop", "~> 1.2"
39
+ end
metadata ADDED
@@ -0,0 +1,188 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lirc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Telyn Z.
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-01-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: eventmachine
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faker
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.14'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.14'
41
+ - !ruby/object:Gem::Dependency
42
+ name: fuubar
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: guard-rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '4.7'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '4.7'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mutant-rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.10.21
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.10.21
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '12.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '12.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '3.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.2'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.2'
125
+ description:
126
+ email:
127
+ - 175827+telyn@users.noreply.github.com
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - ".github/workflows/release.yml"
133
+ - ".github/workflows/test.yml"
134
+ - ".gitignore"
135
+ - ".mutant.yml"
136
+ - ".rspec"
137
+ - ".rubocop.yml"
138
+ - ".travis.yml"
139
+ - CHANGELOG.md
140
+ - CONTRIBUTING.md
141
+ - Gemfile
142
+ - Gemfile.lock
143
+ - Guardfile
144
+ - LICENSE.txt
145
+ - README.md
146
+ - bin/console
147
+ - bin/extract-changelog
148
+ - bin/irsend
149
+ - bin/release-check
150
+ - bin/setup
151
+ - lib/faker/lirc.rb
152
+ - lib/faker/lirc.yml
153
+ - lib/lirc.rb
154
+ - lib/lirc/commands.rb
155
+ - lib/lirc/messages.rb
156
+ - lib/lirc/messages/response_parser.rb
157
+ - lib/lirc/protocol.rb
158
+ - lib/lirc/version.rb
159
+ - lirc.gemspec
160
+ homepage: https://github.com/telyn/ruby-lirc
161
+ licenses:
162
+ - MIT
163
+ metadata:
164
+ homepage_uri: https://github.com/telyn/ruby-lirc
165
+ changelog_uri: https://github.com/telyn/ruby-lirc/blob/master/CONTRIBUTING.md
166
+ bug_tracker_uri: https://github.com/telyn/ruby-lirc/issues
167
+ source_code_uri: https://github.com/telyn/ruby-lirc
168
+ post_install_message:
169
+ rdoc_options: []
170
+ require_paths:
171
+ - lib
172
+ required_ruby_version: !ruby/object:Gem::Requirement
173
+ requirements:
174
+ - - ">="
175
+ - !ruby/object:Gem::Version
176
+ version: 2.5.0
177
+ required_rubygems_version: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ requirements: []
183
+ rubyforge_project:
184
+ rubygems_version: 2.7.6.2
185
+ signing_key:
186
+ specification_version: 4
187
+ summary: lirc client library (focused on sending ir signals
188
+ test_files: []