mixergy 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 +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +77 -0
- data/Rakefile +13 -0
- data/doc/screenshot.png +0 -0
- data/exe/mixergy +117 -0
- data/lib/mixergy/ascii_art.rb +29 -0
- data/lib/mixergy/client.rb +96 -0
- data/lib/mixergy/config.rb +58 -0
- data/lib/mixergy/error.rb +9 -0
- data/lib/mixergy/status.rb +32 -0
- data/lib/mixergy/tank.rb +34 -0
- data/lib/mixergy/version.rb +8 -0
- data/lib/mixergy.rb +6 -0
- data/sig/mixergy.rbs +4 -0
- metadata +104 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: ba0e27e53239f2c48a1a6ea61fa42e6a4e2b2ecf5d030d588e35d58e47497ac2
|
|
4
|
+
data.tar.gz: 855226c79aa3e988c883fcbb2fb629e70acbeea7846f4a1b09198c752562911d
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: fdc10ec896960d3e8afda031b8810504807b1c6bad3c74af12b8ee0f21379ac8d3e541d3b0e40ec4b2837eb2753f4f0b1c45d853032ba5901a13fdc4cb93a153
|
|
7
|
+
data.tar.gz: b6d8f53dcdcc806d378c6e9ad1d0dcd4fa9943069e2808d2d2c61924aea11f29311d72b4cca97ee25a52a1c230aee555fda681f39ad58d70d3c6d144ce650da6
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Nicholas Humfrey
|
|
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,77 @@
|
|
|
1
|
+
|
|
2
|
+
# Mixergy Ruby Client
|
|
3
|
+
|
|
4
|
+
This gem provides a Ruby interface to the Mixergy Hot Water Tank REST API, making it easy to interact with tanks in a Rubyish way. There is also a CLI tool included to help with fetching an authentication token and interacting with the API.
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
Add this line to your application's Gemfile:
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
gem 'mixergy', git: 'https://github.com/njh/ruby-mixergy.git'
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Or install it directly:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
git clone https://github.com/njh/ruby-mixergy.git
|
|
19
|
+
cd ruby-mixergy
|
|
20
|
+
bundle install
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## Command Line Interface
|
|
25
|
+
|
|
26
|
+
Included in the gem is a command line tool, to perform actions with the Mixergy API:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
$ mixergy help
|
|
30
|
+
Commands:
|
|
31
|
+
mixergy boost # Charge tank to 100%
|
|
32
|
+
mixergy charge PERCENT # Charge tank to target percentage
|
|
33
|
+
mixergy help [COMMAND] # Describe available commands or one specific command
|
|
34
|
+
mixergy login # Login to Mixergy API and store token
|
|
35
|
+
mixergy status # Display the current status of a tank
|
|
36
|
+
mixergy tanks # List all your tanks
|
|
37
|
+
mixergy version # Prints the Mixergy gem version
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The `mixergy status` command displays some stats and a visualisation of the tank:
|
|
41
|
+
|
|
42
|
+
<img src="doc/screenshot.png" height="400" alt="A screenshot of a Mac OS terminal running `mixergy status`" />
|
|
43
|
+
|
|
44
|
+
To disable colour, set the `NO_COLOR` environment variable.
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
## Config file format
|
|
48
|
+
|
|
49
|
+
To avoid logging-in before each API request, there is support for saving the authentication token to a configuration file, stored as YAML in `~/.mixergy`.
|
|
50
|
+
|
|
51
|
+
This file can be generated using the `mixergy login` CLI command.
|
|
52
|
+
The default tank ID is also stored, to avoid having to lookup a list of tanks each time too.
|
|
53
|
+
|
|
54
|
+
Example `~/.mixergy` file:
|
|
55
|
+
|
|
56
|
+
```yaml
|
|
57
|
+
---
|
|
58
|
+
token: user/ooShoh7naaR1lai0Ahtie5miechaig7ei/12ab/Tie6sha0vah7onohchifeich2aipheifaiqu9beiphoim4queitheinoMoo2a
|
|
59
|
+
default_tank_id: fcee127d-dad9-4ab4-a734-64586d0c0d68
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
## Development
|
|
64
|
+
|
|
65
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
66
|
+
|
|
67
|
+
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).
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
## Contributing
|
|
71
|
+
|
|
72
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/njh/ruby-mixergy.
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
## License
|
|
76
|
+
|
|
77
|
+
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,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler/gem_tasks"
|
|
4
|
+
require "standard/rake"
|
|
5
|
+
require "yard"
|
|
6
|
+
|
|
7
|
+
# YARD documentation task
|
|
8
|
+
YARD::Rake::YardocTask.new(:yard) do |t|
|
|
9
|
+
t.files = ["lib/**/*.rb"]
|
|
10
|
+
t.options = ["--output-dir", "doc"]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
task default: :standard
|
data/doc/screenshot.png
ADDED
|
Binary file
|
data/exe/mixergy
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
|
|
5
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
|
|
6
|
+
|
|
7
|
+
require "thor"
|
|
8
|
+
require "mixergy"
|
|
9
|
+
require "mixergy/ascii_art"
|
|
10
|
+
require "io/console"
|
|
11
|
+
|
|
12
|
+
module Mixergy
|
|
13
|
+
class CLI < Thor
|
|
14
|
+
# Exit with a non-zero status code on failure
|
|
15
|
+
def self.exit_on_failure?
|
|
16
|
+
true
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
desc "version", "Prints the Mixergy gem version"
|
|
20
|
+
def version
|
|
21
|
+
puts Mixergy::VERSION
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
desc "login", "Login to Mixergy API and store token"
|
|
25
|
+
option :username, aliases: "-u", desc: "Username"
|
|
26
|
+
option :password, aliases: "-p", desc: "Password"
|
|
27
|
+
def login
|
|
28
|
+
username = options[:username] || prompt_for_username
|
|
29
|
+
password = options[:password] || prompt_for_password
|
|
30
|
+
client = Mixergy::Client.new
|
|
31
|
+
token = client.login(username, password)
|
|
32
|
+
if token
|
|
33
|
+
puts "Login successful!"
|
|
34
|
+
config = Mixergy::Config.new
|
|
35
|
+
puts "Writing token to #{config.filepath}"
|
|
36
|
+
config.load
|
|
37
|
+
config[:token] = token
|
|
38
|
+
if !config[:default_tank_id]
|
|
39
|
+
tank_id = client.tanks.first&.id
|
|
40
|
+
if tank_id
|
|
41
|
+
puts "Setting default tank ID to #{tank_id}"
|
|
42
|
+
config[:default_tank_id] = tank_id
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
config.save
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
desc "tanks", "List all your tanks"
|
|
50
|
+
def tanks
|
|
51
|
+
client = Mixergy::Client.new
|
|
52
|
+
client.load_config
|
|
53
|
+
tanks = client.tanks
|
|
54
|
+
if tanks.empty?
|
|
55
|
+
puts "No tanks found."
|
|
56
|
+
else
|
|
57
|
+
tanks.each do |tank|
|
|
58
|
+
puts "Serial: #{tank.serial_number}"
|
|
59
|
+
puts "Id: #{tank.id}"
|
|
60
|
+
puts
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
desc "status", "Display the current status of a tank"
|
|
66
|
+
def status
|
|
67
|
+
client = Mixergy::Client.new
|
|
68
|
+
client.load_config
|
|
69
|
+
# FIXME: add support for chosing a specific tank
|
|
70
|
+
status = client.status
|
|
71
|
+
puts "Charge: #{status.charge} %"
|
|
72
|
+
puts "Top Temperature: #{status.top_temperature} °C"
|
|
73
|
+
puts "Bottom Temperature: #{status.bottom_temperature} °C"
|
|
74
|
+
puts
|
|
75
|
+
puts Mixergy::AsciiArt.draw_tank(status.charge)
|
|
76
|
+
puts
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
desc "charge PERCENT", "Charge tank to target percentage"
|
|
80
|
+
def charge(percent)
|
|
81
|
+
percent = percent.to_i
|
|
82
|
+
unless percent.is_a?(Integer) && percent >= 0 && percent <= 100
|
|
83
|
+
raise ArgumentError, "percent must be an integer between 0 and 100."
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
client = Mixergy::Client.new
|
|
87
|
+
client.load_config
|
|
88
|
+
current_charge = client.status.charge
|
|
89
|
+
if client.set_charge(percent)
|
|
90
|
+
puts "Tank charging from #{current_charge} to #{percent}..."
|
|
91
|
+
else
|
|
92
|
+
puts "Failed to charge tank."
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
desc "boost", "Charge tank to 100%"
|
|
97
|
+
def boost
|
|
98
|
+
charge(100)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
private
|
|
102
|
+
|
|
103
|
+
def prompt_for_username
|
|
104
|
+
print "Username: "
|
|
105
|
+
$stdin.gets.chomp
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def prompt_for_password
|
|
109
|
+
print "Password: "
|
|
110
|
+
password = $stdin.noecho(&:gets)
|
|
111
|
+
puts
|
|
112
|
+
password.chomp
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
Mixergy::CLI.start
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "pastel"
|
|
4
|
+
|
|
5
|
+
module Mixergy
|
|
6
|
+
module AsciiArt
|
|
7
|
+
# Draws an ASCII art hot water cylinder representing a charge level.
|
|
8
|
+
# @param charge [Numeric] The charge percentage (0-100).
|
|
9
|
+
# @param width [Integer] The width of the tank (default: 7).
|
|
10
|
+
# @param height [Integer] The height of the tank (default: 10).
|
|
11
|
+
# @return [String] The ASCII art representation of the tank.
|
|
12
|
+
def self.draw_tank(charge, width: 7, height: 10)
|
|
13
|
+
fill_height = (height * charge / 100.0).round
|
|
14
|
+
pastel = Pastel.new
|
|
15
|
+
|
|
16
|
+
tank = []
|
|
17
|
+
tank << " ╭#{"─" * width}╮"
|
|
18
|
+
height.times do |i|
|
|
19
|
+
tank << if i < height - fill_height
|
|
20
|
+
" │#{pastel.blue.on_blue(" ") * width}│"
|
|
21
|
+
else
|
|
22
|
+
" │#{pastel.red.on_red("█") * width}│"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
tank << " ╰#{"─" * width}╯"
|
|
26
|
+
tank.join("\n")
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "faraday"
|
|
4
|
+
require "json"
|
|
5
|
+
require_relative "config"
|
|
6
|
+
require_relative "error"
|
|
7
|
+
require_relative "tank"
|
|
8
|
+
require_relative "status"
|
|
9
|
+
|
|
10
|
+
module Mixergy
|
|
11
|
+
class Client
|
|
12
|
+
API_ROOT = "https://www.mixergy.io/api/v2"
|
|
13
|
+
|
|
14
|
+
# Create a new Mixergy API client.
|
|
15
|
+
def initialize
|
|
16
|
+
@connection = Faraday.new(
|
|
17
|
+
url: API_ROOT
|
|
18
|
+
) do |faraday|
|
|
19
|
+
faraday.request :json # Automatically encode request bodies as JSON
|
|
20
|
+
faraday.response :json # Automatically parse response bodies as JSON
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Loads configuration from ~/.mixergy and sets the API token if present.
|
|
25
|
+
# @return [Mixergy::Config] the loaded config object
|
|
26
|
+
def load_config
|
|
27
|
+
@config ||= begin
|
|
28
|
+
config = Mixergy::Config.new
|
|
29
|
+
config.load
|
|
30
|
+
# FIXME: find a better place to put this
|
|
31
|
+
@connection.headers["Authorization"] = "Bearer #{config[:token]}"
|
|
32
|
+
config
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Authenticates with the Mixergy API and stores the token in the connection.
|
|
37
|
+
# @param username [String] the username
|
|
38
|
+
# @param password [String] the password
|
|
39
|
+
# @return [String] the authentication token
|
|
40
|
+
# @raise [Mixergy::Error] if login fails
|
|
41
|
+
def login(username, password)
|
|
42
|
+
resp = @connection.post(
|
|
43
|
+
"account/login",
|
|
44
|
+
{username: username, password: password}
|
|
45
|
+
)
|
|
46
|
+
data = resp.body
|
|
47
|
+
|
|
48
|
+
if data["token"]
|
|
49
|
+
@connection.headers["Authorization"] = "Bearer #{data["token"]}"
|
|
50
|
+
data["token"]
|
|
51
|
+
else
|
|
52
|
+
raise Mixergy::Error, "Login failed (status: #{resp.status}, body: #{resp.body.inspect})"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Fetches all tanks associated with the account.
|
|
57
|
+
# @return [Array<Tank>] list of Tank objects
|
|
58
|
+
def tanks
|
|
59
|
+
resp = @connection.get("tanks")
|
|
60
|
+
tank_list = resp.body.dig("_embedded", "tankList") || []
|
|
61
|
+
tank_list.map do |tank_data|
|
|
62
|
+
Tank.new(tank_data)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Returns the default tank ID from config, or the first tank's ID.
|
|
67
|
+
# @return [String, nil] the default tank ID
|
|
68
|
+
def default_tank_id
|
|
69
|
+
@default_tank_id ||= begin
|
|
70
|
+
load_config
|
|
71
|
+
@config[:default_tank_id] || tanks.first&.id
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Fetches the latest status/measurement for a tank.
|
|
76
|
+
# @param tank [Tank, nil] the tank object (optional)
|
|
77
|
+
# @return [Status] the status object for the tank
|
|
78
|
+
def status(tank = nil)
|
|
79
|
+
tank_id = tank.id if tank.is_a?(Tank)
|
|
80
|
+
tank_id = default_tank_id if tank_id.nil?
|
|
81
|
+
resp = @connection.get("tanks/#{tank_id}/measurements/latest")
|
|
82
|
+
Status.new(resp.body)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Sets the target charge for a tank via the control endpoint.
|
|
86
|
+
# @param percent [Integer] the target charge percentage
|
|
87
|
+
# @param tank [Tank, String, nil] the Tank object or Tank GUID (optional)
|
|
88
|
+
# @return [Boolean] true if successful, false otherwise
|
|
89
|
+
def set_charge(percent, tank = nil)
|
|
90
|
+
tank_id = tank.id if tank.is_a?(Tank)
|
|
91
|
+
tank_id = default_tank_id if tank_id.nil?
|
|
92
|
+
resp = @connection.put("tanks/#{tank_id}/control", {charge: percent})
|
|
93
|
+
resp.success?
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "yaml"
|
|
4
|
+
require "fileutils"
|
|
5
|
+
|
|
6
|
+
# Mixergy::Config handles loading and saving user configuration as a YAML file.
|
|
7
|
+
# The default config file is ~/.mixergy.
|
|
8
|
+
module Mixergy
|
|
9
|
+
# Configuration handler for Mixergy CLI and API clients.
|
|
10
|
+
# Loads and saves config as YAML, provides hash-like access.
|
|
11
|
+
class Config
|
|
12
|
+
# Default path for the config file (~/.mixergy)
|
|
13
|
+
DEFAULT_CONFIG_PATH = File.expand_path("~/.mixergy")
|
|
14
|
+
|
|
15
|
+
# @return [String] Path to the config file
|
|
16
|
+
attr_reader :filepath
|
|
17
|
+
# @return [Hash] The loaded config data
|
|
18
|
+
attr_reader :data
|
|
19
|
+
|
|
20
|
+
# Create a new Config object and load config from disk.
|
|
21
|
+
# @param config_path [String] Optional path to config file
|
|
22
|
+
def initialize(config_path = DEFAULT_CONFIG_PATH)
|
|
23
|
+
@filepath = config_path
|
|
24
|
+
@data = load
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Load config from disk.
|
|
28
|
+
# @return [Hash] The loaded config data
|
|
29
|
+
def load
|
|
30
|
+
if File.exist?(@filepath)
|
|
31
|
+
YAML.load_file(@filepath) || {}
|
|
32
|
+
else
|
|
33
|
+
{}
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Save current config data to disk.
|
|
38
|
+
# @return [void]
|
|
39
|
+
def save
|
|
40
|
+
File.write(@filepath, YAML.dump(@data))
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Get a config value by key.
|
|
44
|
+
# @param key [String, Symbol]
|
|
45
|
+
# @return [Object, nil] Value for the key
|
|
46
|
+
def [](key)
|
|
47
|
+
@data[key.to_s]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Set a config value by key.
|
|
51
|
+
# @param key [String, Symbol]
|
|
52
|
+
# @param value [Object]
|
|
53
|
+
# @return [void]
|
|
54
|
+
def []=(key, value)
|
|
55
|
+
@data[key.to_s] = value
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Mixergy::Error is the base exception class for all Mixergy-related errors.
|
|
4
|
+
# Raise this for API, configuration, or client errors.
|
|
5
|
+
module Mixergy
|
|
6
|
+
# Base exception class for Mixergy errors.
|
|
7
|
+
# All custom errors should inherit from this.
|
|
8
|
+
class Error < StandardError; end
|
|
9
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Mixergy::Status represents the latest measurement/status of a tank.
|
|
4
|
+
# It provides access to charge, temperature, and other metrics.
|
|
5
|
+
module Mixergy
|
|
6
|
+
# Represents the latest status/measurement for a Mixergy tank.
|
|
7
|
+
class Status
|
|
8
|
+
# @return [Float] Current charge percentage
|
|
9
|
+
attr_reader :charge
|
|
10
|
+
# @return [Float] Top temperature in Celsius
|
|
11
|
+
attr_reader :top_temperature
|
|
12
|
+
# @return [Float] Bottom temperature in Celsius
|
|
13
|
+
attr_reader :bottom_temperature
|
|
14
|
+
# @return [Float] Frequency in Hz
|
|
15
|
+
attr_reader :frequency
|
|
16
|
+
# @return [Float] Voltage in Volts
|
|
17
|
+
attr_reader :voltage
|
|
18
|
+
# @return [Float] Current in Amps
|
|
19
|
+
attr_reader :current
|
|
20
|
+
|
|
21
|
+
# Create a new Status object from API data.
|
|
22
|
+
# @param data [Hash] API response data for latest measurement
|
|
23
|
+
def initialize(data = {})
|
|
24
|
+
@charge = data["charge"]
|
|
25
|
+
@top_temperature = data["topTemperature"]
|
|
26
|
+
@bottom_temperature = data["bottomTemperature"]
|
|
27
|
+
@frequency = data["frequency"]
|
|
28
|
+
@voltage = data["voltage"]
|
|
29
|
+
@current = data["current"]
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
data/lib/mixergy/tank.rb
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Mixergy::Tank represents a physical Mixergy tank and its metadata.
|
|
4
|
+
# Provides access to tank ID, type, model, volume, firmware version, and serial number.
|
|
5
|
+
module Mixergy
|
|
6
|
+
# Represents a Mixergy tank and its metadata.
|
|
7
|
+
class Tank
|
|
8
|
+
# @return [String] Unique tank ID
|
|
9
|
+
attr_reader :id
|
|
10
|
+
# @return [String] Tank type
|
|
11
|
+
attr_reader :type
|
|
12
|
+
# @return [String] Tank model code
|
|
13
|
+
attr_reader :model
|
|
14
|
+
# @return [Float] Tank volume in liters
|
|
15
|
+
attr_reader :volume
|
|
16
|
+
# @return [String] Firmware version
|
|
17
|
+
attr_reader :firmware_version
|
|
18
|
+
# @return [String] Serial number
|
|
19
|
+
attr_reader :serial_number
|
|
20
|
+
|
|
21
|
+
# Create a new Tank object from API data.
|
|
22
|
+
# @param data [Hash, nil] API response data for the tank
|
|
23
|
+
def initialize(data = nil)
|
|
24
|
+
if data
|
|
25
|
+
@id = data["id"]
|
|
26
|
+
@type = data["type"]
|
|
27
|
+
@model = data["tankModelCode"]
|
|
28
|
+
@volume = data["volume"]
|
|
29
|
+
@firmware_version = data["firmwareVersion"]
|
|
30
|
+
@serial_number = data["serialNumber"]
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
data/lib/mixergy.rb
ADDED
data/sig/mixergy.rbs
ADDED
metadata
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: mixergy
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Nicholas J. Humfrey
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2025-09-16 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: faraday
|
|
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: thor
|
|
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
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: pastel
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
description: This gem provides a simple interface for interacting with the Mixergy
|
|
56
|
+
API, allowing users to manage their hot water tanks programmatically.
|
|
57
|
+
email:
|
|
58
|
+
- njh@aelius.com
|
|
59
|
+
executables:
|
|
60
|
+
- mixergy
|
|
61
|
+
extensions: []
|
|
62
|
+
extra_rdoc_files: []
|
|
63
|
+
files:
|
|
64
|
+
- LICENSE.txt
|
|
65
|
+
- README.md
|
|
66
|
+
- Rakefile
|
|
67
|
+
- doc/screenshot.png
|
|
68
|
+
- exe/mixergy
|
|
69
|
+
- lib/mixergy.rb
|
|
70
|
+
- lib/mixergy/ascii_art.rb
|
|
71
|
+
- lib/mixergy/client.rb
|
|
72
|
+
- lib/mixergy/config.rb
|
|
73
|
+
- lib/mixergy/error.rb
|
|
74
|
+
- lib/mixergy/status.rb
|
|
75
|
+
- lib/mixergy/tank.rb
|
|
76
|
+
- lib/mixergy/version.rb
|
|
77
|
+
- sig/mixergy.rbs
|
|
78
|
+
homepage: https://github.com/njh/ruby-mixergy
|
|
79
|
+
licenses:
|
|
80
|
+
- MIT
|
|
81
|
+
metadata:
|
|
82
|
+
allowed_push_host: https://rubygems.org
|
|
83
|
+
homepage_uri: https://github.com/njh/ruby-mixergy
|
|
84
|
+
source_code_uri: https://github.com/njh/ruby-mixergy.git
|
|
85
|
+
post_install_message:
|
|
86
|
+
rdoc_options: []
|
|
87
|
+
require_paths:
|
|
88
|
+
- lib
|
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
90
|
+
requirements:
|
|
91
|
+
- - ">="
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: 3.2.0
|
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
|
+
requirements:
|
|
96
|
+
- - ">="
|
|
97
|
+
- !ruby/object:Gem::Version
|
|
98
|
+
version: '0'
|
|
99
|
+
requirements: []
|
|
100
|
+
rubygems_version: 3.5.3
|
|
101
|
+
signing_key:
|
|
102
|
+
specification_version: 4
|
|
103
|
+
summary: Ruby gem for controlling Mixergy hot water tanks
|
|
104
|
+
test_files: []
|