A verifiable method of control and actioning of the Somfy blinds was required because they often fail to respond to commands from the Somfy App via its Connectivity Kit .
The Dashboard not only shows the current status of the blinds as depicted by the Roller Blinds icon, but also controls opening and closing either by clicking on the icon, or via the Blinds schedule using ui_scheduling. The status of the Blinds is determined using the Ikea MYGGBETT door/window sensor connected by matter over thread to an Aqara Hub M100 on the home network. When the blinds are in the process of being opened/closed then three pulsating vertical dots appear next to the icon.
The status of the Blinds is determined using matterreadattr of @sammachin/node-red-matter-controller.The Somfy Blinds are operated via their specific app through Alexa and controlled via the mattercontactsensor of @sammachin/node-red-matter-bridge. a maximum of 6 attempts to operate the blinds are made. Each attempt is shown as a LOOP number, if successful the interface reports DONE otherwise it displays FAIL.
This Node-RED flow automates a smart blind system via Matter, using UI scheduling and manual switches to set target states while providing visual, animated feedback during operation. It incorporates a verification loop that checks the blind's status, triggering up to six retries with a five-second delay if the physical position does not match the requested state.
Detect Page Load ui-event for My Dashboard[/dashboard], $pageview - emits whenever a user views a page and so acts as a "Refresh" button that triggers automatically whenever the dashboard is accessed'
ui-event (Detect Page Load): This node listens for any interaction with your Dashboard 2.0 interface. Because includeClientData is enabled in your ui-base, it sends a message whenever a user connects.
switch (Is Pageview?): It filters the incoming events. It only allows the message to pass if the msg.topic is exactly $pageview (meaning a user just opened the URL).
matterreadattr (Blind STATUS): acts as a "request." to ask the MYGGBETT directly: "What is your current stateValue (Cluster 69) right now?"
The Result: The output will contain the real-time status of the blind, ensuring your dashboard doesn't show old info just because the blind has been controlled by e.g. a voice command and not the dashboard.
The Trigger: The flow starts when you either the Blinds Switch is flipped on the dashboard or when the Blinds Schedule hits a pre-set time (like sunrise).The Switch icons (On Icon = mdi-blinds-open; Off Icon = mdi-roller-shade-closed) given </> Class large-switch and assigned in the busy dots ui-template
<template>
<div class="animation-wrapper">
<transition name="fade">
<div v-if="isBusy" class="busy-dots">
●<br>●<br>●
</div>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
isBusy: false
}
},
watch: {
msg: {
handler(msg) {
// If topic is 'busy' (from switch) OR state is 'busy' (from external)
if (msg?.topic === 'busy' || msg?.state === 'busy') {
this.isBusy = true
}
// Stop if explicitly told to be 'idle'
else if (msg?.state === 'idle') {
this.isBusy = false
}
},
immediate: true
}
}
}
</script>
<style>
/* 1. Resize Switch Icon */
.large-switch .v-icon {
font-size: 48px !important;
width: 48px !important;
height: 48px !important;
}
/* 2. Pull animation closer by removing margins/padding */
.animation-wrapper {
height: 48px;
display: flex;
align-items: center;
/*margin-left: -12px; /* Pulls dots toward the switch icon */
}
.busy-dots {
display: flex;
flex-direction: column;
line-height: 0.6; /* Tightens vertical dot spacing */
font-size: 1.1rem;
color: var(--nrdb-primary-color);
animation: pulse 0.8s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.2; }
}
.fade-enter-active, .fade-leave-active { transition: opacity 0.3s; }
.fade-enter-from, .fade-leave-to { opacity: 0; }
</style>
Setting the Goal: Once triggered, the flow saves your request (e.g., "Open") and sets the system status to "busy." The Loop label characteristics and initial retryCount are set.
Visual Feedback: This "busy" status triggers a "Busy Dots" animation on the dashboard. This lets you know the command is being processed even if the blinds haven't finished moving yet.
Checking Reality: The flow talks to your blind (via Matter) to ask for its current physical position.
The Logic Loop:
Success: If the blind’s position matches your request, the status changes to "idle," the dots disappear, and the flow stops.
Try Again: If they don't match, the flow waits e.g. 5 seconds, adds 1 to a "retry count," and sends the command again.
Safety Cut-off: To prevent the motor from running forever if something is stuck, the flow will give up after 6 failed attempts.
The Switch nodes (FAILED and DONE ) in the flow before Loop Count set the characteristics of ui-text in which Apply Style has been enabled