# Notes
## To Do
1. [x] define actions and plan
2. [ ] create setup script
3. [ ] communicate with Meshtastic device via web interface

## Follow up
### Backend
[meshtastic-cli-receive-text](https://github.com/brad28b/meshtastic-cli-receive-text)

### Web app
[flask web app tutorial](https://www.digitalocean.com/community/tutorials/how-to-make-a-web-application-using-flask-in-python-3)

[w3schools How to's](https://www.w3schools.com/howto/default.asp)

## Timeline

### Backend
- Environment setup script in development

### Frontend

### Thoughts
- Play with usbip

To establish a connection between a website and a USB device connected to a Linux server, you cannot directly connect a web application to a USB device over a network using standard web protocols. However, you can achieve this functionality by creating a bridge between the web application and the USB device using a local service on the Linux server. Here’s how:

1. Use USB/IP to Share the USB Device Over the Network: The USB/IP project allows you to share a physical USB device connected to a Linux server over a TCP/IP network, making it appear as a local USB device on a client machine. This is the most direct method for network access.
   - On the Server (where the USB device is physically connected):
     - Install the usbip package.
     - Load the required kernel modules: usbip_core and usbip_host by creating a `.conf` file in `/etc/modules-load.d/` and adding the modules.
     - Start and enable the usbipd.service daemon.
     - List the available USB devices using usbip list -l to find the device's bus ID.
     - Bind the specific USB device to the USB/IP service using usbip bind -b <busid>. This makes the device available for remote access.
   - On the Client (the machine running the web application):
     - Ensure the vhci_hcd kernel module is loaded.
     - List the available devices from the server using usbip list -r <server_ip_address>.
     - Attach the device to the client using usbip attach -r <server_ip_address> -b <busid>. Once attached, the device will appear as a local USB device on the client machine.
2. Integrate the Attached Device with Your Web Application: Once the USB device is attached to the client machine via USB/IP, it will be accessible to any software running on that machine, including a web application. The web application can then communicate with the device using standard USB communication libraries (e.g., libusb for C/C++, pyusb for Python) just as if the device were directly connected to the client machine. The web server (e.g., Apache, Nginx) and the application framework (e.g., Node.js, Django) on the client machine handle the web interface, while the application code uses the local USB device.
3. Alternative: Use a Local Service (e.g., a Web API): Instead of attaching the device to the web server machine, you can create a separate local service (a daemon or a small application) on the server that communicates directly with the USB device. This service can then expose a simple HTTP API (e.g., using a lightweight framework like Flask or Express) that the web application can call to send commands to or receive data from the USB device. This approach keeps the USB device connection confined to the server and uses standard web protocols for communication.

In summary, the most practical approach is to use USB/IP to make the USB device appear as a local device on the machine hosting the web application, allowing the application to interact with it directly through standard USB libraries.

### Troubble Shooting

**usbip: error: could not connect to 192.168.1.8:3240: System error** adjust firewall? `vhci_hcd` on client machine?

So for the daemon - /etc/systemd/system/usbipd.service
```
[Unit]
Description=usbip host daemon
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
Restart=always
ExecStartPre=/usr/sbin/modprobe usbip-core
ExecStartPre=/usr/sbin/modprobe usbip-host
ExecStart=/usr/sbin/usbipd
ExecStopPost=/usr/sbin/rmmod usbip-host
ExecStopPost=/usr/sbin/rmmod usbip-core

[Install]
WantedBy=multi-user.target
```

And the template for the binds - /etc/systemd/system/usbip-bind@.service

```
[Unit]
Description=Bind USB device to usbipd
After=network-online.target usbipd.service
Wants=network-online.target usbipd.service

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/usbip bind --busid %i
ExecStop=/usr/sbin/usbip unbind --busid %i

[Install]
WantedBy=multi-user.target
```

Enable and start the daemon with:
```
systemctl enable usbipd
systemctl start usbuipd
```

Then add binds with:

```
systemctl enable usbip-bind@1-1.2.3
systemctl start usbip-bind@1-1.2.3
```
Replace 1-1.2.3 with the bind id of the USB device you want to share. You can use as many of these as devices you want to share and you can then bind and unbind each one individually and have then bind at machine startup (or not).

Find the bind ids with:

`usbip list -l`
Note that usbip binds seem to expire if not attached by a remote machine within around 10 mins - not very helpful!

I haven't yet decided how I'm going to tackle the client attach, possibly not with systemd. It would be really helpful if usbip had a bit more intelligence...