Categories
raspberrypi technology virtualreality

Control your Raspberry Pi 5 from your Meta Quest 3 over Bluetooth

The Meta Quest 3 is capable of so much since it is an Android based device and can leverage the existing Android app ecosystem – if you know how to do it! Let’s control our Raspberry Pi 5 from within virtual reality over Bluetooth.

Keep in mind that using Bluetooth to pair these two devices limits our ability to connect from a physically distant location. I personally prefer this since exposing it over say, SSH, would open it up to potential exploits over the Internet. I personally wouldn’t trust an SSH private key to an Android app – if you see one asking you for that, I would recommend against using it. For my use case, Bluetooth works perfectly well since I always use my Pi when I’m in close proximity to my Quest.

Disclaimer:

In this tutorial I endorse the use of Bluedot, an Android app by the tech rockstar Martin O’Hanlon. The app is MIT licensed which means you are free to use it for private or commercial use, and you can even distribute it, but you don’t have any warranty or liability claims when using it.

Prerequisites:

  • Follow this video tutorial or this pdf tutorial and have SideQuest downloaded, installed and connected to your Quest 3. Note that you will need the “advanced” version of SideQuest in order to install apk files not distributed by the SideQuest store.
  • You will need to download the apk file from the Bluedot Github repository – click here for the direct download link, or here for the repository link
  • You should be familiar with how to sideload an apk file (not from the SideQuest store). See page 7 of the pdf tutorial for a refresher
  • Raspberry Pi 5 with appropriate accessories
    • an SD card with the Raspberry Pi OS and enough space for this exercise – 50 GB or more should be plenty
    • a power supply that outputs 27W that connects via USB-C
    • a micro HDMI cable with an output compatible with a monitor of your choice
    • a mouse and keyboard that can connect via USB type A (the standard big type) or Bluetooth

If you are brand new to the Raspberry Pi, there is a great “Getting Started” tutorial at https://www.raspberrypi.com/documentation/computers/getting-started.html . This tutorial assumes you have already gone through these steps and have your Pi powered, booted up, configured with your login details, and connected to Wifi .

Steps:

  1. Sideload the Bluedot apk onto the Meta Quest 3

2. Boot up your Pi and ensure that Bluetooth is enabled – on mine it came up enabled automatically.

3. Create a Python script on your Pi to listen for Bluedot button presses. Here is a simple one from the Bluedot docs that says “Hello World” when the button is pressed

from bluedot import BlueDot
from signal import pause

def say_hello():
    print("Hello World")

bd = BlueDot()
bd.when_pressed = say_hello

pause()

4. Install the dependencies bluedot and signal, using a virtual environment as described in this tutorial. Keep in mind that using pip to install packages in the Pi environment directly may break system packages.

5. Run the Python script on the Pi. Unless this script is active and running Bluedot on the Pi will not be able to pair with the Bluedot app on the Quest 3

(myenv)pi@raspberrypi:~ $ python3 myrecipe.py

6. Back on the Quest, turn on Settings > Bluetooth. It should automatically begin scanning for available devices

7. On the Pi, click the Bluetooth icon and click “Make Discoverable”.

The icon should begin flashing

8. On the Quest you should see “raspberrypi” as an available device. When you click it, it will give you a pairing code. Back on the Pi, click the pop-up for pairing. On the Quest, click “Pair” as well. I found it easier to click the pairing pop-up on the Pi first and then on the Quest. If you happen to do it in the reverse order clicking “Pair” on the Quest first, you will need to click “Stop Discovery” on the Pi to get it to recognize the pairing.

The Quest and Pi should be paired via Bluetooth at this point.

9. Open the Bluedot app from App Library > Unknown Sources

10. Select the raspberrypi from the list of devices.

It should pop up with a screen that says “Connected” and a big blue dot

11. Click the dot, and check the Pi to see if it says “Hello World”

12. If it does, congratulations, you have connected your Quest 3 to your Pi 5!

In this tutorial we learned how to connect a Raspberry Pi 5 to a Quest 3 over Bluetooth, and click a button to execute an action on the Pi from with virtual reality.

Enjoy!

Categories
raspberrypi technology virtualreality

Adventures with Immersed VR on the Pi 5

Raspberry Pis are cool. Virtual Reality, also cool.

Let’s make a Raspberry Pi Virtual Reality coolness sandwich!

