36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
# File 'lib/mqtt/home_assistant/client.rb', line 36
def publish_hass_component(object_id, platform:, discovery_prefix: "homeassistant", node_id: nil, **kwargs)
node_and_object_id = node_id ? "#{node_id}/#{object_id}" : object_id
unless KNOWN_ATTRIBUTES.key?(platform)
raise ArgumentError, "Unknown platform #{platform} for #{node_and_object_id}"
end
required_attributes = attributes_for_schema(REQUIRED_ATTRIBUTES, platform, kwargs)
if required_attributes
missing_attributes = required_attributes - kwargs.keys
unless missing_attributes&.empty?
raise ArgumentError,
"Missing attribute(s) #{missing_attributes.join(", ")} for #{platform}/#{node_and_object_id}"
end
end
known_attributes = attributes_for_schema(KNOWN_ATTRIBUTES, platform, kwargs)
unknown_attributes = kwargs.keys - SPECIAL_ATTRIBUTES[:common] - known_attributes
unless unknown_attributes.empty?
raise ArgumentError,
"Unknown attribute(s) #{unknown_attributes.join(", ")} for #{platform}/#{node_and_object_id}"
end
if (availability_list = kwargs[:availability])
unless (kwargs.keys & %i[availability_mode
availability_template
availability_topic
payload_available
payload_not_available]).empty?
raise ArgumentError,
"availability cannot be used together with availability topic for #{platform}/#{node_and_object_id}"
end
availability_list = [availability_list] if availability_list.is_a?(Hash)
unless availability_list.is_a?(Array)
raise ArgumentError, "availability must be an array for #{platform}/#{node_and_object_id}"
end
availability_list.each do |availability|
unless availability.key?(:topic)
raise ArgumentError, "availability must have a topic for #{platform}/#{node_and_object_id}"
end
unless ( = availability.keys - SPECIAL_ATTRIBUTES[:availability]).empty?
raise ArgumentError,
"Unknown attribute(s) #{} for #{platform}/#{node_and_object_id}'s availability"
end
end
end
if (device = kwargs[:device])
raise ArgumentError, "device must be a hash for #{platform}/#{node_and_object_id}" unless device.is_a?(Hash)
unless ( = device.keys - SPECIAL_ATTRIBUTES[:device]).empty?
raise ArgumentError, "Unknown attribute(s) #{} for #{platform}/#{node_and_object_id}'s device"
end
end
INCLUSION_VALIDATIONS[:common].merge(INCLUSION_VALIDATIONS[platform] || {}).each do |attr, valid_values|
if (value = kwargs[attr]) && !valid_values.include?(value)
raise ArgumentError, "Unrecognized #{attr} #{value} for #{platform}/#{node_and_object_id}"
end
end
SUBSET_VALIDATIONS[platform]&.each do |attr, valid_values|
if (values = kwargs[attr]) && !( = values - valid_values).empty?
raise ArgumentError, "Invalid #{attr} #{.join(", ")} for #{platform}/#{node_and_object_id}"
end
end
VALIDATIONS[platform]&.call(**kwargs)
RANGE_ATTRIBUTES[platform]&.each do |attr, prefix_or_suffix|
if (range = kwargs.delete(:"#{attr}_range"))
case prefix_or_suffix
when :prefix
kwargs[:"min_#{attr}"] = range.begin
kwargs[:"max_#{attr}"] = range.end
when :suffix
kwargs[:"#{attr}_min"] = range.begin
kwargs[:"#{attr}_max"] = range.end
when :singleton
kwargs[:min] = range.begin
kwargs[:max] = range.end
end
end
end
publish("#{discovery_prefix || "homeassistant"}/#{platform}/#{node_and_object_id}/config",
kwargs.to_json,
retain: true,
qos: 1)
end
|