home_assistant-generator 0.1.0.pre.alpha.pre.20 → 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 +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
|
[](https://travis-ci.org/kamaradclimber/home_assistant-generator)
|
6
4
|
[](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
|