To be clear, this tutorial is about getting an Immersed VR virtual monitor working with the Pi 5. It is NOT about running a VR simulator with the Pi 5 – if you want that you can get some guides with a Google search on “DIY VR on raspberry pi.”

Disclaimer:

This tutorial makes use of a prototype build compatible with the Raspberry Pi which the Immersed VR team made available to me through Discord. It is not yet available on their downloads page and may not be compatible with all headset/raspberry pi combinations. YMMV.

Shout-Out:
This tutorial would not have been possible without the inspiring work done by Augusto Ícaro . Check out https://github.com/augustoicaro/Immersed-Linux-Virtual-Monitors and be prepared to go ooooh-ahhhhh 🙂

Prerequisites:

  • An Immersed VR account – their free starter mode should work, although you can also earn Pro by using Immersed in starter mode minimum 3 out of 7 days. More on that at https://immersed.com/faq#how_to_unlock_pro_mode
  • Access to the Immersed VR Discord – invite available at https://discord.com/invite/zy6KMbJ – in order to request and download the prototype build. Check out the #linux-help channel for the download and any assistance you might need
  • Headset compatible with Immersed VR – you can see their compatibility statement at https://immersed.com/faq under the “Compatibility” heading
  • Raspberry Pi 5 with appropriate accessories
    • an SD card with the Raspberry Pi OS and enough space for this exercise – 50 GB or more should be plenty
    • a power supply that outputs 27W that connects via USB-C
    • a micro HDMI cable with an output compatible with a monitor of your choice
    • a mouse and keyboard that can connect via USB type A (the standard big type) or Bluetooth
  • Wifi connectivity – Immersed VR works over your wifi network. Both the Pi and the headset should be connected to the same wifi network.
    ** Note that it is advisable to use a private wifi network rather than a public one, since public ones are vulnerable to hacking and could result in your session being compromised

If you are brand new to the Raspberry Pi, there is a great “Getting Started” tutorial at https://www.raspberrypi.com/documentation/computers/getting-started.html . This tutorial assumes you have already gone through these steps and have your Pi powered, booted up, configured with your login details, and connected to Wifi .

All the following steps should be executed on the Pi itself, except for the scp command which would be from a separate computer.

Steps:

  1. Download the app image from the Discord #linux-help Immersed VR channel to your Pi. If you don’t want to install Discord on your Pi, you can also download it on a separate computer that has Discord and use secure copy (scp) to transfer it to the Pi
    To use this second method, first copy your main computer’s public ssh key to the Pi as ~/.ssh/authorized_keys. A sample scp command to do this would be:
scp -i mylaptop_private_ssh_key /Users/mylaptopuser/Downloads/Immersed-aarch64.AppImage mypiuser@192.168.1.165:/home/mypiuser/Downloads

2. Once the App Image is on the Pi, grab the Linux setup script

wget https://raw.githubusercontent.com/augustoicaro/Immersed-Linux-Virtual-Monitors/main/scripts/immersed-setup/immersed-setup.sh

3. This script assumes your app image is in /home/mypiuser/Applications. Either create that directory and move both the setup script and the app image into that directory, or modify the setup script to find these resources wherever you want them to live.

4. Modify the setup script to use the App Image you downloaded. I had to replace “x86_” with “aarch”. A sample command to do this is:

sed -i -e 's/x86_/aarch/g' ~/Applications/immersed-setup.sh

5. Make the setup script executable

chmod a+x ~/Applications/immersed-setup.sh

6. Put your Applications directory on your PATH by adding this export line to your .bashrc file and then sourcing it to load it in your terminal.

echo -n "export PATH=$PATH:$HOME/Applications" >> ~/.bashrc
source ~/.bashrc

7. Install additional packages and make a symbolic link for libwlroots. Note that these versions are specific to the 10.3.2 version of the App Image and may change when this is updated.

sudo apt install -y libfuse2 libwebkit2gtk-4.0 libva2 libva-drm2
sudo ln -s /usr/lib/aarch64-linux-gnu/libwlroots.so.11 /usr/lib/aarch64-linux-gnu/libwlroots.so.5

8. Adjust the ~/.ImmersedConf file to setup your v4l2 camera device (to enable the virtual webcam feature). Use the Text Editor to find the line that starts with “CameraDevice” and adjust it to read like so:

