discovery_spec.rb 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. require 'api_client'
  2. RSpec.describe 'MQTT Discovery' do
  3. before(:all) do
  4. @client = ApiClient.new(ENV.fetch('ESPMH_HOSTNAME'), ENV.fetch('ESPMH_TEST_DEVICE_ID_BASE'))
  5. @client.upload_json('/settings', 'settings.json')
  6. @test_id = 1
  7. @topic_prefix = mqtt_topic_prefix()
  8. @discovery_prefix = "#{@topic_prefix}discovery/"
  9. @mqtt_client = create_mqtt_client()
  10. end
  11. after(:all) do
  12. # Clean up any leftover cruft
  13. @mqtt_client.on_message("#{@discovery_prefix}#", 1, false) do |topic, message|
  14. if message.length > 0
  15. @mqtt_client.publish(topic, '', true)
  16. end
  17. false
  18. end
  19. @mqtt_client.wait_for_listeners
  20. end
  21. before(:each) do
  22. mqtt_params = mqtt_parameters()
  23. @client.put(
  24. '/settings',
  25. mqtt_params
  26. )
  27. @id_params = {
  28. id: @client.generate_id,
  29. type: 'rgb_cct',
  30. group_id: 1
  31. }
  32. @discovery_suffix = "#{@id_params[:type]}_#{sprintf("0x%04x", @id_params[:id])}_#{@id_params[:group_id]}/config"
  33. @test_discovery_prefix = "#{@discovery_prefix}#{@id_params[:id]}/"
  34. end
  35. context 'when not configured' do
  36. it 'should behave appropriately when MQTT is not configured' do
  37. @client.patch_settings(mqtt_server: '', home_assistant_discovery_prefix: '')
  38. expect { @client.get('/settings') }.to_not raise_error
  39. end
  40. it 'should behave appropriately when MQTT is configured, but discovery is not' do
  41. @client.patch_settings(mqtt_parameters().merge(home_assistant_discovery_prefix: ''))
  42. expect { @client.get('/settings') }.to_not raise_error
  43. end
  44. end
  45. context 'discovery topics' do
  46. it 'should send discovery messages' do
  47. saw_message = false
  48. @mqtt_client.on_message("#{@test_discovery_prefix}light/+/#{@discovery_suffix}") do |topic, message|
  49. saw_message = true
  50. end
  51. @client.patch_settings(
  52. home_assistant_discovery_prefix: @test_discovery_prefix,
  53. group_id_aliases: {
  54. 'test_group' => [@id_params[:type], @id_params[:id], @id_params[:group_id]]
  55. }
  56. )
  57. @mqtt_client.wait_for_listeners
  58. expect(saw_message).to be(true)
  59. end
  60. it 'config should have expected keys' do
  61. saw_message = false
  62. config = nil
  63. @mqtt_client.on_message("#{@test_discovery_prefix}light/+/#{@discovery_suffix}") do |topic, message|
  64. config = JSON.parse(message)
  65. saw_message = true
  66. end
  67. @client.patch_settings(
  68. home_assistant_discovery_prefix: @test_discovery_prefix,
  69. group_id_aliases: {
  70. 'test_group' => [@id_params[:type], @id_params[:id], @id_params[:group_id]]
  71. }
  72. )
  73. @mqtt_client.wait_for_listeners
  74. expect(saw_message).to be(true)
  75. expected_keys = %w(
  76. schema
  77. name
  78. command_topic
  79. state_topic
  80. brightness
  81. rgb
  82. color_temp
  83. effect
  84. effect_list
  85. device
  86. )
  87. expect(config.keys).to include(*expected_keys)
  88. end
  89. it 'should list identifiers for ESP and bulb' do
  90. saw_message = false
  91. config = nil
  92. @mqtt_client.on_message("#{@test_discovery_prefix}light/+/#{@discovery_suffix}") do |topic, message|
  93. config = JSON.parse(message)
  94. saw_message = config['device']['identifiers'][1] == @id_params[:id]
  95. end
  96. @client.patch_settings(
  97. home_assistant_discovery_prefix: @test_discovery_prefix,
  98. group_id_aliases: {
  99. 'test_group' => [@id_params[:type], @id_params[:id], @id_params[:group_id]]
  100. }
  101. )
  102. @mqtt_client.wait_for_listeners
  103. expect(config.keys).to include('device')
  104. device_data = config['device']
  105. expect(device_data.keys).to include(*%w(manufacturer sw_version identifiers))
  106. expect(device_data['manufacturer']).to eq('esp8266_milight_hub')
  107. ids = device_data['identifiers']
  108. expect(ids.length).to eq(4)
  109. expect(ids[1]).to eq(@id_params[:id])
  110. expect(ids[2]).to eq(@id_params[:type])
  111. expect(ids[3]).to eq(@id_params[:group_id])
  112. end
  113. it 'should remove discoverable devices when alias is removed' do
  114. seen_config = false
  115. seen_blank_message = false
  116. @mqtt_client.on_message("#{@test_discovery_prefix}light/+/#{@discovery_suffix}") do |topic, message|
  117. seen_config = seen_config || message.length > 0
  118. seen_blank_message = seen_blank_message || message.length == 0
  119. seen_config && seen_blank_message
  120. end
  121. # This should create the device
  122. @client.patch_settings(
  123. home_assistant_discovery_prefix: @test_discovery_prefix,
  124. group_id_aliases: {
  125. 'test_group' => [@id_params[:type], @id_params[:id], @id_params[:group_id]]
  126. }
  127. )
  128. # This should clear it
  129. @client.patch_settings(
  130. group_id_aliases: { }
  131. )
  132. @mqtt_client.wait_for_listeners
  133. expect(seen_config).to be(true)
  134. expect(seen_blank_message).to be(true), "should see deletion message"
  135. end
  136. it 'should configure devices with an availability topic if client status is configured' do
  137. expected_keys = %w(
  138. availability_topic
  139. payload_available
  140. payload_not_available
  141. )
  142. config = nil
  143. @mqtt_client.on_message("#{@test_discovery_prefix}light/+/#{@discovery_suffix}") do |topic, message|
  144. config = JSON.parse(message)
  145. (expected_keys - config.keys).empty?
  146. end
  147. # This should create the device
  148. @client.patch_settings(
  149. home_assistant_discovery_prefix: @test_discovery_prefix,
  150. group_id_aliases: {
  151. 'test_group' => [@id_params[:type], @id_params[:id], @id_params[:group_id]]
  152. },
  153. mqtt_client_status_topic: "#{@topic_prefix}status",
  154. simple_mqtt_client_status: true
  155. )
  156. @mqtt_client.wait_for_listeners
  157. expect(config.keys).to include(*expected_keys)
  158. end
  159. end
  160. end