mirror of
https://github.com/cimryan/teslausb.git
synced 2026-02-28 20:20:32 +00:00
36
GetShellWithoutMonitorOnWindows.md
Normal file
36
GetShellWithoutMonitorOnWindows.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Seting up the Pi without a monitor using Windows
|
||||
1. Download and install: [Notepad++](https://notepad-plus-plus.org/) Alternatively, any other text editor which is capable of editing files with Unix-style line endings.
|
||||
1. Optional: Watch [this video](https://www.youtube.com/watch?v=xj3MPmJhAPU) to get an idea of the process. The steps from the video are partially automated, below.
|
||||
1. Remove the MicroSD card from your computer and reinsert it. Do not at any point during the setup of the USB drive allow Windows to format any partition on any drive.
|
||||
1. Note that a new drive labeled "boot" has appeared on your computer. Note the drive letter of that drive.
|
||||
1. Right-click on your Start menu icon and select "Windows PowerShell (Admin)".
|
||||
1. Right-click the title bar of the window and select "Properties". Ensure that the "Use legacy console" checkbox is unchecked and activate the OK button. If it was checked before you unchecked it, close te PowerShell window and go back to step 3. If it wasn't, proceed onto the next step.
|
||||
1. Run the following command:
|
||||
> Note: You can paste into the PowerShell window by right-clicking. The text will appear at the position of the cursor, not necessarily at the position where you click.
|
||||
```
|
||||
Set-ExecutionPolicy -Scope CurrentUser Unrestricted
|
||||
```
|
||||
1. Enter Y when prompted, and press Enter.
|
||||
1. Run the following commands:
|
||||
```
|
||||
cd ~
|
||||
wget https://raw.githubusercontent.com/cimryan/teslausb/master/windows_archive/setup-piForHeadlessConfig.ps1 -OutFile setup-piForHeadlessConfig.ps1
|
||||
./setup-piForHeadlessConfig.ps1 -Verbose
|
||||
```
|
||||
1. Enter the single letter of the "boot" drive and press Enter.
|
||||
1. Eject the sd card.
|
||||
1. Move the sd card to the Pi.
|
||||
1. Connect a micro usb cable to the port labeled "USB" on the Raspberry Pi, and to the PC.
|
||||
1. On the PC, press your Windows key, type Control Panel.
|
||||
1. Open "Network and Sharing Center"
|
||||
1. Click "Change adapter settings"
|
||||
1. Wait for something labeled "USB Ethernet/RNDIS Gadget" to appear.
|
||||
1. Enter this command in your PowerShell window:
|
||||
```
|
||||
ssh pi@raspberrypi.local
|
||||
```
|
||||
1. If you get an "unknown host" error message install Bonjour: https://support.apple.com/kb/DL999 and go back to step 15.
|
||||
1. You should be prompted for the password for the user "pi". Enter
|
||||
```
|
||||
raspberry
|
||||
```
|
||||
8
GetShellWitoutMonitorOnLinux.md
Normal file
8
GetShellWitoutMonitorOnLinux.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# Seting up the Pi without a monitor using a Mac or Linux
|
||||
Basically what you're doing is using the Pi's capability to emulate a network connection over USB. So you need to get the Pi (the guest) set up to load the proper modules to do so, and then connect from your machine (the host) using a shell (like iTerm+SSH on macOS).
|
||||
|
||||
Here are a few ways to accomplish this
|
||||
* [Gist (text file) showing example steps and discussion thread about issues, etc](https://gist.github.com/gbaman/975e2db164b3ca2b51ae11e45e8fd40a)
|
||||
* [Script to setup the Pi for connecting over USB](https://github.com/BigNate1234/rpi-USBSSH)
|
||||
* (I.e. First write the OS image to the SD card, then this script will make the changes to the card so you can boot it and access it over the USB cable.
|
||||
* **Assumes the SD card for the Pi is mounted at /Volumes/boot , and that you can use `sh`/`bash`**. This _should_ be the default for a Mac; if using something else, modify the script accordingly.
|
||||
217
README.md
217
README.md
@@ -7,12 +7,6 @@ This repo contains steps and scripts originally from [this thread on Reddit]( ht
|
||||
|
||||
The original post on Reddit assumed that the archive would be hosted on Windows and that the Pi would be set up using a Windows machine but this Git repo welcomes the contribution of instructions for other platforms.
|
||||
|
||||
TODO/Asks
|
||||
|
||||
* Script to make this easy to get going. Ideally supports multiple targets (see further TODO/Asks)
|
||||
* Copy to AWS S3 / Google Drive / Etc
|
||||
* Copy to SSH/SFTP
|
||||
|
||||
## Intro
|
||||
|
||||
You can configure a Raspberry Pi Zero W so that your Tesla thinks it's a USB drive and will write dashcam footage to it. Since it's a computer, you can run scripts on the Pi to automatically copy the clips to an archive server when you get home. The Pi is going to continually:
|
||||
@@ -21,7 +15,7 @@ You can configure a Raspberry Pi Zero W so that your Tesla thinks it's a USB dri
|
||||
1. Wait until it can't connect to the archive server
|
||||
1. GOTO 1.
|
||||
|
||||
Disclaimer: It hasn't been confirmed that this solution will work with v9 of the Tesla software. It has been verified that when files are present in the TeslaCam directory they are archived to a server when the car gets back on the wireless network.
|
||||
The scripts in this repo will also allow you to use the Pi to store music that the Tesla can read through the USB interface.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@@ -35,6 +29,8 @@ Disclaimer: It hasn't been confirmed that this solution will work with v9 of the
|
||||
|
||||
Required:
|
||||
* [Raspberry Pi Zero W](https://www.raspberrypi.org/products/raspberry-pi-zero-w/): [Adafruit](https://www.adafruit.com/product/3400) or [Amazon](https://www.amazon.com/Raspberry-Pi-Zero-Wireless-model/dp/B06XFZC3BX/)
|
||||
> Note: Of the many varieties of Raspberry Pi only the Raspberry Pi Zero and Raspberry Pi Zero W can be used as simulated USB drives. It may be possible to use a Pi Zero with a USB Wifi adapter to achieve the same result as the Pi Zero W, but this hasn't been confirmed.
|
||||
|
||||
* A Micro SD card, at least 8 GB in size, and an adapter (if necessary) to connect the card to your computer.
|
||||
* A USB A/Micro B cable: [Adafruit](https://www.adafruit.com/product/898) or [Amazon](https://www.amazon.com/gp/product/B013G4EAEI/)
|
||||
|
||||
@@ -48,8 +44,6 @@ Optional:
|
||||
* A case. Don't want unprotected circuits hanging about! Official case at [Adafruit](https://www.adafruit.com/product/2885) or [Amazon](https://www.amazon.com/gp/product/B06Y593MHV). There are many others to choose from. Note that the official case won't work with the USB A Add on board.
|
||||
* USB Splitter if you don't want to lose a front USB port. [The Onvian Splitter](https://www.amazon.com/gp/product/B01KX4TKH6) has been reported working by multiple people on reddit.
|
||||
|
||||
> Note: Of the many varieties of Raspberry Pi only the Raspberry Pi Zero and Raspberry Pi Zero W can be used as simulated USB drives. It may be possible to use a Pi Zero with a USB Wifi adapter to achieve the same result as the Pi Zero W, but this hasn't been confirmed.
|
||||
|
||||
### Software
|
||||
Download [Raspbian Stretch Lite](https://www.raspberrypi.org/downloads/raspbian/)
|
||||
* Note: Bittorrent is dramatically faster than direct download.
|
||||
@@ -60,9 +54,10 @@ Download and install:
|
||||
|
||||
## Create your archive
|
||||
### Hosting on Windows
|
||||
Set up a share on a Windows machine to host the archive. These instructions assume that you created a share named "SailfishCam". It is recommended that you create a new user. Grant the user you'll be using read/write access to the share. These instructions will assume that the user you've created is named "sailfish" and that the password for this user is "pa$$w0rd".
|
||||
Set up a share on a Windows machine to host the archive. These instructions assume that you created a share named "SailfishCam" on the server "Nautilus". It is recommended that you create a new user. Grant the user you'll be using read/write access to the share. These instructions will assume that the user you've created is named "sailfish" and that the password for this user is "pa$$w0rd".
|
||||
|
||||
Get the IP address of the archive machine. You'll need this later, so write it down, somewhere. You can do this by opening a command prompt on the archive machine and typing ipconfig. Get the IP address from the line labeled "IPv4 Address". These instructions will assume that the IP address of the archive server is 192.168.0.41.
|
||||
|
||||
Get the IP address of the archive machine. You'll need this later, so write it down, somewhere. You can do this by opening a command prompt on the archive machine and typing ipconfig. Get the IP address from the line labeled "IPv4 Address".
|
||||
### TODO Other hosting solutions
|
||||
|
||||
## Set up the Raspberry Pi
|
||||
@@ -78,194 +73,76 @@ There are four phases to setting up the Pi:
|
||||
1. Connect your SD card to your computer.
|
||||
2. Use Etcher to write the zip file you downloaded to the SD card. Etcher works well and is multi-platform.
|
||||
> Note: you don't need to uncompress the zip file you downloaded.
|
||||
3. Plug the micro sd card into the Pi.
|
||||
|
||||
### Get a shell on the Pi
|
||||
If you have a monitor with an hdmi input, a mini hdmi to hdmi cable, a usb keyboard and a micro usb power cable you can hook up the devices to the Pi and configure it directly. Plug it in and turn it on. When you're prompted for the password for the user "pi" use "raspberry" without the quotes. Now skip to section below titled "Get the scripts onto the Pi".
|
||||
If you have a monitor with an hdmi input, a mini hdmi to hdmi cable, a usb keyboard and a micro usb power cable you can hook up the devices to the Pi and configure it directly.
|
||||
1. Insert the MicroSD card into the Pi.
|
||||
1. Connect the keyboard, and monitor to the Pi.
|
||||
1. Connect the power supply to the Pi using the port labeld "PWR" on the circuitboard.
|
||||
1. When you're prompted for the password for the user "pi" use "raspberry" without the quotes.
|
||||
1. Now skip to section below titled "Get the scripts onto the Pi".
|
||||
|
||||
If you don't have a keyboard/HDMI setup to boot the Pi and edit/transfer files directly, you'll probably want to connect to it over USB. See the sections below for instructions.
|
||||
|
||||
#### Seting up the Pi without a monitor using Windows
|
||||
1. Download and install:
|
||||
* [Notepad++](https://notepad-plus-plus.org/) Alternatively, any other text editor which is capable of editing files with Unix-style line endings.
|
||||
* [Putty]( https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html) Note: You can paste into Putty by right-clicking. No matter where you right-click, the content will be inserted at the position of the cursor, as if you had typed it in.
|
||||
1. Watch [this video](https://www.youtube.com/watch?v=xj3MPmJhAPU) The instructions from the video are recreated below, with some changes.
|
||||
1. Open the config.txt file on the sd card with Notepad++
|
||||
1. Add this line to the end of the file
|
||||
```
|
||||
dtoverlay=dwc2
|
||||
```
|
||||
1. Add a blank line to the end of the file.
|
||||
1. Open cmdline.txt with Notepad++
|
||||
1. Find the word "rootwait", add this text, separated by spaces, between rootwait and the word following it:
|
||||
```
|
||||
modules-load=dwc2,g_ether
|
||||
```
|
||||
1. Create a file named ssh (with no extension) at the root
|
||||
1. Eject the sd card
|
||||
1. Move the sd card to the Pi.
|
||||
1. Connect a micro usb cable to the port labeled "USB" on the Raspberry Pi, and to the PC.
|
||||
1. On the PC, press your Windows key, type Control Panel.
|
||||
1. Open "Network and Sharing Center"
|
||||
1. Click "Change adapter settings"
|
||||
1. Wait for something labeled "USB Ethernet/RNDIS Gadget" to appear.
|
||||
1. Launch Putty
|
||||
1. In the Host Name box enter
|
||||
```
|
||||
pi@raspberrypi.local
|
||||
```
|
||||
1. If you get an "unknown host" error message install Bonjour: https://support.apple.com/kb/DL999 and go back to step 17.
|
||||
1. Password is raspberry
|
||||
1. Skip down to the section titled "Get the scripts onto the Pi"
|
||||
|
||||
#### Seting up the Pi without a monitor using a Mac or Linux
|
||||
Basically what you're doing is using the Pi's capability to emulate a network connection over USB. So you need to get the Pi (the guest) set up to load the proper modules to do so, and then connect from your machine (the host) using a shell (like iTerm+SSH on macOS).
|
||||
|
||||
Here are a few ways to accomplish this
|
||||
* [Gist (text file) showing example steps and discussion thread about issues, etc](https://gist.github.com/gbaman/975e2db164b3ca2b51ae11e45e8fd40a)
|
||||
* [Script to setup the Pi for connecting over USB](https://github.com/BigNate1234/rpi-USBSSH)
|
||||
* (I.e. First write the OS image to the SD card, then this script will make the changes to the card so you can boot it and access it over the USB cable.
|
||||
* **Assumes the SD card for the Pi is mounted at /Volumes/boot , and that you can use `sh`/`bash`**. This _should_ be the default for a Mac; if using something else, modify the script accordingly.
|
||||
If you don't have a keyboard/HDMI setup to boot the Pi and edit/transfer files directly, you'll probably want to connect to the Pi over USB.
|
||||
* If you're using Windows, follow [these instructions](GetShellWithoutMonitorOnWindows.md), then skip down to the section titled "Get the scripts onto the Pi".
|
||||
* If you're using Linux or a Mac, follow [these instructions](GetShellWitoutMonitorOnLinux.md), then proceed to the next section.
|
||||
|
||||
### Get the scripts onto the Pi
|
||||
Now that you have a shell on the Pi you can turn the Pi into a smart USB drive.
|
||||
1. Enter the following command.
|
||||
1. Enter the following commands:
|
||||
```
|
||||
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf
|
||||
sudo -i
|
||||
nano /etc/wpa_supplicant/wpa_supplicant.conf
|
||||
```
|
||||
1. Add this block to the bottom of the file specifying the actual SSID of your network and your actual PSK, keeping the quotes around both values.
|
||||
1. Add this block to the bottom of the file specifying the actual SSID of your network and your actual PSK, keeping the quotes around both values. Note that the SSID may be case-sensitive on your network.
|
||||
```
|
||||
network={
|
||||
ssid="NETWORK"
|
||||
ssid="SSID"
|
||||
psk="PASSWORD"
|
||||
}
|
||||
```
|
||||
1. Configure the wifi to ensure that your Pi has access to your network. Note that this command differs from what's described in the video above.
|
||||
1. Press Control-O, Enter to save the file.
|
||||
1. Press Control-X to return to the command line.
|
||||
1. Configure the wifi to ensure that your Pi has access to your network.
|
||||
```
|
||||
sudo wpa_cli -i wlan0 reconfigure
|
||||
wpa_cli -i wlan0 reconfigure
|
||||
```
|
||||
1. Run this command
|
||||
```
|
||||
ifconfig wlan0
|
||||
```
|
||||
1. Verify that there's an IP address on your subnet assigned.
|
||||
1. Run:
|
||||
1. Verify that there's an IP address on your subnet assigned. If you don't see the IP address wait for a couple of seconds and re-run the command.
|
||||
1. Try to ping your archive server from the Pi.
|
||||
```
|
||||
sudo nano /boot/cmdline.txt
|
||||
ping -c 3 nautilus
|
||||
```
|
||||
1. Remove the g_ether parameter and the comma preceding it, so you have
|
||||
```
|
||||
modules-load=dwc2
|
||||
```
|
||||
1. Figure out how much space to allocate for your usb drive. First run these command:
|
||||
```
|
||||
size="$(($(df --output=avail / | tail -1) - 1000000))"
|
||||
echo $size
|
||||
```
|
||||
1. If the number is negative, stop; you're using a MicroSD card that's too small. Otherwise:
|
||||
```
|
||||
sudo fallocate -l "$size"K /piusb.bin
|
||||
```
|
||||
1. Create a filesystem for the drive:
|
||||
```
|
||||
sudo mkdosfs /piusb.bin -F 32 -I
|
||||
```
|
||||
1. Create the mount point from which the scripts will copy the clips:
|
||||
```
|
||||
sudo mkdir /mnt/usb_share
|
||||
```
|
||||
1. Create the mount point for the network share to which the clips will be copied:
|
||||
```
|
||||
sudo mkdir /mnt/cam_archive
|
||||
```
|
||||
1. Tell the system how to connect the mount points to actual data:
|
||||
```
|
||||
sudo nano /etc/fstab
|
||||
```
|
||||
1. Add this line to the end of the file.
|
||||
```
|
||||
/piusb.bin /mnt/usb_share vfat noauto,users,umask=000 0 0
|
||||
```
|
||||
1. Add this line to the end of the file. Change the IP address here (192.168.0.41) to the actual IP address of the machine hosting your archive. Change the name of the share "SailfishCam" to the actual name of the share you created. Note: This is a single line.
|
||||
```
|
||||
//192.168.0.41/SailfishCam /mnt/cam_archive cifs vers=3,credentials=/root/.teslaCamArchiveCredentials,iocharset=utf8,file_mode=0777,dir_mode=0777 0 0
|
||||
```
|
||||
1. Create the credential file:
|
||||
```
|
||||
sudo nano /root/.teslaCamArchiveCredentials
|
||||
```
|
||||
1. Enter this content, specifying the actual user name and password for the user you created on the archive machine:
|
||||
```
|
||||
username=sailfish
|
||||
password=pa$$w0rd
|
||||
```
|
||||
1. Get the script which will archive the clips.
|
||||
```
|
||||
sudo mkdir /root/bin
|
||||
sudo -i
|
||||
cd /root/bin
|
||||
wget https://raw.githubusercontent.com/cimryan/teslausb/master/windows_archive/archive-teslacam-clips
|
||||
chmod +x archive-teslacam-clips
|
||||
exit
|
||||
```
|
||||
1. Verify that the archive server is reachable by name. Replace "archiveserver" with the actual name of your archive server.
|
||||
```
|
||||
ping archiveserver
|
||||
```
|
||||
1. If the name isn't resolvable, try its IP address.
|
||||
1. If the server can't be reached, ping its IP address:
|
||||
```
|
||||
ping 192.168.0.41
|
||||
```
|
||||
1. Get the script which will continually check for access to the archive server and trigger the archival:
|
||||
1. If you can't ping the archive server by IP address from the Pi you should go do whatever you need to on your network to fix that. If you can't reach the archive server by name from the Pi but you can by IP address then use its IP address, below, in place of its name.
|
||||
1. Run these commands, subsituting your values. The last line is the percent of the drive you want to allocate for dashcam storage. The remaining percentage will be allocated for music.
|
||||
```
|
||||
sudo -i
|
||||
cd /root/bin
|
||||
wget https://raw.githubusercontent.com/cimryan/teslausb/master/windows_archive/archiveloop
|
||||
chmod +x archiveloop
|
||||
exit
|
||||
export archiveserver=Nautilus
|
||||
export sharename=SailfishCam
|
||||
export shareuser=sailfish
|
||||
export sharepassword=pa$$w0rd
|
||||
export campercent=100
|
||||
```
|
||||
1. Edit the script and replace archiveserver on line 4 with the name or IP address of your archive server.
|
||||
1. Make the scripts run at startup:
|
||||
1. Run these commands:
|
||||
```
|
||||
sudo nano /etc/rc.local
|
||||
wget https://raw.githubusercontent.com/cimryan/teslausb/master/windows_archive/setup-teslausb
|
||||
chmod +x setup-teslausb
|
||||
./setup-teslausb
|
||||
```
|
||||
1. Change the very first line in the file to
|
||||
1. Run this command:
|
||||
```
|
||||
#!/bin/bash -eu
|
||||
reboot
|
||||
```
|
||||
1. Add this content before the last line (exit 0):
|
||||
```
|
||||
LOGFILE=/tmp/rc.local.log
|
||||
|
||||
function log () {
|
||||
echo "$( date )" >> "$LOGFILE"
|
||||
echo "$1" >> "$LOGFILE"
|
||||
}
|
||||
|
||||
log "Running fsck..."
|
||||
/sbin/fsck /mnt/usb_share -- -a >> "$LOGFILE" 2>&1 || echo ""
|
||||
log "Running modprobe..."
|
||||
/sbin/modprobe g_mass_storage >> "$LOGFILE" 2>&1
|
||||
log "Launching archival script..."
|
||||
/root/bin/archiveloop &
|
||||
log "All done"
|
||||
1. Set the configuration for the g_mass_storage module:
|
||||
```
|
||||
sudo -i
|
||||
cd /etc/modprobe.d
|
||||
wget https://raw.githubusercontent.com/cimryan/teslausb/master/g_mass_storage.conf
|
||||
|
||||
exit
|
||||
```
|
||||
1. Reboot the Pi:
|
||||
```
|
||||
sudo reboot
|
||||
```
|
||||
|
||||
### Get the Pi set up for your Tesla.
|
||||
If you set up the Pi with a keyboard and a monitor disconnect it and connect it to a PC. If you're using a cable be sure to use the cable labeled "usb" on the circuitboard.
|
||||
If you set up the Pi with a keyboard and a monitor disconnect it and connect it to a PC. If you're using a cable be sure to use the port labeled "usb" on the circuitboard.
|
||||
1. Wait for the Pi to show up on the PC as a USB drive.
|
||||
1. Create a directory named TeslaCam at the root of the drive.
|
||||
1. Eject the drive.
|
||||
1. Plug the Drive into your Tesla.
|
||||
|
||||
1. Create a directory named TeslaCam at the root of the drive labeled CAM.
|
||||
1. Copy any music you'd like to the drive labeled MUSIC.
|
||||
1. Eject the drives.
|
||||
1. Unplug the Pi from the PC.
|
||||
1. Plug the Pi into your Tesla.
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
options g_mass_storage file=/piusb.bin removable=1 ro=0 stall=0 iSerialNumber=123456
|
||||
@@ -1,10 +1,36 @@
|
||||
#!/bin/bash -eu
|
||||
|
||||
LOGFILE=/tmp/archive-teslacam-clips.log
|
||||
LOG_FILE=/tmp/archive-teslacam-clips.log
|
||||
CAM_MOUNT=/mnt/cam
|
||||
ARCHIVE_MOUNT=/mnt/archive
|
||||
|
||||
function log () {
|
||||
echo "$( date )" >> "$LOGFILE"
|
||||
echo "$1" >> "$LOGFILE"
|
||||
echo "$( date )" >> "$LOG_FILE"
|
||||
echo "$1" >> "$LOG_FILE"
|
||||
}
|
||||
|
||||
function retry () {
|
||||
local attempts=0
|
||||
while [ true ]
|
||||
do
|
||||
if eval "$@"
|
||||
then
|
||||
true
|
||||
return
|
||||
fi
|
||||
if [ "$attempts" -ge 10 ]
|
||||
then
|
||||
log "Attempts exhausted."
|
||||
false
|
||||
return
|
||||
fi
|
||||
log "Sleeping before retry..."
|
||||
/bin/sleep 1
|
||||
attempts=$((attempts + 1))
|
||||
log "Retrying..."
|
||||
done
|
||||
false
|
||||
return
|
||||
}
|
||||
|
||||
function mount_mountpoint () {
|
||||
@@ -12,7 +38,7 @@ function mount_mountpoint () {
|
||||
log "Mounting $mount_point..."
|
||||
|
||||
local mounted=true
|
||||
mount "$mount_point" >> "$LOGFILE" 2>&1 || mounted=false
|
||||
mount "$mount_point" >> "$LOG_FILE" 2>&1 || mounted=false
|
||||
if [ "$mounted" = true ]
|
||||
then
|
||||
log "Mounted $mount_point."
|
||||
@@ -39,63 +65,63 @@ function ensure_mountpoint_is_mounted () {
|
||||
fi
|
||||
}
|
||||
|
||||
function ensure_mountpoint_is_mounted_with_retry () {
|
||||
retry ensure_mountpoint_is_mounted "$1"
|
||||
}
|
||||
|
||||
function move_clips_to_archive () {
|
||||
log "Moving clips to archive..."
|
||||
for file_name in /mnt/usb_share/TeslaCam/saved*; do
|
||||
for file_name in "$CAM_MOUNT"/TeslaCam/saved*; do
|
||||
[ -e "$file_name" ] || continue
|
||||
log "Moving $file_name ..."
|
||||
mv -- "$file_name" /mnt/cam_archive >> "$LOGFILE" 2>&1
|
||||
mv -- "$file_name" "$ARCHIVE_MOUNT" >> "$LOG_FILE" 2>&1 || echo ""
|
||||
log "Moved $file_name."
|
||||
done
|
||||
log "Finished moving clips to archive."
|
||||
}
|
||||
|
||||
function disconnect_usb_from_host () {
|
||||
function disconnect_usb_drives_from_host () {
|
||||
log "Disconnecting usb from host..."
|
||||
modprobe -r g_mass_storage
|
||||
log "Disconnected usb from host."
|
||||
}
|
||||
|
||||
function mount_usb_drive_locally () {
|
||||
log "Mounting usb locally..."
|
||||
mount /mnt/usb_share
|
||||
log "Mounted usb locally."
|
||||
function fix_errors_on_cam_drive () {
|
||||
log "Running fsck..."
|
||||
/sbin/fsck "$CAM_MOUNT" -- -a >> "$LOG_FILE" 2>&1 || echo ""
|
||||
log "Finished running fsck."
|
||||
}
|
||||
|
||||
function ensure_cam_archive_is_mounted () {
|
||||
function ensure_archive_is_mounted () {
|
||||
log "Ensuring cam archive is mounted..."
|
||||
ensure_mountpoint_is_mounted /mnt/cam_archive
|
||||
ensure_mountpoint_is_mounted_with_retry "$ARCHIVE_MOUNT"
|
||||
log "Ensured cam archive is mounted."
|
||||
}
|
||||
|
||||
function ensure_usb_share_is_mounted () {
|
||||
log "Ensuring usb share is mounted..."
|
||||
ensure_mountpoint_is_mounted /mnt/usb_share
|
||||
log "Ensured usb share is mounted."
|
||||
function ensure_cam_drive_is_mounted () {
|
||||
log "Ensuring cam drive is mounted..."
|
||||
ensure_mountpoint_is_mounted_with_retry "$CAM_MOUNT"
|
||||
log "Ensured cam drive is mounted."
|
||||
}
|
||||
|
||||
function unmount_usb_share () {
|
||||
log "Unmounting usb share..."
|
||||
umount /mnt/usb_share
|
||||
log "Unmounted usb share."
|
||||
}
|
||||
|
||||
function connect_usb_to_host() {
|
||||
log "Connecting usb to host..."
|
||||
modprobe g_mass_storage
|
||||
log "Connected usb to host."
|
||||
function unmount_cam_drive () {
|
||||
log "Unmounting cam drive..."
|
||||
umount "$CAM_MOUNT"
|
||||
log "Unmounted cam drive."
|
||||
}
|
||||
|
||||
log "Starting..."
|
||||
|
||||
ensure_cam_archive_is_mounted
|
||||
ensure_archive_is_mounted
|
||||
|
||||
disconnect_usb_from_host
|
||||
disconnect_usb_drives_from_host
|
||||
|
||||
ensure_usb_share_is_mounted
|
||||
fix_errors_on_cam_drive
|
||||
|
||||
ensure_cam_drive_is_mounted
|
||||
|
||||
move_clips_to_archive
|
||||
|
||||
unmount_usb_share
|
||||
unmount_cam_drive
|
||||
|
||||
connect_usb_to_host
|
||||
connect_usb_drives_to_host
|
||||
@@ -4,16 +4,12 @@
|
||||
ARCHIVE_HOST_NAME=archiveserver
|
||||
LOGFILE=/tmp/archiveloop.log
|
||||
|
||||
function clear_log () {
|
||||
rm "$LOGFILE" > /dev/null 2>&1 || echo ""
|
||||
}
|
||||
|
||||
function log () {
|
||||
echo "$( date )" >> "$LOGFILE"
|
||||
echo "$1" >> "$LOGFILE"
|
||||
}
|
||||
|
||||
function check_archive_reachability () {
|
||||
function archive_is_reachable () {
|
||||
local reachable=true
|
||||
ping -q -w 1 -c 1 "$ARCHIVE_HOST_NAME" > /dev/null 2>&1 || reachable=false
|
||||
if [ "$reachable" = false ]
|
||||
@@ -24,11 +20,17 @@ function check_archive_reachability () {
|
||||
true
|
||||
}
|
||||
|
||||
function connect_usb_drives_to_host() {
|
||||
log "Connecting usb to host..."
|
||||
modprobe g_mass_storage
|
||||
log "Connected usb to host."
|
||||
}
|
||||
|
||||
function wait_for_archive_to_be_reachable () {
|
||||
log "Waiting for archive to be reachable..."
|
||||
while [ true ]
|
||||
do
|
||||
if check_archive_reachability
|
||||
if archive_is_reachable
|
||||
then
|
||||
log "Archive is reachable."
|
||||
break
|
||||
@@ -47,7 +49,7 @@ function wait_for_archive_to_be_unreachable () {
|
||||
log "Waiting for archive to be unreachable..."
|
||||
while [ true ]
|
||||
do
|
||||
if ! check_archive_reachability
|
||||
if ! archive_is_reachable
|
||||
then
|
||||
log "Archive is unreachable."
|
||||
break
|
||||
@@ -56,10 +58,19 @@ function wait_for_archive_to_be_unreachable () {
|
||||
done
|
||||
}
|
||||
|
||||
clear_log
|
||||
export -f connect_usb_drives_to_host
|
||||
|
||||
log "Starting..."
|
||||
|
||||
if archive_is_reachable
|
||||
then
|
||||
archive_clips
|
||||
|
||||
wait_for_archive_to_be_unreachable
|
||||
else
|
||||
connect_usb_drives_to_host
|
||||
fi
|
||||
|
||||
while [ true ]
|
||||
do
|
||||
wait_for_archive_to_be_reachable
|
||||
|
||||
31
windows_archive/setup-piForHeadlessConfig.ps1
Normal file
31
windows_archive/setup-piForHeadlessConfig.ps1
Normal file
@@ -0,0 +1,31 @@
|
||||
[CmdletBinding()]
|
||||
Param
|
||||
(
|
||||
[Parameter(Mandatory=$True,Position=1)]
|
||||
[string]$driveLetter
|
||||
)
|
||||
|
||||
$drivePath="${driveLetter}:"
|
||||
$configPath = "$drivePath\config.txt"
|
||||
$cmdlinePath = "$drivePath\cmdline.txt"
|
||||
$sshPath = "$drivePath\ssh"
|
||||
|
||||
if ((![System.IO.File]::Exists($configPath) -or
|
||||
(![System.IO.File]::Exists($cmdlinePath)))) {
|
||||
Write-Error "Didn't find cmdline.txt and config.txt on drive $drivePath."
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Verbose "Updating $configPath ..."
|
||||
|
||||
"" | Out-File -FilePath $configPath -Append -Encoding utf8
|
||||
"dtoverlay=dwc2" | Out-File -FilePath $configPath -Append -Encoding utf8
|
||||
|
||||
Write-Verbose "Updating $cmdlinePath ..."
|
||||
$cmdlinetxtContent = gc -Raw $cmdlinePath
|
||||
$cmdlinetxtContent.Replace("rootwait", "rootwait modules-load=dwc2,g_ether") | Out-File -FilePath $cmdlinePath -Encoding utf8
|
||||
|
||||
Write-Verbose "Enabling SSH ..."
|
||||
[System.IO.File]::CreateText($sshPath).Dispose()
|
||||
|
||||
Write-Verbose "All done."
|
||||
122
windows_archive/setup-teslausb
Normal file
122
windows_archive/setup-teslausb
Normal file
@@ -0,0 +1,122 @@
|
||||
#!/bin/bash -eu
|
||||
|
||||
if [ "$(whoami)" != "root" ]
|
||||
then
|
||||
echo "STOP: Run sudo -i."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
function check_variable () {
|
||||
local var_name="$1"
|
||||
if [ -z "${!var_name+x}" ]
|
||||
then
|
||||
echo "STOP: Define the variable $var_name like this: export $var_name=value"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_variable "archiveserver"
|
||||
check_variable "sharename"
|
||||
check_variable "shareuser"
|
||||
check_variable "sharepassword"
|
||||
check_variable "campercent"
|
||||
|
||||
serverunreachable=false
|
||||
ping -c 1 -w 1 "$archiveserver" 1>/dev/null 2>&1 || serverunreachable=true
|
||||
|
||||
if [ "$serverunreachable" = true ]
|
||||
then
|
||||
echo "STOP: The archive server $archiveserver is unreachable. Try specifying its IP address instead."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
archiveserverip="$(getent hosts $archiveserver | cut -d' ' -f1)"
|
||||
|
||||
available_space="$(($(df --output=avail / | tail -1) - 1000000))"
|
||||
|
||||
if [ "$available_space" -lt 0 ]
|
||||
then
|
||||
echo "STOP: The MicroSD card is too small."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
function add_drive () {
|
||||
local name="$1"
|
||||
local label="$2"
|
||||
local size="$3"
|
||||
|
||||
local filename="$4"
|
||||
fallocate -l "$size"K "$filename"
|
||||
mkfs.vfat "$filename" -F 32 -n "$label"
|
||||
|
||||
local mountpoint=/mnt/"$name"
|
||||
|
||||
mkdir "$mountpoint"
|
||||
echo "$filename $mountpoint vfat noauto,users,umask=000 0 0" >> /etc/fstab
|
||||
}
|
||||
|
||||
pushd ~
|
||||
|
||||
cp /boot/cmdline.txt ~
|
||||
cat ~/cmdline.txt | sed 's/[[:space:]]\+modules-load=[^ [:space:]]\+//' | sed 's/rootwait/rootwait modules-load=dwc2/' > /boot/cmdline.txt
|
||||
rm ~/cmdline.txt
|
||||
|
||||
mkdir /mnt/archive
|
||||
|
||||
echo "" >> /etc/fstab
|
||||
echo "//$archiveserverip/$sharename /mnt/archive cifs vers=3,credentials=/root/.teslaCamArchiveCredentials,iocharset=utf8,file_mode=0777,dir_mode=0777 0" >> /etc/fstab
|
||||
|
||||
echo "username=$shareuser" > /root/.teslaCamArchiveCredentials
|
||||
echo "password=$sharepassword" >> /root/.teslaCamArchiveCredentials
|
||||
|
||||
mkdir /root/bin
|
||||
|
||||
wget https://raw.githubusercontent.com/cimryan/teslausb/master/windows_archive/archiveloop
|
||||
sed s/ARCHIVE_HOST_NAME=archiveserver/ARCHIVE_HOST_NAME=$archiveserver/ ~/archiveloop > /root/bin/archiveloop
|
||||
rm ~/archiveloop
|
||||
chmod +x /root/bin/archiveloop
|
||||
|
||||
pushd /root/bin
|
||||
wget https://raw.githubusercontent.com/cimryan/teslausb/master/windows_archive/archive-teslacam-clips
|
||||
chmod +x archive-teslacam-clips
|
||||
popd
|
||||
|
||||
echo "#!/bin/bash -eu" > ~/rc.local
|
||||
tail -n +2 /etc/rc.local | sed '$d' >> ~/rc.local
|
||||
cat << 'EOF' >> ~/rc.local
|
||||
LOGFILE=/tmp/rc.local.log
|
||||
|
||||
function log () {
|
||||
echo "$( date )" >> "$LOGFILE"
|
||||
echo "$1" >> "$LOGFILE"
|
||||
}
|
||||
|
||||
log "Launching archival script..."
|
||||
/root/bin/archiveloop &
|
||||
log "All done"
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
cat ~/rc.local > /etc/rc.local
|
||||
rm ~/rc.local
|
||||
|
||||
cam_disk_size="$(( $available_space * $campercent / 100 ))"
|
||||
cam_disk_file_name="/cam_disk.bin"
|
||||
add_drive "cam" "CAM" "$cam_disk_size" "$cam_disk_file_name"
|
||||
|
||||
if [ "$campercent" -lt 100 ]
|
||||
then
|
||||
musicpercent="$(( 100 - $campercent ))"
|
||||
music_disk_size="$(( $available_space * $musicpercent / 100 ))"
|
||||
music_disk_file_name="/music_disk.bin"
|
||||
add_drive "music" "MUSIC" "$music_disk_size" "$music_disk_file_name"
|
||||
echo "options g_mass_storage file=$cam_disk_file_name,$music_disk_file_name removable=1,1 ro=0,0 stall=0 iSerialNumber=123456" > /etc/modprobe.d/g_mass_storage.conf
|
||||
else
|
||||
echo "options g_mass_storage file=$cam_disk_file_name removable=1 ro=0 stall=0 iSerialNumber=123456" > /etc/modprobe.d/g_mass_storage.conf
|
||||
fi
|
||||
|
||||
cp /etc/hosts ~
|
||||
sed s/raspberrypi/teslausb/g ~/hosts > /etc/hosts
|
||||
|
||||
cp /etc/hostname ~
|
||||
sed s/raspberrypi/teslausb/g ~/hostname > /etc/hostname
|
||||
Reference in New Issue
Block a user