CameraDevice=/dev/video7

8. Run the immersed-setup.sh script from the Applications directory.

cd ~/Applications
./immersed-setup.sh


This script may end with an error similar to this:

modprobe fatal module card_label=Immersed not found in directory /lib/modules/6.6.31+rpt-rpi-2712

If so not to worry, it means the v4l2loopback module hasn’t loaded into your current session. The v4l2loopback module relates to the webcam functionality.

To load the module, restart your Pi with shutdown now -r or by hitting the power button, letting it power off, and hitting the power button again.

9. At this point you should be able to run the setup script and not get any errors. Now it’s time to run the app image!

cd ~/Applications
./Immersed-aarch64.AppImage

Depending on what happened with the v4l2loopback module, the app image may generate a pop-up prompting you to install a few more dependencies. If so not to worry, we already installed these in step 7, so you can click “Do not display again” on these.

At this point you should be able to sign in with your Immersed VR account and pair the VR app with the Pi. The pop-up should say “Agent Ready” when it is available for the VR app.

10. In the VR app, select “Computers” and click the “raspberry pi” option. It should connect after a few moments. If it does not connect right away, try stopping the AppImage with Ctrl + C and re-run it.

11. View your fancy new monitor in VR!

OCULUS_ATTRIBUTION_ID:9279578942068913–

Congratulations! You now have the ability to connect to your Raspberry Pi 5 in virtual reality!

If you have any questions or get stuck, feel free to ping in the #linux-help channel of the Immersed VR Discord and we’ll see what we can do!

Categories
devops

Celebrating 10 Years in Cloud Engineering

The year was 2014 and I was working at Internet of Things startup Axeda (later acquired by PTC). I was building prototypes of Internet of Things solutions using the Axeda platform, and this particular one needed a UI, customer facing component. My manager suggested using an EC2 instance on AWS, which I had never tried before. I went through the flow of choosing an AMI, tweaking the knobs, and launching it. The invisible computer appeared!

That very year, the first annual State of DevOps report was released Nicole Forsgren, Gene Kim, Jez Humble and others. After the acquisition of Axeda, I applied for my first “DevOps Engineer” job and worked at Teradata automating the provisioning of flavors of Hadoop clusters across various clouds. Although SRE would later become known as the “implementation of class DevOps”, I always preferred to consider myself working in DevOps as that embodied to me the principle of bridging gaps between siloed developers and ops engineers.

At Acquia, I was able to mature my engineering experience to encompass Enterprise-grade practices. I worked with compliance concerns, went on call for the first time, and used Puppet to automate complex tasks. However at that time they did not offer a DevOps career track, so I transitioned into a full time DevOps role at Tomorrow.io (formerly ClimaCell).

It was at Tomorrow.io that I was able to find my sweet spot of working with Kubernetes on a daily basis, adopting Terraform and Helm as orchestration go-to tools. I used GitOps to ensure that the state of the deployment always matched the code, and hooked it all up to a Gitlabs pipeline for on demand releases.

The basis for my current work at Sensible Weather relies on the foundation laid by my combination of Enterprise and Start-up experience. I have the depth to understand how mature companies need to work, and the breadth to implement solutions tailored to the particular challenges of a growing org.

Ultimately, I am extremely grateful for the opportunity to enjoy meaningful work that remains fresh and interesting to this day.

Here’s to another ten years!

Categories
devops

Eliminating NaNs in PromQL Histogram Quantile

Working with Prometheus and PromQL can be tricky. I found it challenging to define an SLO using sloth-sli for a service whose histogram had a lot of NaN (Not a Number) values. I searched around for an out of the box solution and didn’t find what I was looking for.

The key to the solution was the knowledge that in PromQL an NaN doesn’t equal itself: NaN != NaN.

With this in mind I could use the “unless” operator to filter out any value that didn’t equal itself.

p50 Latency Error Query

histogram_quantile(0.5, sum(rate(http_request_duration_seconds_bucket{job="$job", namespace="$namespace"}[{{.window}}])) by (le)) > 5 unless (histogram_quantile(0.5, sum(rate(http_request_duration_seconds_bucket{job="$job", namespace="$namespace"}[{{.window}}])) by (le)) != histogram_quantile(0.5, sum(rate(http_request_duration_seconds_bucket{job="$job", namespace="$namespace"}[{{.window}}])) by (le))) OR on() vector(0)



