Skip to content

jkitchin/claude-light

Repository files navigation

Claude light

This repository contains the app code to run a claude-light server and to interact with it through Python.

Usage

Welcome to Claude-Light! You can use this instrument to learn about running remote experiments, analyzing data, automation, design of experiments, and more. The following sections describe several ways you can interact with Claude Light.

The Green machine

The entry level instrument is hosted at: https://claude-light.cheme.cmu.edu/gm

Here you will see a web-form where you can enter the Green LED level, and get a measurement of the 515nm light level, and a picture of the LED during the measurement.

There is only one input, and one output in this machine. This instrument can be used to illustrate reproducibility and statistics, linear regression, optimization and design of experiments.

Recommended exercises

Here are some exercises you could try:

  1. How reproducible is a particular setting? Try running the same experiment many times. Record each result. Make a histogram of the results, and compute statistics like the mean and standard deviation. Does the distribution of measurements look like a Gaussian distribution?
  2. How does your measurement change during the day? The color sensor is exposed to ambient light which changes throughout the day. Experiment with measuring the background with G=0 and subtracting that from your data.
  3. How does the output depend on the input setting? Run experiments at a variety of green levels and plot how the output depends on those levels. It should look approximately linear. Try fitting a line to the data.
  4. Find the input setting that yields an output of 25000 (or other value of your choice).

The RGB machine

The RGB machine has three inputs. You can access it at https://claude-light.cheme.cmu.edu/rgb

The output includes 8 wavelengths of light, and two additional outputs for the total intensity (clear) and near-IR (nir), as well as a picture of the LED during the experiment.

Recommended exercises

  1. Reproducibility across the output channels. Repeat a measurement many times, and copy the data into a spreadsheet. Compute the mean and standard deviations for each channel and compare the results.
  2. Vary one input, and plot how the outputs depend on it.
  3. Use multivariate linear regression to build a model for the inputs and outputs.
  4. Find the input settings that lead to an output of 25000 for the 480 nm, 25000 for the 515nm channel, and 25000 for the 630 nm channel.

The API endpoint

The API endpoint is intended for scripting. You can access it at https://claude-light.cheme.cmu.edu/api.

This returns simple json with input and output. You can pass R, G and B levels as url params, e.g.

https://claude-light.cheme.cmu.edu/api?R=0.1&G=0.3&B=0.2

Here is an API example with curl. You could process this by using jq in a shell if desired.

curl "https://claude-light.cheme.cmu.edu/api?R=0.12&G=0.45&B=1" 

Here is an example where we extract the Green channel at 515nm.

curl -s "https://claude-light.cheme.cmu.edu/api?R=0.12&G=0.45&B=1" | jq -M '.out."515nm"' 

Here is an example with Python. You can use this in a Jupyter notebook, for example.

import requests
resp = requests.get('https://claude-light.cheme.cmu.edu/api',
                    params={'R': 0.12, 'G':0.45, 'B': 1})
print(resp.json())

Recommended exercises

  1. Write a Python script that loops over a range of input values. Save the output in each iteration. Make a plot showing how the output depends on the inputs.
  2. Write a Python script to repeat a measurement many times. Accumulate the results. Plot a histogram of the results, and compute some statistical properties of them.

The Python interface

See https://github.com/jkitchin/claude-light-python for a Python package you can install to control and automate Claude.

Suggested exercises

You can find more exercises at ./exercises.org.

About

Claude Light is a simple instrument inspired by the work of Sterling Baird and Taylor Sparks in these papers:

Claude light has only a few minor variations:

  • I use a REST API instead of MQTT because it is easier (for me) to develop. Specifically, by using flask we can provide a variety of interfaces at different levels of sophistication including a browser interface and API access.
  • I use an ethernet cable because the wifi at school is too secure to connect a PicoW and wired so far is more reliable
  • I use a Raspberry Pi instead of a PicoW because it has built in Ethernet port, and I find it easier to debug since I can ssh into it and it has a display port. The Pi also enables better logging.
  • I use float inputs from 0-1 instead of integers. In the program that runs it, floats are the inputs anyway, and the continuous inputs are easier to introduce in my opinion.
  • With the RPi I can use the full Python language which I am more familiar with than MicroPython, and it has more functionality.
  • I integrated a camera into part of the interface so you can see what color the LED looks like in a measurement. This might one day lead to a computer vision application of claude-light.

Some history of this project

I bought two of the devices developed by Baird and Sparks. These are based on PicoW chips and meant to work on wifi. At my home they work great, but the wifi protocol supported is not well-suited to the wifi at CMU.

I tried an Arduino with Arduino Cloud. This worked ok for me, but I learned there is not a way to share the Arduino cloud dashboard with others unless they have an Arduino cloud account too. This also would need a Wifi solution that isn’t easy.

I got some Arduinos and Ethernet shields for my CMU office. This was going well until I learned I would probably have to write Arduino code to parse the URL for the query parameters. This is too easy in Python, and unfortunately the UNO boards do not run Micropython, so I abandoned this approach.

I got a Raspberry Pi 5 because it has an ethernet port, and it supports full Python. However, The Pi5 made some changes to their GPIO code and hardware, and it is no longer compatible with Rpi.GPIO, so I was unable to use the GPIO for the RGB LED and make I2C measurements. It is possible there was a fix, but I didn’t find it fast enough and decided to go down in versions.

