<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tafadzwa Alexander Razaro</title>
    <description>The latest articles on DEV Community by Tafadzwa Alexander Razaro (@tafadzwaalexander_razaro).</description>
    <link>https://dev.to/tafadzwaalexander_razaro</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1902048%2Fef997fe9-272c-4bb5-8288-03508514ee64.jpeg</url>
      <title>DEV Community: Tafadzwa Alexander Razaro</title>
      <link>https://dev.to/tafadzwaalexander_razaro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tafadzwaalexander_razaro"/>
    <language>en</language>
    <item>
      <title>LumiPulse: a cartoon of my face that breathes with you, built on Presage SmartSpectra (my pick: it’s clear and it names the SDK)</title>
      <dc:creator>Tafadzwa Alexander Razaro</dc:creator>
      <pubDate>Sat, 14 Nov 2026 03:29:50 +0000</pubDate>
      <link>https://dev.to/tafadzwaalexander_razaro/lumipulse-a-cartoon-of-my-face-that-breathes-with-you-built-on-presage-smartspectra-my-pick-4nm2</link>
      <guid>https://dev.to/tafadzwaalexander_razaro/lumipulse-a-cartoon-of-my-face-that-breathes-with-you-built-on-presage-smartspectra-my-pick-4nm2</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/presage-2026-11-04"&gt;Presage SmartSpectra SDK Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;LumiPulse&lt;/strong&gt; is an iPhone app where a cartoon buddy breathes with you, reads the room, and tries to make you laugh.&lt;/p&gt;

&lt;p&gt;The buddy is &lt;strong&gt;Lumi&lt;/strong&gt;, a wobbly poster-style blob drawn live in SwiftUI, every frame computed from your signals. Point your front camera at yourself and Lumi comes alive. It breathes in when you should breathe in, closes its eyes when you close yours, copies your mood, and cracks a joke when you look like you're carrying something heavy.&lt;/p&gt;

&lt;p&gt;Under the cartoon, LumiPulse uses the Presage SmartSpectra SDK to read your pulse, breathing, HRV, blinking, talking and facial expression live from the camera. You don't need a wearable or a chest strap, just the phone you already own. That matters where I live in Gweru, Zimbabwe, where a smartwatch is a luxury but almost everyone has a phone.&lt;/p&gt;

&lt;p&gt;There are four modes, each with its own loud poster colour:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;What it's for&lt;/th&gt;
&lt;th&gt;What Lumi does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🟢 &lt;strong&gt;Still&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;A calm minute: breathe in for 4 seconds, out for 6&lt;/td&gt;
&lt;td&gt;Breathes in exact step with you, eyes open or closed (your choice), and your phone taps a soft &lt;em&gt;lub-dub&lt;/em&gt; at your own heart rate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🟡 &lt;strong&gt;Mirror&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;"How do I look?"&lt;/td&gt;
&lt;td&gt;Copies your mood (happy, cheerful, thoughtful, sad, angry, stressed) and, if you look heavy, offers to breathe with you&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🟠 &lt;strong&gt;Ready&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;A one-minute self check-in before a ride or a drive&lt;/td&gt;
&lt;td&gt;Compares you with &lt;em&gt;your own&lt;/em&gt; usual numbers, with no pass/fail and no verdicts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🩷 &lt;strong&gt;Stage&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Speaking practice&lt;/td&gt;
&lt;td&gt;Listens while you talk, then shows where your pulse rose, with the moments you were speaking shaded in&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The style is a deliberate break from clinical health apps: lime, cobalt, pink and sun-yellow, thick ink outlines, hard shadows, tilted sticker labels and buttons that physically press down. Heavy days deserve something that doesn't look like a hospital chart.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;iframe src="https://player.vimeo.com/video/1246782165" width="710" height="399"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The video shows, on a real iPhone:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Onboarding.&lt;/strong&gt; Lumi introduces itself and explains what the camera is for. Consent comes before anything starts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Still.&lt;/strong&gt; The "Got you!" moment when the signal locks, then Lumi breathing in and out with the on-screen cue while the haptic heartbeat follows my real pulse.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mirror.&lt;/strong&gt; I smile, frown and go quiet, and Lumi's mood (and its jokes) change with me.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stage.&lt;/strong&gt; I answer a prompt out loud, then the pulse timeline shows where my nerves showed up.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/sirx2713" rel="noopener noreferrer"&gt;
        sirx2713
      &lt;/a&gt; / &lt;a href="https://github.com/sirx2713/LumiPulse" rel="noopener noreferrer"&gt;
        LumiPulse
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      iOS app where Alexander, a hand-animated Rive face, breathes with you and mirrors your mood using live pulse, breathing and expressions from the Presage SmartSpectra SDK. SwiftUI · Rive · Core Haptics. Built in Zimbabwe 🇿🇼
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;LumiPulse&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Your camera, reading the light in your skin.&lt;/strong&gt; An iOS app by LumiTek Exchange (Gweru, Zimbabwe), built on the &lt;a href="https://github.com/Presage-Security/SmartSpectra" rel="noopener noreferrer"&gt;Presage SmartSpectra SDK&lt;/a&gt;. It reads live pulse, breathing, HRV, blinking, talking and facial expressions from the front camera.&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;Live signals used&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Still&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A calm minute with Lumi, a poster-style orb that breathes in for 4 s and out for 6 s in perfect step with the on-screen cue, phase ring and haptic taps, and ripples on every real heartbeat, your phone beats softly in your hand at your own pulse, and you finish with a shareable card of how your breathing slowed.&lt;/td&gt;
&lt;td&gt;Breathing trace, breathing rate, pulse, HRV&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ready&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A one-minute self check-in before a ride or drive, compared with your &lt;em&gt;own&lt;/em&gt; usual levels. No pass/fail, no verdicts, nothing shared.&lt;/td&gt;
&lt;td&gt;Pulse, breathing rate, HRV (RMSSD), blink rate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Stage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Speaking practice. Answer a prompt out loud,&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/sirx2713/LumiPulse" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;The README covers setup in five commands: clone the repo, copy &lt;code&gt;Secrets.example.xcconfig&lt;/code&gt;, paste in your Presage API key, run &lt;code&gt;xcodegen generate&lt;/code&gt;, and open the project in Xcode. The app needs a physical iPhone, because the SDK can't measure in the Simulator. The API key lives in a git-ignored &lt;code&gt;.xcconfig&lt;/code&gt; and is read from &lt;code&gt;Info.plist&lt;/code&gt; at runtime, so it never touches the repo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stack:&lt;/strong&gt; SwiftUI (Canvas + TimelineView) · SmartSpectra Swift SDK 3.4.0 · Core Haptics · Swift Charts · XcodeGen · Rive iOS runtime 6.29.0 (for the upcoming hand-animated face)&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Responds to Human Signals
&lt;/h2&gt;

