sesame_os2 0.1.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: 1f0b5a4520bdeff026e38159f0fffa40e1e42a850b6916550a918039a795881f
4
+ data.tar.gz: 46ffb7e94ab10675aa007675a2771ea327eb766e730fdb12b400bcffa4b1c09c
5
+ SHA512:
6
+ metadata.gz: 12182699f5c1ef7801a5a3c7b1680804fa153b3f58d920c8f66c174bca54ec2ed5334a33a12ce5691eb42b6678a0088f90818d67ec403bdbb105291739d47a55
7
+ data.tar.gz: 5280dd825cbd6cdf60657e8474523045d475c4c5970edf4c44809cf28796a11d05891605f0b77bdedd41358b68c691d398dce39bccf97bdf51c6b4cb90e2eee3
@@ -0,0 +1,16 @@
1
+ name: Ruby
2
+
3
+ on: [push,pull_request]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: ubuntu-latest
8
+ steps:
9
+ - uses: actions/checkout@v2
10
+ - name: Set up Ruby
11
+ uses: ruby/setup-ruby@v1
12
+ with:
13
+ ruby-version: 3.0.2
14
+ bundler-cache: true
15
+ - name: Run the default task
16
+ run: bundle exec rake
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
+ .env
10
+ Dockerfile
11
+ docker-compose.yml
12
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in sesame_os2.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+
10
+ gem "test-unit", "~> 3.0"
data/README.md ADDED
@@ -0,0 +1,123 @@
1
+ # SesameOs2
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/sesame_os2`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ This gem is wrapper for using with sesame web api with ruby(sesame3, sesame4).
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'sesame_os2'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle install
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install sesame_os2
22
+
23
+ ## Usage
24
+
25
+ - Set environment variables
26
+ - SESAME_API_KEY
27
+ - SESAME_SSM
28
+
29
+ ```ruby
30
+ client = SesameOs2::Client.new(name: 'webapi')
31
+ ```
32
+
33
+ It can also be set with arguments.
34
+
35
+ ```ruby
36
+ sesame_api_key = 'your api key'
37
+ sesame_ssm = 'youse sesame ssm'
38
+
39
+ client =
40
+ SesameOs2::Client.new(
41
+ name: 'webapi',
42
+ api_key: sesame_api_key,
43
+ ssm: sesame_ssm
44
+ )
45
+ ```
46
+
47
+ ### status
48
+
49
+ ```ruby
50
+ client.status
51
+ =>
52
+ {"batteryPercentage"=>100,
53
+ "batteryVoltage"=>6.095014662756598,
54
+ "position"=>223,
55
+ "CHSesame2Status"=>"unlocked",
56
+ "timestamp"=>1640393667,
57
+ "wm2State"=>true}
58
+ ```
59
+
60
+
61
+ ### histories
62
+
63
+ ```ruby
64
+ client.histories
65
+ =>
66
+ [{"recordID"=>312,
67
+ "type"=>11,
68
+ "timeStamp"=>1640393671108,
69
+ "cast_type"=>:driveUnlocked},
70
+ {"recordID"=>311,
71
+ "type"=>17,
72
+ "timeStamp"=>1640393668401,
73
+ "historyTag"=>"d2ViYXBp",
74
+ "cast_type"=>nil,
75
+ "name"=>"webapi"}
76
+ ]
77
+ ```
78
+
79
+ You can also pass page or lg arguments.
80
+
81
+ ```ruby
82
+ client.histories(page: 2, lg: 10)
83
+ =>
84
+ [{"recordID"=>318,
85
+ "type"=>11,
86
+ "timeStamp"=>1640394507582,
87
+ "cast_type"=>:driveUnlocked}]
88
+ ```
89
+
90
+ ### unlock
91
+
92
+ ```ruby
93
+ client.unlock
94
+ => {:status=>200}
95
+ ```
96
+
97
+ ### lock
98
+
99
+ ```ruby
100
+ client.lock
101
+ => {:status=>200}
102
+ ```
103
+
104
+ ### toggle
105
+
106
+ ```ruby
107
+ client.toggle
108
+ => {:status=>200}
109
+ ```
110
+
111
+ ## Development
112
+
113
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test-unit` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
114
+
115
+ 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 the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
116
+
117
+ ## Contributing
118
+
119
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ihatov08/sesame_os2.
120
+
121
+ ## License
122
+
123
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/testtask"
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << "test"
8
+ t.libs << "lib"
9
+ t.test_files = FileList["test/**/*_test.rb"]
10
+ end
11
+
12
+ task default: :test
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 "sesame_os2"
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__)
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
@@ -0,0 +1,95 @@
1
+ require 'faraday'
2
+ require 'base64'
3
+ require 'digest/cmac'
4
+ require 'json'
5
+
6
+ module SesameOs2
7
+ class Client
8
+ API_ENDPOINT = 'https://app.candyhouse.co/api/sesame2'
9
+
10
+ HISTORY_TYPES = {
11
+ 0 => :none,
12
+ 1 => :bleLock,
13
+ 2 => :bleUnLock,
14
+ 3 => :timeChanged,
15
+ 4 => :autoLockUpdated,
16
+ 5 => :mechSettingUpdated,
17
+ 6 => :autoLock,
18
+ 7 => :manualLocked,
19
+ 8 => :manualUnlocked,
20
+ 9 => :manualElse,
21
+ 10 => :driveLocked,
22
+ 11 => :driveUnlocked,
23
+ 12 => :driveFailed,
24
+ 13 => :bleAdvParameterUpdated,
25
+ }
26
+
27
+ COMMAND = {
28
+ toggle: 88,
29
+ lock: 82,
30
+ unlock: 83
31
+ }.freeze
32
+
33
+ def initialize(api_key: ENV['SESAME_API_KEY'], name:, ssm: ENV['SESAME_SSM'])
34
+ @api_key = api_key
35
+ @name = name
36
+ @ssm = Ssm.new(ssm: ssm)
37
+ end
38
+
39
+ def status
40
+ res = client.get(uuid)
41
+ JSON.parse(res.body)
42
+ end
43
+
44
+ def histories(page: 0, lg: 50)
45
+ res = client.get("#{uuid}/history", { page: page, lg: lg })
46
+ parsed_body = JSON.parse(res.body)
47
+
48
+ return parsed_body if res.status != 200
49
+
50
+ parsed_body.map do |body|
51
+ body['cast_type'] = HISTORY_TYPES[body['type']]
52
+ body['name'] = Base64.decode64(body['historyTag']) if body['historyTag']
53
+ body
54
+ end
55
+ end
56
+
57
+ def command(command:)
58
+ res = client.post("#{uuid}/cmd") do |req|
59
+ req.body = { cmd: command, history: encoded64_name, sign: sign }.to_json
60
+ end
61
+
62
+ { status: res.status }
63
+ end
64
+
65
+ COMMAND.each do |command, value|
66
+ define_method(command) do
67
+ command(command: value)
68
+ end
69
+ end
70
+
71
+ private
72
+
73
+ attr_reader :api_key, :name, :ssm
74
+
75
+ def client
76
+ @client = ::Faraday.new(url: API_ENDPOINT, headers: { 'x-api-key' => api_key })
77
+ end
78
+
79
+ def uuid
80
+ ssm.uuid
81
+ end
82
+
83
+ def secret_key
84
+ ssm.secret_key
85
+ end
86
+
87
+ def encoded64_name
88
+ Base64.encode64(name)
89
+ end
90
+
91
+ def sign
92
+ Sign.create(secret_key: secret_key)
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,39 @@
1
+ module SesameOs2
2
+ class Sign
3
+ def initialize(secret_key:)
4
+ @secret_key = secret_key
5
+ end
6
+
7
+ class << self
8
+ def create(secret_key:)
9
+ new(secret_key: secret_key).create
10
+ end
11
+ end
12
+
13
+ def create
14
+ digest.unpack1("H*")
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :secret_key
20
+
21
+ def message
22
+ [Time.now.to_i].pack("i*").unpack1("H*")[2, 8]
23
+ end
24
+
25
+ def key
26
+ [secret_key].pack("H*")
27
+ end
28
+
29
+ def cmac
30
+ Digest::CMAC.new(OpenSSL::Cipher.new("aes-128-cbc"), key).tap do |c|
31
+ c.update([message].pack("H*"))
32
+ end
33
+ end
34
+
35
+ def digest
36
+ cmac.digest
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,59 @@
1
+ require 'base64'
2
+
3
+ module SesameOs2
4
+ class Ssm
5
+ def initialize(ssm:)
6
+ @ssm = ssm
7
+ end
8
+
9
+ def name
10
+ information['n']
11
+ end
12
+
13
+ def uuid
14
+ unpacked = unpacked_sk[83..99].pack("C*").unpack("H*").first.upcase
15
+
16
+ parts = [
17
+ unpacked[0..7],
18
+ unpacked[8..11],
19
+ unpacked[12..15],
20
+ unpacked[16..19],
21
+ unpacked[20..-1]
22
+ ]
23
+
24
+ parts.join('-')
25
+ end
26
+
27
+ def key_index
28
+ unpacked_sk[81..82].pack("C*").unpack("H*").first
29
+ end
30
+
31
+ def secret_key
32
+ unpacked_sk[1..16].pack("C*").unpack("H*").first
33
+ end
34
+
35
+ def publick_key
36
+ unpacked_sk[17..80].pack("C*").unpack("H*").first
37
+ end
38
+
39
+ def information
40
+ URI::decode_www_form(parsed_ssm.query).to_h
41
+ end
42
+
43
+ private
44
+
45
+ attr_reader :ssm
46
+
47
+ def parsed_ssm
48
+ URI.parse(ssm)
49
+ end
50
+
51
+ def sk
52
+ information['sk']
53
+ end
54
+
55
+ def unpacked_sk
56
+ Base64.decode64(sk).unpack("C*")
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SesameOs2
4
+ VERSION = "0.1.0"
5
+ end
data/lib/sesame_os2.rb ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "sesame_os2/version"
4
+ require "sesame_os2/ssm"
5
+ require "sesame_os2/client"
6
+ require "sesame_os2/sign"
7
+
8
+ module SesameOs2
9
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path("lib", __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require "sesame_os2/version"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "sesame_os2"
9
+ spec.version = SesameOs2::VERSION
10
+ spec.authors = ["ihatov08"]
11
+ spec.email = ["ihatov08@gmail.com"]
12
+
13
+ spec.summary = "Ruby wrapper for CANDIHOUSE sesame os2 Web API"
14
+ spec.homepage = "https://github.com/ihatov08/sesame_os2"
15
+ spec.license = "MIT"
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = "https://github.com/ihatov08/sesame_os2"
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
23
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
24
+ end
25
+ spec.bindir = "exe"
26
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
27
+ spec.require_paths = ["lib"]
28
+
29
+ spec.add_dependency 'digest-cmac'
30
+ spec.add_dependency 'faraday'
31
+
32
+ # Uncomment to register a new dependency of your gem
33
+ # spec.add_dependency "example-gem", "~> 1.0"
34
+
35
+ # For more information and examples about making a new gem, checkout our
36
+ # guide at: https://bundler.io/guides/creating_gem.html
37
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sesame_os2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - ihatov08
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-12-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: digest-cmac
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description:
42
+ email:
43
+ - ihatov08@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".github/workflows/main.yml"
49
+ - ".gitignore"
50
+ - Gemfile
51
+ - README.md
52
+ - Rakefile
53
+ - bin/console
54
+ - bin/setup
55
+ - lib/sesame_os2.rb
56
+ - lib/sesame_os2/client.rb
57
+ - lib/sesame_os2/sign.rb
58
+ - lib/sesame_os2/ssm.rb
59
+ - lib/sesame_os2/version.rb
60
+ - sesame_os2.gemspec
61
+ homepage: https://github.com/ihatov08/sesame_os2
62
+ licenses:
63
+ - MIT
64
+ metadata:
65
+ homepage_uri: https://github.com/ihatov08/sesame_os2
66
+ source_code_uri: https://github.com/ihatov08/sesame_os2
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubygems_version: 3.1.2
83
+ signing_key:
84
+ specification_version: 4
85
+ summary: Ruby wrapper for CANDIHOUSE sesame os2 Web API
86
+ test_files: []