Next, I reverted to a Raspberry Pi 2 I had sitting around where finally everything worked fine.

Finally, I settled on a Raspberry Pi 4 which is the version described here.

The main point of this section is that this is not as easy as it seems. I probably spent 2 months on and off trying all these variations.

Parts list

The instrument is hosted at https://claude-light.cheme.cmu.edu:5000. That url brings you to this page (which is hosted on GitHUB). This section describes the instrument and its parts.

In the end there is not that much to this device.

You need some wires and soldering tools to put it all together.

All together it looks like this:

./claude-air.png

Setting up Claude-light

Register the MAC address

At CMU it is necessary to do this so you can get an IP address.

Setup the Raspberry Pi

This is mostly a one time setup on a new Pi. You have to specify a username and password in this process. I recommend running all the updates. You may want to run raspi-config to update it first.

sudo apt update && apt full-upgrade && apt clean

Maybe this should be done weekly? You can find a script for this at ./update-pi.sh.

You have to enable the I2C interface in raspi-config. I also enable ssh.

sudo raspi-config

Go to interface options, then to I2C to enable it.

Setup and activate a virtual environment for Python

I suggest you run this in ~/. Note the –system-site-packages is important if you want to have the camera on.

python -m venv --system-site-packages .venv

I also recommend add this line to .bashrc so it loads when you login.

source ~/.venv/bin/activate

If not, you have to manually run this.

Install claude

The package is only available on GitHUB. Install it like this.

pip install git+git://github.com/jkitchin/claude-light

Alternatively you can clone and install it locally.

git clone [email protected]:jkitchin/claude-light.git
pip install -e claude-pi

I think this will install all the dependencies and it should also install a cli called claude that will start the app. Normally you would only run this on the Raspberry Pi.

You also have to set up /etc/rc.local to automatically start the server when it boots up. To achieve this, add something like this before the exit 0 line.:

sudo -u jkitchin claude &

It is a little tricky to kill the server. So far I use:

pkill claude

Setup claude as a service

It is desirable to setup the Pi so that claude automatically runs when the Pi starts up, and is easy to restart. The best way to do this is with systemd. We have to create a file like this in /etc/systemd/system called claude.service with these contents. You should adapt this file to use the username on the Pi where claude is installed.

[Unit]                                               
Description=Claude Light server
		                                               
[Service]                                          
Type=simple                                       
Restart=always                                         
RestartSec=1                                        
User=jkitchin                                
ExecStart=/home/jkitchin/.venv/bin/claude                           
ExecStop=pkill claude
	                         
[Install]
WantedBy=multi-user.target  

I use this script to setup, load and enable the service ./setup-service.sh.

sudo systemctl daemon-reload
sudo systemctl enable claude.service

This should result in claude starting on bootup, and if it dies, systemd will try to restart it. You can also stop, start, and restart the service.

sudo systemctl start claude.service
sudo systemctl stop claude.service
sudo systemctl restart claude.service

You can also see the status.

sudo systemctl status claude.service

Use nginx to forward port 80 to 5000

This is not a critical step, but it makes it a little easier to use the url at https://claude-light.cheme.cmu.edu without a port number. I followed the directions at https://engineerworkshop.com/blog/setup-an-nginx-reverse-proxy-on-a-raspberry-pi-or-any-other-debian-os/amp/. Basically, install nginx:

sudo apt install nginx
sudo systemctl start nginx

Then, create /etc/nginx/sites-available/claude-light.cheme.cmu.edu.conf with these contents

server {
	listen 80;
	server_name claude-light.cheme.cmu.edu;
	location / {
	proxy_pass https://claude-light.cheme.cmu.edu:5000;
	}
}

Link it like this:

ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/example.com.conf

and reload nginx

sudo systemctl reload nginx

Roadmap

https - secure http

  • [X] While at this, get port redirection so we can just use the url with no port.
sudo apt-get install certbot python3-certbot-nginx
sudo certbot --nginx  # answer some interactive questions

That seems to actually be it. The certificate was automatically installed, and now you can visit https://claude-light.cheme.cmu.edu/api.

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/claude-light.cheme.cmu.edu/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/claude-light.cheme.cmu.edu/privkey.pem
This certificate expires on 2024-12-14.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

Deploying certificate
Successfully deployed certificate for claude-light.cheme.cmu.edu to /etc/nginx/sites-enabled/claude-light.cheme.cmu.edu.conf
Congratulations! You have successfully enabled HTTPS on https://claude-light.cheme.cmu.edu

An MQTT version

A bluetooth version

Claude-light was built specifically for Internet accessibility. A totally local version would be interesting to learn how to build with Bluetooth and a phone bluetooth app.

wifi

It is probably a good idea to see if we can get a wifi capability. That would provide some portability.

add instrument parameters to API

There are some features in the sensor library we don’t use, e.g. flicker-detection https://docs.circuitpython.org/projects/as7341/en/latest/examples.html#flicker-detection, and some things like atime and gain (https://docs.circuitpython.org/projects/as7341/en/latest/api.html#adafruit_as7341.Gain) that could affect measurements.

We could add these to an api to affect how the measurements are made.

We could also add an optional image to the output

Better camera mount

The camera is somewhat floppy at the moment. It could use a better mount. It is a little tricky to figure out what the best thing to do is though. Maybe a 3-d printed case? or something stiffer that can be bolted down to the PCB.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published