&lt;p&gt;LumiPulse uses SmartSpectra's continuous mode with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;sdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;requestedMetrics&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;breathing&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;cardio&lt;/span&gt; &lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blinking&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;talking&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expressions&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All of it flows through one &lt;code&gt;@Observable&lt;/code&gt; &lt;code&gt;VitalsEngine&lt;/code&gt; that keeps only fresh samples (newer than the last timestamp it saw) and publishes them to SwiftUI. Here's how each signal changes the experience in real time:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💓 Pulse&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When the SDK first returns a steady pulse, Lumi fires its "lock on" reaction and says &lt;em&gt;"Got you!"&lt;/em&gt;, with a success haptic.&lt;/li&gt;
&lt;li&gt;From then on the phone plays a Core Haptics &lt;em&gt;lub-dub&lt;/em&gt; at your own heart rate, so you can feel your heartbeat in your hand.&lt;/li&gt;
&lt;li&gt;In Mirror and Ready, a pulse well above your personal usual (averaged from your past sessions) nudges Lumi's mood towards "stressed", unless you're smiling.&lt;/li&gt;
&lt;li&gt;In Stage, pulse is plotted on a Swift Charts timeline against the moments you were speaking.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🌬️ Breathing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Still runs a single &lt;code&gt;BreathPacer&lt;/code&gt; clock (in 4 s, out 6 s) that drives everything at once: the "Breathe in / Breathe out" text, the phase ring, the haptic taps, and Lumi's size. The face never drifts from the instructions.&lt;/li&gt;
&lt;li&gt;The live breathing trace and rate are recorded so your results card can show how your breathing slowed over the minute.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🙂 Expressions, 👄 talking and 👁️ blinking&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;code&gt;MoodReader&lt;/code&gt; maps the SDK's expression, plus talking and pulse, onto Lumi's moods:

&lt;ul&gt;
&lt;li&gt;happy for a few seconds, or chatting → &lt;em&gt;cheerful&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;neutral and quiet → &lt;em&gt;thoughtful&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;sad → &lt;em&gt;sad&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;angry, disgust or contempt → &lt;em&gt;angry&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;fear, or a racing pulse → &lt;em&gt;stressed&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Moods only switch after a 2-second hold, so Lumi doesn't flicker.&lt;/li&gt;
&lt;li&gt;Each change triggers a matching line ("Long day? I've got a minute for you.") and, when the mood is heavy, a &lt;em&gt;Breathe with Lumi&lt;/em&gt; button.&lt;/li&gt;
&lt;li&gt;Talking makes sound waves pulse beside Lumi in Stage, so you can see it listening.&lt;/li&gt;
&lt;li&gt;Blink rate feeds the Ready check-in.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Drawing Lumi from the signals.&lt;/strong&gt; Lumi is a SwiftUI &lt;code&gt;Canvas&lt;/code&gt; inside a &lt;code&gt;TimelineView&lt;/code&gt;, redrawn every frame:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Size and a gentle stretch come straight from &lt;code&gt;BreathPacer.level&lt;/code&gt;, so Lumi's in-breath and out-breath can never drift from the on-screen cue.&lt;/li&gt;
&lt;li&gt;Eyes open blink naturally; eyes closed stay closed as calm "︶" curves for the whole session.&lt;/li&gt;
&lt;li&gt;Each mood changes the body colour, brows, slanted eyelids, mouth, cheeks, even a sweat drop when "stressed".&lt;/li&gt;
&lt;li&gt;While Lumi talks, its mouth moves through the 9 Rhubarb lip-sync shapes (X, A–H), and sound waves pulse when it's listening to you in Stage.&lt;/li&gt;
&lt;li&gt;Reactions play once and settle: a hop and sparkles on "Got you!", a spin on finishing, sunglasses or a snooze when you leave it idle.&lt;/li&gt;
&lt;li&gt;Tap Lumi and it squishes. Tap three times and it complains: &lt;em&gt;"Ow! I'm a face, not a button."&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A hand-animated Rive version of the face (driven by Rive data binding) is already wired in behind a flag for a future update.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Most Creative or Delightful Use&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What inspired it:&lt;/strong&gt; most stress and wellness apps look like a medical chart: grey cards, red warnings, numbers that make you feel worse. I wanted the opposite, a reason to smile on a bad day. Making the guide a character turns a breathing exercise into something closer to a friend pulling silly faces at you until you crack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What makes it original:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The signal &lt;em&gt;is&lt;/em&gt; the animation.&lt;/strong&gt; Lumi isn't decoration next to a chart. Your breathing, pulse and expression drive its body, eyes, mouth and mood directly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your heartbeat in your hand.&lt;/strong&gt; Haptics at your own measured heart rate make an invisible signal physical.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Humour as the interface.&lt;/strong&gt; Every state has a line written to lighten the moment, from onboarding (&lt;em&gt;"Tap me. Go on, I dare you."&lt;/em&gt;) to finishing a calm minute.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No comparison with anyone else.&lt;/strong&gt; Ready and Mirror only compare you with your own usual, never with a "normal" range, so there's nothing to fail.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Consent and Data Handling
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Consent first.&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;On first launch, Lumi explains in plain words what the camera does before any session can start; nothing runs until you accept.&lt;/li&gt;
&lt;li&gt;iOS then asks for camera permission the first time you start a session.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No covert capture.&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The camera runs only while a session is on screen.&lt;/li&gt;
&lt;li&gt;A visible "camera on" indicator shows in the live preview.&lt;/li&gt;
&lt;li&gt;The camera stops the moment you leave that screen. There's no background capture.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Video never leaves the phone.&lt;/strong&gt; Frames are processed by the SmartSpectra SDK. LumiPulse never records, saves, uploads or shares video or photos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What's stored.&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Only short session summaries: mode, date, duration, average/start/end pulse and breathing rate, HRV (RMSSD), blinks per minute, share of time speaking, the most common expression, and the practice prompt.&lt;/li&gt;
&lt;li&gt;They're kept in one JSON file on the phone with iOS Data Protection (&lt;code&gt;.completeFileProtection&lt;/code&gt;). No raw waveforms are stored.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No sharing.&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;There's no account, no backend, no analytics and no AI service. Nothing goes to me, an employer or anyone else.&lt;/li&gt;
&lt;li&gt;The share card is drawn on the phone and only leaves it if &lt;em&gt;you&lt;/em&gt; tap Share.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retention and deletion.&lt;/strong&gt; Summaries stay until you delete them. You can swipe to delete a single session in History, use &lt;strong&gt;Settings › Delete all sessions&lt;/strong&gt;, or delete the app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network.&lt;/strong&gt; The SDK connects to Presage's servers to authenticate the API key and track usage credits at session start. Measured values aren't part of that.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SDK telemetry.&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Off by default&lt;/strong&gt; (&lt;code&gt;enableTelemetry = false&lt;/code&gt;). You can opt in from the consent screen or Settings.&lt;/li&gt;
&lt;li&gt;If you do, the SDK sends an anonymous per-session diagnostic summary (SDK version, device model, frame-rate and error counts). It never includes video, measured values or identifiers.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not medical.&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;LumiPulse is a wellness and self-awareness toy.&lt;/li&gt;
&lt;li&gt;It makes no diagnosis or treatment claims, and Ready gives no pass/fail or fitness-to-drive verdict.&lt;/li&gt;
&lt;li&gt;Lumi's moods are a playful guess from your expression, and the app says so.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Agent Session
&lt;/h2&gt;

&lt;p&gt;I built LumiPulse in a long session with Claude, from the first SDK wiring and XcodeGen setup, through the Kinetic poster redesign and a Rive face experiment, to Lumi, the native SwiftUI character.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built by Tafadzwa Alexander Razaro · LumiTek Exchange, Gweru, Zimbabwe 🇿🇼&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>presagechallenge</category>
      <category>lumipulse</category>
      <category>claude</category>
    </item>
  </channel>
</rss>