This query returns the 0.5 bucket values that are over 5, and if the values that it evaluates do not equal themselves (i.e., are NaNs), it turns those into nulls. The nulls are evaluated to false (while the NaNs are evaluated to true) and then OR’ed with the vector 0 to create a consistent graph with no gaps.

Hope this tidbit helps someone, SLOs are hard enough as it is without NaNs in your life!

Categories
devops

Startup Life with DevOps at Sensible Weather

During my time so far at Sensible Weather, I’ve built an infrastructure pipeline which moves code from Github to an EKS cluster via Argo CD, a project lovingly named Margaritaville, since once you’re done with it you can go sip margaritas … 🙂 This project leveraged Terraform in Github Actions to deploy Helm applications onto the cluster. The only gap here was the management of secrets, which I initially deployed using Velero as a stopgap. Velero is a powerful tool which allows you to back up Kubernetes resources from a cluster and then restore them either to the same or a different cluster. Using it for secrets management didn’t make sense in the long term however, so as soon as I was able I migrated us to the External Secrets project, which enables the syncing of Kubernetes secrets to an external secrets provider. In this case we used AWS Parameter Store since we didn’t need cross-region or cross-account secrets sync ( and hey, free ).

Once this was all set up we needed centralized metrics, logging, and tracing, so I made use of the excellent Grafana open source LGTM stack . I used Pomerium to provide SSO for these tools which I covered in a post featured on Sensible Weather’s official blog.

Next steps – setting up an official on call with integrations into our comms. #StartupLife !

Categories
devops

DevOps at ClimaCell

I joined ClimaCell as a Senior DevOps Engineer in January.  I love it!  I am working in Terraform spooling up Kubernetes infrastructure as well as using Helm to bootstrap applications.

JAJ is learning her letters and walking around opening doors wherever she can.  Super proud of her.

Categories
family

New Arrival

We welcomed our newest family member in late July – JAJ, already a smart and expressive little girl.  She hasn’t seen much yet but Mom and Dad are counting the days til she can enjoy the local greenery and other attractions.  So far she has gotten a quick visit to a family farm stand – sneak preview of a much bigger world!

 

 

Categories
devops scrum

Scrum Master Class

I have a new mission at Acquia – I am taking over as Scrum Master for my team. Bwahahahaha …

I’ve been doing Scrum ever since I started in tech full time at Axeda. Stand-ups and sprints are all old hat, but for the first time thanks to Acquia, I have received formal training in Scrum and a certification from Scrum Inc in Boston.

board
Scrum Inc.

Effectiveness
How does Scrum help? Why do it?

You use Scrum because you want to improve team velocity without increasing team resources.

I liked the fact that the Scrum Master class itself was organized as a Sprint using Scrum. This let us “live the example” and see first-hand the effectiveness of the techniques.

History
What is Scrum? What is its relationship to Lean and Agile?

Scrum is different from Lean and Agile but it derives from both. It came about as an evolution in workflow process based on techniques pioneered at Toyota. Scrum is an adaptation of manufacturing floor process to software engineering.
Lean

  • Eliminate waste
  • Understand Value Stream Analysis
  • Implement Single Piece Continuous Flow

Agile competition – rapid prototyping and fail fast mentality, permit the customer to determine what the product will be jointly with the producer

Requirements
What do you have to have and do in order to be doing Scrum authentically?

In order to do authentic Scrum, you must satisfy these requirements – these particular 3 artifacts, 5 events, and 3 roles as part of the team’s process.

3 Artifacts

  • Product Backlog – vision, priorities
  • Sprint Backlog – known work, capacity
  • Product Increment – scrum board, burndown, velocity

5 Events

  • Backlog Refinement
  • Sprint Planning
  • Daily Scrum
  • Sprint Review
  • Retrospective

3 Roles

  • Product Owner
  • Scrum Master
  • Team

Values
What do these workflow philosophies consider worthwhile?

Scrum inherits values from Agile. The five values of scrum are focus, courage, openness, commitment and respect.
Agile Manifesto

  • Individuals and interactions over processes and tools
  • Working software over comprehensive documentation
  • Customer collaboration over contract negotiation
  • Responding to change over following a plan

