When the app is told to make it snow it adds full-screen non-interactive windows on each display and inside those windows adds a SpriteKit view with a scene inside that contains emitters.
Thanks to Whisper and this awesome port, the tree is responding to spoken words. 🗣🎄
Since the tree itself only has a low-powered MCU, we need another machine to act as a listener.
The architecture is:
A machine in my office runs the Whisper model and listens for words.
If certain keywords are found it finds a corresponding command to run (e.g. do a theater chase sequence in a green color).
It sends that command to the tree over the network.
For now I’m running it from iOS and macOS, so I wrote the current implementation in Swift. The code is currently still in “hack” status, but working well!
Now it’s time to test it when talking to coworkers at Automattic.
Thanks to this repo you can fire up Windows 3.11 painlessly and even connect to the Internet! Lots of goodies are already installed so it’s a fun virtual trip.
There were some graphical glitches (restarting or dropping down into DOS and back helps) and it crashes when running Netscape, but Microsoft Bob seemed to work fine!
Something I should’ve done long ago – enabling OTA (Over The Air) firmware updates so I don’t have to disassemble the project box and move the tree every time I want to change its code.
struct ChristmasTree: View {
var body: some View {
ZStack {
// draw the tree trunk
Rectangle()
.fill(Color.brown)
.frame(width: 20, height: 100)
// draw the tree branches
ForEach(0..<5) { i in
HStack(spacing: 5) {
ForEach(0..<5-i) { j in
Triangle()
.fill(Color.green)
.frame(width: 10, height: 10)
}
}
.offset(x: 0, y: -10 * CGFloat(i))
}
// draw the star on top of the tree
Circle()
.fill(Color.yellow)
.frame(width: 10, height: 10)
.offset(x: 0, y: -50)
}
}
}
The only major issue syntax-wise is that Triangle() isn’t defined – where did it get that?
A quick visit to Hacking with Swift had this nice snippet, which I dropped in.
This weekend the NeoPixel tree got many much-needed updates!
Though I have more ideas to implement, the basics of what I wanted to do are complete, like sending commands remotely.
What we can currently do:
Set the brightness
Change the color
Turn the pixels off
Run some built-in sequences, like a nice rainbow
Set repeating color patterns
Set individual pixels
I also threw together a really quick iOS app to set the color with SwiftUI’s built-in ColorPicker view. Thanks to the Rover project (another one that’s been neglected), I had some UDP client code I could borrow to speed up development.
Connect it wirelessly to the network (it has an ESP8266, after all)
Run a UDP server on it
Respond to various commands
Write a client that sends UDP packets to it
It’s fun to design UX for limited hardware. In this case, the tree starts with an orange pattern that rotates until a WiFi connection is successful. If it fails the tree will go red, otherwise the tree briefly goes green to let the end user know all is well before starting its first sequence.