@@ -493,6 +493,191 @@ async def test_controlling_state_via_mqtt_rgbww(hass, mqtt_mock, setup_tasmota):
493493 assert state .state == STATE_OFF
494494
495495
496+ async def test_controlling_state_via_mqtt_rgbww_hex (hass , mqtt_mock , setup_tasmota ):
497+ """Test state update via MQTT."""
498+ config = copy .deepcopy (DEFAULT_CONFIG )
499+ config ["rl" ][0 ] = 2
500+ config ["lt_st" ] = 5 # 5 channel light (RGBCW)
501+ config ["so" ]["17" ] = 0 # Hex color in state updates
502+ mac = config ["mac" ]
503+
504+ async_fire_mqtt_message (
505+ hass ,
506+ f"{ DEFAULT_PREFIX } /{ mac } /config" ,
507+ json .dumps (config ),
508+ )
509+ await hass .async_block_till_done ()
510+
511+ state = hass .states .get ("light.test" )
512+ assert state .state == "unavailable"
513+ assert not state .attributes .get (ATTR_ASSUMED_STATE )
514+
515+ async_fire_mqtt_message (hass , "tasmota_49A3BC/tele/LWT" , "Online" )
516+ state = hass .states .get ("light.test" )
517+ assert state .state == STATE_OFF
518+ assert not state .attributes .get (ATTR_ASSUMED_STATE )
519+
520+ async_fire_mqtt_message (hass , "tasmota_49A3BC/tele/STATE" , '{"POWER":"ON"}' )
521+ state = hass .states .get ("light.test" )
522+ assert state .state == STATE_ON
523+
524+ async_fire_mqtt_message (hass , "tasmota_49A3BC/tele/STATE" , '{"POWER":"OFF"}' )
525+ state = hass .states .get ("light.test" )
526+ assert state .state == STATE_OFF
527+
528+ async_fire_mqtt_message (
529+ hass , "tasmota_49A3BC/tele/STATE" , '{"POWER":"ON","Dimmer":50}'
530+ )
531+ state = hass .states .get ("light.test" )
532+ assert state .state == STATE_ON
533+ assert state .attributes .get ("brightness" ) == 127.5
534+
535+ async_fire_mqtt_message (
536+ hass , "tasmota_49A3BC/tele/STATE" , '{"POWER":"ON","Color":"FF8000"}'
537+ )
538+ state = hass .states .get ("light.test" )
539+ assert state .state == STATE_ON
540+ assert state .attributes .get ("rgb_color" ) == (255 , 128 , 0 )
541+
542+ async_fire_mqtt_message (
543+ hass , "tasmota_49A3BC/tele/STATE" , '{"POWER":"ON","Color":"00FF800000"}'
544+ )
545+ state = hass .states .get ("light.test" )
546+ assert state .state == STATE_ON
547+ assert state .attributes .get ("rgb_color" ) == (0 , 255 , 128 )
548+
549+ async_fire_mqtt_message (
550+ hass , "tasmota_49A3BC/tele/STATE" , '{"POWER":"ON","White":50}'
551+ )
552+ state = hass .states .get ("light.test" )
553+ assert state .state == STATE_ON
554+ assert state .attributes .get ("white_value" ) == 127.5
555+ # Setting white > 0 should clear the color
556+ assert not state .attributes .get ("rgb_color" )
557+
558+ async_fire_mqtt_message (
559+ hass , "tasmota_49A3BC/tele/STATE" , '{"POWER":"ON","CT":300}'
560+ )
561+ state = hass .states .get ("light.test" )
562+ assert state .state == STATE_ON
563+ assert state .attributes .get ("color_temp" ) == 300
564+
565+ async_fire_mqtt_message (
566+ hass , "tasmota_49A3BC/tele/STATE" , '{"POWER":"ON","White":0}'
567+ )
568+ state = hass .states .get ("light.test" )
569+ assert state .state == STATE_ON
570+ # Setting white to 0 should clear the white_value and color_temp
571+ assert not state .attributes .get ("white_value" )
572+ assert not state .attributes .get ("color_temp" )
573+
574+ async_fire_mqtt_message (
575+ hass , "tasmota_49A3BC/tele/STATE" , '{"POWER":"ON","Scheme":3}'
576+ )
577+ state = hass .states .get ("light.test" )
578+ assert state .state == STATE_ON
579+ assert state .attributes .get ("effect" ) == "Cycle down"
580+
581+ async_fire_mqtt_message (hass , "tasmota_49A3BC/stat/RESULT" , '{"POWER":"ON"}' )
582+
583+ state = hass .states .get ("light.test" )
584+ assert state .state == STATE_ON
585+
586+ async_fire_mqtt_message (hass , "tasmota_49A3BC/stat/RESULT" , '{"POWER":"OFF"}' )
587+
588+ state = hass .states .get ("light.test" )
589+ assert state .state == STATE_OFF
590+
591+
592+ async def test_controlling_state_via_mqtt_rgbww_tuya (hass , mqtt_mock , setup_tasmota ):
593+ """Test state update via MQTT."""
594+ config = copy .deepcopy (DEFAULT_CONFIG )
595+ config ["rl" ][0 ] = 2
596+ config ["lt_st" ] = 5 # 5 channel light (RGBCW)
597+ config ["ty" ] = 1 # Tuya device
598+ mac = config ["mac" ]
599+
600+ async_fire_mqtt_message (
601+ hass ,
602+ f"{ DEFAULT_PREFIX } /{ mac } /config" ,
603+ json .dumps (config ),
604+ )
605+ await hass .async_block_till_done ()
606+
607+ state = hass .states .get ("light.test" )
608+ assert state .state == "unavailable"
609+ assert not state .attributes .get (ATTR_ASSUMED_STATE )
610+
611+ async_fire_mqtt_message (hass , "tasmota_49A3BC/tele/LWT" , "Online" )
612+ state = hass .states .get ("light.test" )
613+ assert state .state == STATE_OFF
614+ assert not state .attributes .get (ATTR_ASSUMED_STATE )
615+
616+ async_fire_mqtt_message (hass , "tasmota_49A3BC/tele/STATE" , '{"POWER":"ON"}' )
617+ state = hass .states .get ("light.test" )
618+ assert state .state == STATE_ON
619+
620+ async_fire_mqtt_message (hass , "tasmota_49A3BC/tele/STATE" , '{"POWER":"OFF"}' )
621+ state = hass .states .get ("light.test" )
622+ assert state .state == STATE_OFF
623+
624+ async_fire_mqtt_message (
625+ hass , "tasmota_49A3BC/tele/STATE" , '{"POWER":"ON","Dimmer":50}'
626+ )
627+ state = hass .states .get ("light.test" )
628+ assert state .state == STATE_ON
629+ assert state .attributes .get ("brightness" ) == 127.5
630+
631+ async_fire_mqtt_message (
632+ hass , "tasmota_49A3BC/tele/STATE" , '{"POWER":"ON","Color":"255,128,0"}'
633+ )
634+ state = hass .states .get ("light.test" )
635+ assert state .state == STATE_ON
636+ assert state .attributes .get ("rgb_color" ) == (255 , 128 , 0 )
637+
638+ async_fire_mqtt_message (
639+ hass , "tasmota_49A3BC/tele/STATE" , '{"POWER":"ON","White":50}'
640+ )
641+ state = hass .states .get ("light.test" )
642+ assert state .state == STATE_ON
643+ assert state .attributes .get ("white_value" ) == 127.5
644+ # Setting white > 0 should clear the color
645+ assert not state .attributes .get ("rgb_color" )
646+
647+ async_fire_mqtt_message (
648+ hass , "tasmota_49A3BC/tele/STATE" , '{"POWER":"ON","CT":300}'
649+ )
650+ state = hass .states .get ("light.test" )
651+ assert state .state == STATE_ON
652+ assert state .attributes .get ("color_temp" ) == 300
653+
654+ async_fire_mqtt_message (
655+ hass , "tasmota_49A3BC/tele/STATE" , '{"POWER":"ON","White":0}'
656+ )
657+ state = hass .states .get ("light.test" )
658+ assert state .state == STATE_ON
659+ # Setting white to 0 should clear the white_value and color_temp
660+ assert not state .attributes .get ("white_value" )
661+ assert not state .attributes .get ("color_temp" )
662+
663+ async_fire_mqtt_message (
664+ hass , "tasmota_49A3BC/tele/STATE" , '{"POWER":"ON","Scheme":3}'
665+ )
666+ state = hass .states .get ("light.test" )
667+ assert state .state == STATE_ON
668+ assert state .attributes .get ("effect" ) == "Cycle down"
669+
670+ async_fire_mqtt_message (hass , "tasmota_49A3BC/stat/RESULT" , '{"POWER":"ON"}' )
671+
672+ state = hass .states .get ("light.test" )
673+ assert state .state == STATE_ON
674+
675+ async_fire_mqtt_message (hass , "tasmota_49A3BC/stat/RESULT" , '{"POWER":"OFF"}' )
676+
677+ state = hass .states .get ("light.test" )
678+ assert state .state == STATE_OFF
679+
680+
496681async def test_sending_mqtt_commands_on_off (hass , mqtt_mock , setup_tasmota ):
497682 """Test the sending MQTT commands."""
498683 config = copy .deepcopy (DEFAULT_CONFIG )
@@ -745,6 +930,26 @@ async def test_transition(hass, mqtt_mock, setup_tasmota):
745930 )
746931 mqtt_mock .async_publish .reset_mock ()
747932
933+ # Dim the light from 0->100: Speed should be capped at 40
934+ await common .async_turn_on (hass , "light.test" , brightness = 255 , transition = 100 )
935+ mqtt_mock .async_publish .assert_called_once_with (
936+ "tasmota_49A3BC/cmnd/Backlog" ,
937+ "NoDelay;Fade 1;NoDelay;Speed 40;NoDelay;Dimmer 100" ,
938+ 0 ,
939+ False ,
940+ )
941+ mqtt_mock .async_publish .reset_mock ()
942+
943+ # Dim the light from 0->0: Speed should be 1
944+ await common .async_turn_on (hass , "light.test" , brightness = 0 , transition = 100 )
945+ mqtt_mock .async_publish .assert_called_once_with (
946+ "tasmota_49A3BC/cmnd/Backlog" ,
947+ "NoDelay;Fade 1;NoDelay;Speed 1;NoDelay;Power1 OFF" ,
948+ 0 ,
949+ False ,
950+ )
951+ mqtt_mock .async_publish .reset_mock ()
952+
748953 # Dim the light from 0->50: Speed should be 4*2*2=16
749954 await common .async_turn_on (hass , "light.test" , brightness = 128 , transition = 4 )
750955 mqtt_mock .async_publish .assert_called_once_with (
0 commit comments