Happiness is important because it is a precursor to great team performance and high velocity. Team velocity will predictably go down after happiness does. Scrum practice works to improve happiness by relying on intrinsic motivators over external ones – purpose, mastery, and autonomy over money, power and status. The workplace should ensure the external rewards are present to the extent that they are no longer preoccupying thought, but the flow of the team should emphasize those internal motivators over the external ones.

Best Practices
What are the best practices included in Scrum that help the teams that adopt them?

There were numerous best practices discussed during the class.  The first one that I’ll be introducing to my team is the observance of strict scrum rules during our standup.

During our standup, we will kick it off with a short inspirational music clip and physically stand up to report our answers to “What did you do yesterday”, “What will you do today” and “What are your impediments if any.”

Since we are a remote team doing our standup over a call, we will determine the order of statuses according to the order that the team members join the call. Since not everyone joins right at 10:30, the standup will start at 10:35, and the first five minutes will be used for team sync and/or a single ticket triage. At 10:35 the alarm goes off, and the team gets up for standup! Post scrums optional, anyone with a post scrum says who they need and everyone else should drop off.

One further thing I learned that I will mention is about measuring velocity. While you can’t compare velocity across teams, you can compare acceleration. Subtle but important.

Terminology
What Scrum terminology provides useful ideas?

Kaizen (evolution) and Kaikaku ( revolution).Kaikaku means the philosophy of challenging entrenched dogma, refusing to accept waste no matter how it is disguised

Forms of waste

  • Muda – work in progress but not finished
  • Mura – inconsistency
  • Muri – unreasonable demands

Types of Waste and their Mnemonic
DOWNTIME – Defects, Overproduction, Waiting, Not utilizing talent, Transportation, Inventory, Movement, Extra processing

“Don’t take my word for it” – any change we make should have a follow up to ensure that the data proves the change is helping team velocity

JJ Sutherland, Alex Sheive, Sara Jarjoura
JJ Sutherland, Alex Sheive, Sara Jarjoura

All in all, I had a fantastic time and learned a ton. I am stoked to bring this to the team and see how we do.

Sara Jarjoura-ScrumAlliance_CSM_Certificate
Certified Scrum Master

Categories
Uncategorized

First On Call And It Was Fun

This week I went on call for the first time at Acquia and it was actually a lot of fun. As a Cloud Engineer, I’m on the escalation path for issues with our Amazon services – an example would be something goes wrong with an Amazon instance, I put in the ticket to Amazon customer support and handle its resolution.

What’s fantastic is that we have 24 hour support, but I am only on call during my work hours. Our support shifts and on call rotation “follow the sun.” I have colleagues on my team who work in Europe and Australia. In the morning (from my perspective) my European colleague passes the shift to me, and in the evening I pass the shift to my Australian colleague. Neat!

One of my buddies on the team is taking a vacation that happened to have an on call week right in the middle. I am enjoying it so much that I volunteered to take his shift. Looking forward to getting more exposure to the “hot seat” – so far so good!

Categories
code devops geek

Resiliency and Game Day Exercises at Acquia

In March of 2017 I came across the idea of “Game Day” in the DevOps Handbook by Gene Kim and others. Game Day is brilliantly advocated by Jesse Robbins in his presentation from 2011. It’s the idea that deliberately staging periodic system outages forces engineers to think about and design for resiliency in those systems. The extreme programming example is Chaos Monkey, which operates under only the one constraint that the outages should happen during working hours. Other than that, the outages caused by Chaos Monkey can happen anywhere in the system (even production!) and at any time.

Game Day is a step removed from Chaos Monkey, conceived of as a planned activity for engineers to resolve systemic outages. The resiliency exercises held at Acquia were yet another step away from the extreme towards the approachable. Our exercise included two activities, one geared for non-support engineers and the other for support. The non-support engineers had to bring back up a down site, and the support engineers had to attack and compromise an insecure site. The idea was to challenge engineers to step outside their comfort zone, and attempt to resolve technical challenges beyond the requirements of their every-day work.

The Team
The personalities involved in Game Day were a strong influence on the event. There’s Amin Astaneh, an Ops manager with the temperament of the proverbial town crier, faithfully and urgently supporting us in our DevOps transformation. Then there’s Apollo Clark, expert in secure systems who contributed the idea of doing a security vulnerability exercise. Finally there’s James Goin, seasoned Ops warrior relentlessly invested in the improvement of systems administration, including resiliency and disaster recovery training.

