As an experiment, I converted your pyscript example to python_script to demonstrate the syntactic differences between the two. During this exercise, I encountered the same issue you did, it failed to break out of the loop when the light group was turned off.
To correct it, I employed the technique described in this StackOverflow post: python - Breaking out of nested loops - Stack Overflow
Here’s the python_script version (confirmed it works):
# python_script
light_group = data.get('light_group', None)
delay = data.get('delay', 1)
transition = data.get('transition', 5)
colors = data.get('colors', ["red","purple"])
brightness = data.get('brightness', 255)
if light_group is not None:
bulbs = (hass.states.get(light_group)).attributes['entity_id']
for color in colors:
for bulb in bulbs:
if (hass.states.get(light_group)).state == 'off':
break
time.sleep(delay)
hass.services.call('light', 'turn_on', {'entity_id': bulb, 'color_name': color, 'transition': transition, 'brightness': brightness}, False)
else:
if (hass.states.get(light_group)).state == 'off':
break
time.sleep(transition)
continue
break
I applied the same technique to your pyscript in the example shown below. However, I have not tested it because my Hue lights are connected to my production server and I’m not running pyscript on it (yet). Comparing the syntax of the two examples, it’s clear the pyscript version provides simplified access to an entity’s state and attributes.
#pyscript
@service
def light_sequence(light_group=None, delay=1, transition=5, colors=["red","purple"], brightness=255):
if light_group is not None:
bulbs = state.get(light_group+".entity_id")
for color in colors:
for bulb in bulbs:
if state.get(light_group) == "off":
break
task.sleep(delay)
light.turn_on(entity_id=bulb, color_name=color, transition=transition, brightness=brightness)
else:
if state.get(light_group) == "off":
break
task.sleep(transition)
continue
break
Let me know if it works or not.