home_assistant-generator 0.1.0.pre.alpha.pre.20 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +0 -2
- data/Rakefile +3 -3
- data/example_config.rb +2 -149
- data/home_assistant-generator.gemspec +9 -10
- data/lib/home_assistant/generator/component.rb +16 -13
- data/lib/home_assistant/generator/dsl.rb +21 -76
- data/lib/home_assistant/generator/version.rb +1 -1
- metadata +5 -24
- data/.rubocop.yml +0 -20
- data/lib/home_assistant/generator/automation.rb +0 -54
- data/lib/home_assistant/generator/plural.rb +0 -52
- data/lib/home_assistant/generator/properties.rb +0 -54
- data/lib/home_assistant/generator/script.rb +0 -72
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5f610d28c745f225706900acf1767edb018b8e66
|
4
|
+
data.tar.gz: 9f1822ce7a64e18321e08c9ddad0fc7efb2a5e7d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e74b050eda292364af6a8c9fd53622f93272041be5b1696a643d5e0a0826a6a5c3bf816caeca91917b37f26c879681da1c5e1b32bf82ee8690b16ff3d8890466
|
7
|
+
data.tar.gz: b99f77560d217c568e9341e8148956143425fe6d8ab5783ba517894d5c57377a287e2960310e80f0259fd19e6b6b9d3d3efb1aabe12b5750c8a2048a30c9efda
|
data/README.md
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# HomeAssistant::Generator
|
2
2
|
|
3
|
-
https://www.home-assistant.io/ for more details
|
4
|
-
|
5
3
|
[![Build Status](https://travis-ci.org/kamaradclimber/home_assistant-generator.svg?branch=master)](https://travis-ci.org/kamaradclimber/home_assistant-generator)
|
6
4
|
[![Gem Version](https://badge.fury.io/rb/home_assistant-generator.svg)](https://badge.fury.io/rb/home_assistant-generator)
|
7
5
|
|
data/Rakefile
CHANGED
data/example_config.rb
CHANGED
@@ -1,157 +1,10 @@
|
|
1
|
-
homeassistant 'home' do
|
2
|
-
longitude 2.3267746000000216
|
3
|
-
latitude 48.8264967
|
4
|
-
elevation 66
|
5
|
-
unit_system 'metric'
|
6
|
-
time_zone 'Europe/Paris'
|
7
|
-
customize('switch.capodimonte_led': { icon: 'mdi:led-variant-on' })
|
8
|
-
end
|
9
|
-
|
10
1
|
media_player 'KoKodi' do
|
11
2
|
platform :kodi
|
12
3
|
host 'http://192.168.0.13'
|
13
4
|
port 8080
|
14
5
|
end
|
15
6
|
|
16
|
-
sun # Track sun position
|
17
|
-
discovery # Discover some devices automatically
|
18
|
-
frontend # Enable home-assistant front-end
|
19
|
-
conversation # Allow to issue voice commands from the frontend
|
20
|
-
zeroconf # Expose home-assistant over bonjour
|
21
|
-
|
22
|
-
recorder do
|
23
|
-
purge_days 14
|
24
|
-
end
|
25
|
-
|
26
|
-
logbook do
|
27
|
-
# sun moves too much, useless in the log
|
28
|
-
exclude(domains: %w(sun))
|
29
|
-
end
|
30
|
-
|
31
|
-
updater do
|
32
|
-
reporting 'no'
|
33
|
-
end
|
34
|
-
|
35
|
-
yr__sensor
|
36
|
-
# strictly equivalent to:
|
37
|
-
#sensor do
|
38
|
-
# platform :yr
|
39
|
-
#end
|
40
|
-
|
41
|
-
|
42
|
-
speedtest__sensor do
|
43
|
-
monitored_conditions %w(ping)
|
44
|
-
#hour [0, 6, 12, 18]
|
45
|
-
#minute 5
|
46
|
-
end
|
47
|
-
|
48
|
-
darksky__sensor do
|
49
|
-
api_key 'FAKE_KEY'
|
50
|
-
end
|
51
|
-
|
52
|
-
statistics__sensor 'Ping Stats' do
|
53
|
-
entity_id 'sensor.speedtest_ping'
|
54
|
-
end
|
55
|
-
|
56
|
-
waqi__sensor do
|
57
|
-
locations %w(paris)
|
58
|
-
stations ['place victor basch']
|
59
|
-
end
|
60
|
-
|
61
|
-
nmap_tracker__device_tracker do
|
62
|
-
hosts '192.168.0.0/24'
|
63
|
-
home_interval 10
|
64
|
-
interval_seconds 120
|
65
|
-
track_new_devices 'yes'
|
66
|
-
end
|
67
|
-
|
68
|
-
zone 'Criteo' do
|
69
|
-
longitude 2.331610
|
70
|
-
latitude 48.878887
|
71
|
-
icon 'mdi:desktop-tower'
|
72
|
-
end
|
73
|
-
|
74
|
-
limitless__light do
|
75
|
-
bridges([
|
76
|
-
{ host: '192.168.0.110', groups: [{ number: 1, type: 'rgbw', name: 'Table à manger' }] }
|
77
|
-
])
|
78
|
-
end
|
79
|
-
|
80
|
-
command_line__switch 'capodimonte_led' do
|
81
|
-
command_on 'sudo systemctl start raspberry_led'
|
82
|
-
command_off 'sudo systemctl stop raspberry_led'
|
83
|
-
command_state 'sudo systemctl is-active raspberry_led > /dev/null 2>&1'
|
84
|
-
end
|
85
|
-
|
86
|
-
command_line__switch 'nzbget_pause' do
|
87
|
-
command_on <<~EOH.split("\n").join(' && ')
|
88
|
-
curl -XPOST capodimonte/nzbget/jsonrpc -d '{"method": "pausepost"}'
|
89
|
-
curl -XPOST capodimonte/nzbget/jsonrpc -d '{"method": "pausedownload"}'
|
90
|
-
EOH
|
91
|
-
command_off %(curl -XPOST capodimonte/nzbget/jsonrpc -d '{"method": "scheduleresume", "params": [1]}')
|
92
|
-
command_state %(curl -s capodimonte/nzbget/jsonrpc -d '{"method": "status"}' |grep -q 'Paused" : true')
|
93
|
-
end
|
94
|
-
|
95
|
-
command_line__cover 'volets_salon' do
|
96
|
-
command_open %(curl -s http://192.168.0.20/up)
|
97
|
-
command_close %(curl -s http://192.168.0.20/down)
|
98
|
-
command_stop %(curl -s http://192.168.0.20/down) # can't do better for now
|
99
|
-
# since "volets" are disconnected very often, output of status pollutes the log TODO
|
100
|
-
# command_status %(curl -s http://192.168.0.20/status)
|
101
|
-
end
|
102
|
-
|
103
|
-
input_boolean do # TODO: improve this kind of declaration
|
104
|
-
light_control_by_kokodi(
|
105
|
-
name: 'Kokodi controle lumière du salon',
|
106
|
-
initial: 'on',
|
107
|
-
icon: 'mdi:toggle-switch'
|
108
|
-
)
|
109
|
-
end
|
110
|
-
|
111
|
-
shell_command do
|
112
|
-
classical_music_on_kodi '/var/lib/hass/play_random_classical_music_kodi.sh'
|
113
|
-
radio_swiss_classic '/var/lib/hass/play_radio_swiss_classic.sh'
|
114
|
-
end
|
115
|
-
|
116
|
-
script 'Restart HA' do
|
117
|
-
restart_homeassistant
|
118
|
-
end
|
119
|
-
|
120
|
-
#script 'Heal Zwave' do
|
121
|
-
# heal_network(:zwave)
|
122
|
-
# soft_reset(:zwave)
|
123
|
-
#end
|
124
7
|
#
|
125
|
-
#
|
126
|
-
#
|
127
|
-
# delay(5.seconds)
|
128
|
-
# turn_on_light('group.sdb_parents').with(brightness: 20)
|
129
|
-
# delay(5.seconds)
|
130
|
-
# turn_on_light('group.sdb_parents').with(brightness: 40)
|
8
|
+
#automation 'Activate movie playing scene' do
|
9
|
+
# trigger.when('KoKodi').state(to: 'playing')
|
131
10
|
#end
|
132
|
-
#
|
133
|
-
#script 'bedtime' do
|
134
|
-
# turn_on_light('table_a_manger').with(transition: 1, brightness: 10, color_name: 'white')
|
135
|
-
# turn_on_light('table_a_manger').with(transition: 10, brightness: 215, color_name: 'white')
|
136
|
-
# delay(10.seconds) # wait for previous pipeline to complete
|
137
|
-
# delay(60.seconds) # wait go to bed
|
138
|
-
# turn_off_light('table_a_manger').with(transition: 60)
|
139
|
-
#end
|
140
|
-
|
141
|
-
automation 'Activate movie playing scene' do
|
142
|
-
# trigger.when('KoKodi').from(:paused).to(:playing)
|
143
|
-
|
144
|
-
# Other examples
|
145
|
-
trigger.when('KoKodi').playing
|
146
|
-
# equivalent to:
|
147
|
-
# trigger.when('KoKodi').to(:playing)
|
148
|
-
|
149
|
-
# trigger.at('18:00:00')
|
150
|
-
# trigger.when('sun').set
|
151
|
-
# trigger.on('my_event_name') # using platform 'event'
|
152
|
-
#
|
153
|
-
# Documentation:
|
154
|
-
# trigger.when('a component short name') creates a trigger on the component state. It is possible to call:
|
155
|
-
# from('old state') and to('new state') on it.
|
156
|
-
# It is also possible to call any method whose name is the new state, like .playing
|
157
|
-
end
|
@@ -4,24 +4,23 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'home_assistant/generator/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = "home_assistant-generator"
|
8
8
|
spec.version = HomeAssistant::Generator::VERSION
|
9
9
|
spec.version = "#{spec.version}-alpha-#{ENV['TRAVIS_BUILD_NUMBER']}" if ENV['TRAVIS']
|
10
10
|
spec.authors = ["Grégoire Seux"]
|
11
|
-
spec.email = [
|
11
|
+
spec.email = ["grego_homeassistant@familleseux.net"]
|
12
12
|
|
13
|
-
spec.summary =
|
14
|
-
spec.license =
|
13
|
+
spec.summary = %q{Helper to generate home-assistant configuration}
|
14
|
+
spec.license = "Apache License v2"
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
-
spec.bindir =
|
17
|
+
spec.bindir = "bin"
|
18
18
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
-
spec.require_paths = [
|
19
|
+
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_development_dependency
|
22
|
-
spec.add_development_dependency
|
23
|
-
spec.add_development_dependency
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.11"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
24
24
|
|
25
25
|
spec.add_runtime_dependency 'mash'
|
26
|
-
spec.add_runtime_dependency 'activesupport'
|
27
26
|
end
|
@@ -1,30 +1,33 @@
|
|
1
|
-
|
1
|
+
require 'mash'
|
2
2
|
|
3
3
|
module HomeAssistant
|
4
4
|
module Generator
|
5
5
|
# generic home-assistant component
|
6
6
|
class Component
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
send(name_property, name) if name
|
7
|
+
attr_reader :properties
|
8
|
+
attr_accessor :component_class
|
9
|
+
def initialize(name)
|
10
|
+
@properties = Mash.new
|
11
|
+
send(name_property, name)
|
13
12
|
end
|
14
13
|
|
15
14
|
def name_property
|
16
15
|
:name
|
17
16
|
end
|
18
17
|
|
18
|
+
def to_h
|
19
|
+
properties.to_hash
|
20
|
+
end
|
21
|
+
|
19
22
|
def method_missing(name, *args)
|
20
23
|
super unless args.one?
|
21
24
|
|
22
|
-
properties[name.
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
properties[name.to_sym] = case args.first
|
26
|
+
when Symbol
|
27
|
+
args.first.to_s
|
28
|
+
else
|
29
|
+
args.first
|
30
|
+
end
|
28
31
|
end
|
29
32
|
end
|
30
33
|
end
|
@@ -1,103 +1,48 @@
|
|
1
|
+
require 'mash'
|
1
2
|
require 'yaml'
|
2
3
|
|
3
4
|
require_relative 'component'
|
4
|
-
require_relative 'plural'
|
5
|
-
require_relative 'script'
|
6
|
-
require_relative 'automation'
|
7
|
-
|
8
|
-
module CamelCase
|
9
|
-
refine String do
|
10
|
-
def snake_case
|
11
|
-
gsub(/::/, '/')
|
12
|
-
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
13
|
-
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
14
|
-
.tr('-', '_')
|
15
|
-
.downcase
|
16
|
-
end
|
17
|
-
|
18
|
-
def camel_case
|
19
|
-
split('_').collect(&:capitalize).join
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
module IfEmpty
|
25
|
-
refine Hash do
|
26
|
-
def if_empty(default)
|
27
|
-
if empty?
|
28
|
-
default
|
29
|
-
else
|
30
|
-
self
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
5
|
|
36
6
|
module HomeAssistant
|
37
7
|
module Generator
|
38
8
|
# dsl class to read config file and evaluate it
|
39
9
|
class DSL
|
40
|
-
attr_reader :component_list
|
41
|
-
|
42
|
-
using CamelCase
|
43
|
-
using IfEmpty
|
10
|
+
attr_reader :component_list
|
44
11
|
|
45
12
|
def initialize
|
46
13
|
@component_list = []
|
47
|
-
@automations = []
|
48
14
|
end
|
49
15
|
|
50
|
-
def eval(file_path
|
51
|
-
instance_eval(File.read(file_path), file_path)
|
52
|
-
instance_eval(&block) if block_given?
|
16
|
+
def eval(file_path)
|
17
|
+
instance_eval(File.read(file_path), file_path)
|
53
18
|
end
|
54
19
|
|
55
20
|
def method_missing(name, *args, &block)
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
if DSL.const_defined?(klass_name)
|
67
|
-
debug("Found #{klass_name} in DSL namespace, will use it")
|
68
|
-
else
|
69
|
-
debug("No #{klass_name} class, defining dynamic class")
|
70
|
-
DSL.const_set(klass_name, Class.new(Component) {})
|
71
|
-
end
|
72
|
-
element = DSL.const_get(klass_name).new(*args)
|
73
|
-
element.send(:platform, platform) if platform
|
21
|
+
super unless args.one?
|
22
|
+
|
23
|
+
klass_name = name.to_s.split('_').collect(&:capitalize).join
|
24
|
+
element = if DSL.const_defined?(klass_name) && DSL.const_get(klass_name)
|
25
|
+
debug("Defining #{klass_name} instance")
|
26
|
+
DSL.const_get(klass_name).new(*args)
|
27
|
+
else
|
28
|
+
debug("No #{klass_name} class, fallback on basic component")
|
29
|
+
Component.new(*args).tap { |c| c.component_class = name }
|
30
|
+
end
|
74
31
|
component_list << element
|
75
32
|
element.instance_eval(&block) if block_given?
|
76
33
|
element
|
77
34
|
end
|
78
35
|
|
79
|
-
def
|
80
|
-
|
36
|
+
def debug(message)
|
37
|
+
$stderr.puts message if ENV['DEBUG']
|
81
38
|
end
|
82
39
|
|
83
40
|
def to_s
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
components.map(&:to_h)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
config = config.merge('automation' => automations.map(&:to_h))
|
94
|
-
config.to_h.to_yaml
|
95
|
-
end
|
96
|
-
|
97
|
-
private
|
98
|
-
|
99
|
-
def debug(message)
|
100
|
-
$stderr.puts message if ENV['DEBUG']
|
41
|
+
component_list.inject(Mash.new) do |mem, component|
|
42
|
+
mem[component.component_class] ||= []
|
43
|
+
mem[component.component_class] << component.to_h
|
44
|
+
mem
|
45
|
+
end.to_hash.to_yaml
|
101
46
|
end
|
102
47
|
end
|
103
48
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: home_assistant-generator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Grégoire Seux
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-01-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,20 +66,6 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: activesupport
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :runtime
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
69
|
description:
|
84
70
|
email:
|
85
71
|
- grego_homeassistant@familleseux.net
|
@@ -90,7 +76,6 @@ extra_rdoc_files: []
|
|
90
76
|
files:
|
91
77
|
- ".gitignore"
|
92
78
|
- ".rspec"
|
93
|
-
- ".rubocop.yml"
|
94
79
|
- ".travis.yml"
|
95
80
|
- Gemfile
|
96
81
|
- LICENSE
|
@@ -100,12 +85,8 @@ files:
|
|
100
85
|
- example_config.rb
|
101
86
|
- home_assistant-generator.gemspec
|
102
87
|
- lib/home_assistant/generator.rb
|
103
|
-
- lib/home_assistant/generator/automation.rb
|
104
88
|
- lib/home_assistant/generator/component.rb
|
105
89
|
- lib/home_assistant/generator/dsl.rb
|
106
|
-
- lib/home_assistant/generator/plural.rb
|
107
|
-
- lib/home_assistant/generator/properties.rb
|
108
|
-
- lib/home_assistant/generator/script.rb
|
109
90
|
- lib/home_assistant/generator/version.rb
|
110
91
|
homepage:
|
111
92
|
licenses:
|
@@ -122,12 +103,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
122
103
|
version: '0'
|
123
104
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
105
|
requirements:
|
125
|
-
- - "
|
106
|
+
- - ">="
|
126
107
|
- !ruby/object:Gem::Version
|
127
|
-
version:
|
108
|
+
version: '0'
|
128
109
|
requirements: []
|
129
110
|
rubyforge_project:
|
130
|
-
rubygems_version: 2.
|
111
|
+
rubygems_version: 2.5.2
|
131
112
|
signing_key:
|
132
113
|
specification_version: 4
|
133
114
|
summary: Helper to generate home-assistant configuration
|
data/.rubocop.yml
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
AllCops:
|
2
|
-
TargetRubyVersion: 2.3
|
3
|
-
|
4
|
-
Style/FrozenStringLiteralComment:
|
5
|
-
Enabled: false
|
6
|
-
|
7
|
-
Metrics/LineLength:
|
8
|
-
Max: 120
|
9
|
-
|
10
|
-
Metrics/MethodLength:
|
11
|
-
Max: 20
|
12
|
-
|
13
|
-
Metrics/AbcSize:
|
14
|
-
Enabled: false
|
15
|
-
|
16
|
-
Metrics/CyclomaticComplexity:
|
17
|
-
Enabled: false
|
18
|
-
|
19
|
-
Style/Documentation:
|
20
|
-
Enabled: false # not yet
|
@@ -1,54 +0,0 @@
|
|
1
|
-
require_relative 'properties'
|
2
|
-
|
3
|
-
module HomeAssistant
|
4
|
-
module Generator
|
5
|
-
# describe an automation from home-assistant
|
6
|
-
class Automation
|
7
|
-
prepend Properties
|
8
|
-
|
9
|
-
def initialize(name, &block)
|
10
|
-
properties['alias'] = name
|
11
|
-
instance_eval(&block)
|
12
|
-
end
|
13
|
-
|
14
|
-
def trigger
|
15
|
-
properties['trigger'] ||= Trigger.new
|
16
|
-
properties['trigger']
|
17
|
-
end
|
18
|
-
|
19
|
-
class Trigger
|
20
|
-
prepend Properties
|
21
|
-
attr_reader :sub
|
22
|
-
def initialize
|
23
|
-
@sub = nil
|
24
|
-
end
|
25
|
-
|
26
|
-
def when(component_short_name)
|
27
|
-
# TODO: search for real entity_id
|
28
|
-
properties['entity_id'] = component_short_name
|
29
|
-
properties['platform'] = 'state'
|
30
|
-
@sub = State.new(properties)
|
31
|
-
@sub
|
32
|
-
end
|
33
|
-
|
34
|
-
class State
|
35
|
-
def initialize(properties)
|
36
|
-
@properties = properties
|
37
|
-
end
|
38
|
-
|
39
|
-
def method_missing(name, *args)
|
40
|
-
case args.size
|
41
|
-
when 1
|
42
|
-
@properties[name.to_s] = args.first
|
43
|
-
when 0
|
44
|
-
@properties['to'] = name
|
45
|
-
else
|
46
|
-
super
|
47
|
-
end
|
48
|
-
self
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
require 'active_support/inflector'
|
2
|
-
|
3
|
-
module HomeAssistant
|
4
|
-
module Generator
|
5
|
-
# using default Component class behavior would lead to write:
|
6
|
-
# command_line__switch do
|
7
|
-
# switches(capodimonte_led: {
|
8
|
-
# command_on: ...,
|
9
|
-
# commond_off: ...
|
10
|
-
# },
|
11
|
-
# nzbget_pause: {
|
12
|
-
# command_on: ...,
|
13
|
-
# commond_off: ...
|
14
|
-
# })
|
15
|
-
# end
|
16
|
-
#
|
17
|
-
# which is not very convenient
|
18
|
-
# it is easier to read the following code:
|
19
|
-
#
|
20
|
-
# command_line__switch 'capodimonte_led' do
|
21
|
-
# command_on '...'
|
22
|
-
# command_off '...'
|
23
|
-
# end
|
24
|
-
# command_line__switch 'nzbget' do
|
25
|
-
# command_on '...'
|
26
|
-
# command_off '...'
|
27
|
-
# end
|
28
|
-
class PluralComponent < Component
|
29
|
-
def name(value)
|
30
|
-
@element_name = value
|
31
|
-
end
|
32
|
-
|
33
|
-
def platform(value)
|
34
|
-
@platform = value
|
35
|
-
end
|
36
|
-
|
37
|
-
def to_h
|
38
|
-
plural = self.class.name.downcase.split('::').last.pluralize
|
39
|
-
if properties.key?(plural)
|
40
|
-
# support "dumb" syntax
|
41
|
-
{ 'platform' => @platform }.merge(super)
|
42
|
-
else
|
43
|
-
{ 'platform' => @platform, plural => { @element_name => super } }
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
class DSL
|
48
|
-
class Switch < PluralComponent; end
|
49
|
-
class Cover < PluralComponent; end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
require 'mash'
|
2
|
-
|
3
|
-
class Hash
|
4
|
-
# reimplem of ruby 2.4 transform_values
|
5
|
-
if RUBY_VERSION < '2.4'
|
6
|
-
def transform_values
|
7
|
-
Hash[
|
8
|
-
map do |k, v|
|
9
|
-
[k, (yield v)]
|
10
|
-
end
|
11
|
-
]
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
class Object
|
17
|
-
def convert_to_hash
|
18
|
-
has_to_h = ->(x) { x.respond_to?(:to_h) }
|
19
|
-
case self
|
20
|
-
when String, Numeric, TrueClass, FalseClass
|
21
|
-
self
|
22
|
-
when Symbol
|
23
|
-
to_s
|
24
|
-
when Hash
|
25
|
-
keys.each_with_object({}) do |key, hash|
|
26
|
-
hash[key.to_s] = self[key].convert_to_hash
|
27
|
-
end
|
28
|
-
when Array # here we suppose array of scalar
|
29
|
-
map(&:convert_to_hash)
|
30
|
-
when has_to_h
|
31
|
-
to_h
|
32
|
-
else
|
33
|
-
raise "Can't convert #{inspect} to a hash"
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
module HomeAssistant
|
39
|
-
module Generator
|
40
|
-
# can be prepended by any class with properties hash
|
41
|
-
module Properties
|
42
|
-
attr_reader :properties
|
43
|
-
|
44
|
-
def initialize(*args)
|
45
|
-
@properties = {}
|
46
|
-
super
|
47
|
-
end
|
48
|
-
|
49
|
-
def to_h
|
50
|
-
properties.convert_to_hash
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
@@ -1,72 +0,0 @@
|
|
1
|
-
require_relative 'component'
|
2
|
-
|
3
|
-
class Array
|
4
|
-
def ===(value)
|
5
|
-
# self is the pattern, value is the object we try to match
|
6
|
-
return false unless value.is_a?(Array) && size == value.size
|
7
|
-
zip(value).all? do |pattern, b|
|
8
|
-
(pattern === b).tap do |res|
|
9
|
-
puts "#{pattern.inspect} === #{b} => #{res}"
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
module HomeAssistant
|
16
|
-
module Generator
|
17
|
-
class DSL
|
18
|
-
class Script < Component
|
19
|
-
|
20
|
-
def name_property
|
21
|
-
:alias
|
22
|
-
end
|
23
|
-
|
24
|
-
def alias(value = nil)
|
25
|
-
if value
|
26
|
-
@alias = value
|
27
|
-
properties[id]['alias'] ||= value
|
28
|
-
end
|
29
|
-
@alias
|
30
|
-
end
|
31
|
-
|
32
|
-
def id
|
33
|
-
@alias.underscore.tap do |_id|
|
34
|
-
properties[_id] ||= {}
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
class SequenceAction
|
39
|
-
def initialize(k, v)
|
40
|
-
@k = k
|
41
|
-
@v = v
|
42
|
-
end
|
43
|
-
|
44
|
-
def convert_to_hash
|
45
|
-
{ @k => @v }
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def method_missing(name, *args, &block)
|
50
|
-
properties[id]['sequence'] ||= []
|
51
|
-
parts = name.to_s.split('_')
|
52
|
-
|
53
|
-
empty = -> (array) { array.is_a?(Array) && array.empty? }
|
54
|
-
one_el = -> (array) { array.is_a?(Array) && array.one? }
|
55
|
-
|
56
|
-
case [args, parts]
|
57
|
-
when [empty, one_el]
|
58
|
-
return super if parts.size.one?
|
59
|
-
when [empty, Array]
|
60
|
-
# there is ambiguity if parts has 3 elements
|
61
|
-
component = parts.pop
|
62
|
-
SequenceAction.new('service', "#{component}.#{parts.join('_')}")
|
63
|
-
else
|
64
|
-
raise 'Not implemented yet!'
|
65
|
-
end.tap do |el|
|
66
|
-
properties[id]['sequence'] << el if el.is_a?(SequenceAction)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|