Constraints
It just so happened that the idea for Game Day came two months in advance of Acquia’s annual engineering-wide event called Build Week, a truly awesome gathering of the entire team at Acquia HQ in Boston (read more on Dries’ blog!). Holding our Game Day at the same time would allow it to reach a broader audience across the company, so we requested a slot on the calendar. We ended up with 8-9pm on the Tuesday during Build Week. We had our opportunity!

Build Week imposed two constraints that had a significant and positive influence on our interpretation of Game Day. The whole event needed to fit in a single hour, and the event had to be accessible to engineers other than just the Ops subject matter experts. A Game Day exercise typically involves only the core engineering team which works directly with critical systems, and it takes however long they need to bring the systems back up. These constraints made the whole thing more approachable, and inspired the introduction of an Easy Mode and a Hard Mode.

Game Day as Exercise
The original idea was to have a trouble-shooting session with an Acquia development installation of a Drupal site (managed Enterprise-grade Drupal being the chief product of Acquia). The site would have some failure that either smaller teams or the whole group would have to resolve. Since we needed to accommodate varying levels and areas of expertise in the product, we settled on two “modes”, Easy Mode and Hard Mode, that participants would opt into based on their familiarity with troubleshooting techniques. The difference between the modes would only be in the level of difficulty. Easy Mode would be for those who don’t handle troubleshooting support calls as part of their regular day-job, Hard Mode for those who do.

The Identity Crisis
At this point, it hit home for me that the exercise was not going to be what I had originally intended – it wasn’t going to be a cookie-cutter Game Day. Although this seemed disappointing at the time, looking back it was a blessing in disguise, since it motivated us to create a new idea instead of copying someone else’s.

Apollo’s suggestion which we ended up following was to stage a Hard Mode Capture the Flag exercise instead of a site outage. Capture the Flag in a security context is an exercise where teams gain access to privileged resources in a system by leveraging security vulnerabilities. We could hide hashes – randomized strings of a fixed length – throughout the site. The winner of the competition would be the team that found all the hashes first.

The exercise would demonstrate that a site that works from a user perspective can still need work to become secure and performant. We would have Easy Mode to include some troubleshooting, which would then flow directly into the Capture the Flag exercise.

Trying It Out
We ran through the whole event a few weeks before Build Week. Easy Mode troubleshooting took up the first half hour, transitioning to Hard Mode Capture the Flag for the second half hour. This was pure thought experiment at this stage, and shockingly for me, it worked really really well.

During Easy Mode, non-Ops engineers drove the resolution with Ops experts only acting as consultants. Once the site was back up, we switched over to Capture the Flag. For this run through we only had one shared site for all the Hard Mode participants. One mischievous participant who found the site credentials deliberately locked out everyone else. This incident motivated much of the end-game setup for prevention of cross-site hacking.

Game Day!
Our Game Day-inspired exercise followed the flow established in our run through, with the addition of the isolated environments for Capture the Flag.

The Easy Mode troubleshooting took less time than we had allowed for, putting the start of Hard Mode right on time. The teams dove in, probing their environment – a Drupal site – for weaknesses. The narrative revolved around a fictional user submitting a question to the forum about how to enable the PHP module in Drupal, which would allow access to the bash shell on the server. The fictional admin replied that she had enabled the module for him, and reset his login to a “temporary password”. These were the credentials the participants were expected to use to hack the site. Since the user had access to the PHP module, they could also use it to gain shell access. Using this shell access to the server, they had easy access to the privileged resources and opportunities to discover the hashes.

When time ran out at 8:55, three of our twelve teams and forty participants had found all five of their hashes. The first team with all five hashes won the grand prize, an invitation for morning coffee with our resident tech celebrity, Drupal founder and Acquia CTO Dries Buytaert. As an aside, when I thanked Dries for agreeing to have coffee with our winners, he graciously replied, “No, thank you – now I get to have coffee!”

Epilogue
The decision to pivot from the established Game Day resulted in a new kind of learning in the spirit of Game Day. This learning was more accessible for our engineers and bridged the gap between where we are and where we are headed. While this isn’t the end of the story, I think it’s a fantastic start. Game Day, Day 2, here we come …