Skip to content

Commit 0029224

Browse files
authored
feat: host website on external webserver (#16)
* feat(web): add fetch from url * feat(server): add option to use external webserver * feat(web): nginx dockerfile * Update ci.yml * ci: bump node version * Update BuildInstructions.md * Update package.json * fixes * Update index.htm * ci: docker image release * feat(web): config.json * Update ci.yml * format * Update ci.yml * format * format * format * update instructions * Update release.yml * format * format * format * Update index.htm * revert * rename prettier file * ci: add permissions * cI: add registry login * Update BuildInstructions.md * ci: add build arg * Update BuildInstructions.md
1 parent 8cbd8ff commit 0029224

File tree

11 files changed

+220
-26
lines changed

11 files changed

+220
-26
lines changed

.github/dependabot.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,19 @@ updates:
1212
- "dependencies"
1313

1414
- package-ecosystem: "github-actions"
15+
directory: "/"
16+
schedule:
17+
interval: "monthly"
18+
labels:
19+
- "dependencies"
20+
21+
- package-ecosystem: "docker"
1522
directory: "/"
1623
schedule:
1724
interval: "weekly"
25+
groups:
26+
patch-dependencies:
27+
update-types:
28+
- "patch"
1829
labels:
1930
- "dependencies"

.github/workflows/ci.yml

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ jobs:
5757
- name: Setup Node
5858
uses: actions/setup-node@v6
5959
with:
60-
node-version: 22.x
60+
node-version: 24.x
6161

6262
- name: Install dependecies
6363
working-directory: ${{ env.WEB_PATH }}
@@ -66,3 +66,34 @@ jobs:
6666
- name: Check format
6767
working-directory: ${{ env.WEB_PATH }}
6868
run: npm run format:check
69+
70+
Docker:
71+
runs-on: ubuntu-latest
72+
steps:
73+
- name: Checkout repository
74+
uses: actions/checkout@v5
75+
76+
- name: Docker build
77+
working-directory: web
78+
run: docker build -t remote-switch .
79+
80+
- name: Run container
81+
run: |
82+
docker run --rm -d \
83+
-p 80:80 \
84+
--name remote-switch remote-switch
85+
86+
- name: Wait for container to start
87+
run: sleep 5
88+
89+
- name: Ping
90+
run: |
91+
if curl -f http://localhost:80 | grep -q ">Arduino Remote Switch</title>"; then
92+
echo "Title found!"
93+
else
94+
echo "Error: '>Arduino Remote Switch</title>' not found." >&2
95+
exit 1
96+
fi
97+
98+
- name: Stop container
99+
run: docker stop remote-switch

.github/workflows/release.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: Release
2+
3+
on:
4+
release:
5+
types: [released, prereleased]
6+
7+
jobs:
8+
docker:
9+
runs-on: ubuntu-latest
10+
permissions:
11+
contents: read
12+
packages: write
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v4
16+
17+
- name: Log in to GitHub Container Registry
18+
uses: docker/login-action@v3
19+
with:
20+
registry: ghcr.io
21+
username: ${{ github.actor }}
22+
password: ${{ secrets.GITHUB_TOKEN }}
23+
24+
- name: Set up QEMU
25+
uses: docker/setup-qemu-action@v3
26+
27+
- name: Set up Docker Buildx
28+
uses: docker/setup-buildx-action@v3
29+
30+
- name: Build and push Docker image (latest)
31+
uses: docker/build-push-action@v6
32+
if: ${{ !github.event.release.prerelease }}
33+
with:
34+
context: ./web
35+
push: true
36+
labels: ${{ steps.meta.outputs.labels }}
37+
platforms: linux/amd64,linux/arm64
38+
tags: |
39+
ghcr.io/matiasg19/arduino-remote-switch:latest
40+
ghcr.io/matiasg19/arduino-remote-switch:${{ github.ref_name }}
41+
build-args: |
42+
TAG=${{ github.ref_name }}
43+
44+
- name: Build and push Docker image (prerelease)
45+
uses: docker/build-push-action@v6
46+
if: ${{ github.event.release.prerelease }}
47+
with:
48+
context: ./web
49+
push: true
50+
labels: ${{ steps.meta.outputs.labels }}
51+
platforms: linux/amd64,linux/arm64
52+
tags: |
53+
ghcr.io/matiasg19/arduino-remote-switch:pre
54+
ghcr.io/matiasg19/arduino-remote-switch:${{ github.ref_name }}
55+
build-args: |
56+
TAG=${{ github.ref_name }}

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Remote switch to turn on, off, reset or kill PC via a web interface.
44

5-
This project is based on a Arduino with a ethernet shield and a small daugtherboard to connect to PC headers by decoupling the two circuits with optocouplers. The power for the Arduino is sourced from the PC's motherboard USB header. The switch interface is hosted on the ethernet shield as a website and can be accessed from anywhere on the network via a webbrowser.
5+
This project is based on a Arduino with a ethernet shield and a small daughter board to connect to PC headers by decoupling the two circuits with optocouplers. The power for the Arduino is sourced from the PC's motherboard USB header. The switch interface is hosted on the ethernet shield as a website and can be accessed from anywhere on the network via a web browser.
66

77
![Web interface](./web.png)
88

docs/BuildInstructions.md

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,64 @@
88

99
![Schematic](./Assets/schematic.png)
1010

11-
1. Cut PCB to the right size if neccessary.
11+
1. Cut PCB to the right size if necessary.
1212
2. Drill two mounting holes into PCB to fit the board at the end of the case.
13-
3. Solder the componentes onto PCB (daughterboard).
14-
4. Screw Arduino with shield and spacers into case (saw spacers to the right length in neccessary).
15-
5. Install daughterboard.
16-
6. Wire daughterboard to Arduino.
13+
3. Solder the components onto PCB (daughter board).
14+
4. Screw Arduino with shield and spacers into case (saw spacers to the right length in necessary).
15+
5. Install daughter board.
16+
6. Wire daughter board to Arduino.
17+
7. Next steps: [install software](#installing-software).
1718

18-
![Daughterboard](./Assets/daughterboard.png)
19+
![Daughter board](./Assets/daughterboard.png)
1920

2021
## Installing software
2122

23+
### Installation steps
24+
25+
1. Deploy website on [SD card](#deploy-website-on-sd-card-default) or on [external webserver](#deploy-website-on-external-webserver-recommended)
26+
2. Connect Arduino to a powered on PC via USB and the shield to a router via ethernet.
27+
3. Open router configuration, set a static IP range and choose a free IP address.
28+
4. Set the IP address in the `src.ino` file and save (skip this step when already done in a previous step).
29+
5. Open Arduino IDE and upload `src.ino` to Arduino.
30+
6. Test if the website can be reached by typing the IP into the web browser (skip this step when already done in a previous step).
31+
7. Unplug all the cables from the Arduino for the next steps.
32+
8. Next steps: [Install into PC](#installing-into-pc).
33+
34+
### Website deploy options
35+
36+
Website can be deployed on SD card of the ethernet shield or on a dedicated webserver.
37+
38+
Recommended way is to deploy the website on a dedicated webserver due to problems with the SD card initialization. Sometimes the SD card does not initialize on startup, pulling the SD card out and pushing it in again helps. But this is not a viable solution when the arduino is installed inside a PC.
39+
40+
#### Deploy website on SD card (default)
41+
2242
1. Format SD card to FAT16 with [SDcard formatter (recommended)](https://www.sdcard.org/downloads/formatter/)
2343
2. Store website (content of `web/src/`) on SD card.
2444
3. Put SD card into ethernet shield.
25-
4. Connect Arduino to a powerd on PC via USB and the shield to a router via ethernet.
26-
5. Open router configuration, set a static IP range and choose a free IP address.
27-
6. Set the IP address in the `src.ino` file and save.
28-
7. Open Arduino IDE and upload `src.ino` to Arduino.
29-
8. Test if the website can be reached by typing the IP into the webbrowser.
30-
9. Unplug all the cables from the Arduino for the next steps.
45+
46+
#### Deploy website on external webserver (recommended)
47+
48+
1. In `server/src/src.ino`
49+
50+
- Comment out `#define WEBSITE_ON_SD_CARD`
51+
- Comment in `#define WEBSITE_ON_EXTERNAL_WEBSERVER`
52+
- Set the IP address in the `src.ino` file and save.
53+
54+
2. Create a directory on your server e.g. `remote-switch` and copy `web/src/config.json` to it
55+
56+
- `mkdir remote-switch`
57+
58+
3. In `remote-switch/config.json`
59+
60+
- Set the `apiUrl` constant to the IP address of the arduino ethernet shield
61+
- (optional) Change the `title`
62+
63+
3. Deploy the webserver using docker
64+
65+
- `cd` into `remote-switch` directory
66+
- docker run -p 80:80 -v ./config.json:/usr/share/nginx/html/config.json ghcr.io/matiasg19/arduino-remote-switch:latest
67+
68+
4. Test if the website can be reached by typing the IP into the web browser.
3169

3270
## Installing into PC
3371

@@ -37,7 +75,7 @@
3775
4. Connect Arduino to the USB header.
3876
5. Connect the shield to ethernet to router.
3977
6. Restore power to PC again. Arduino should turn on.
40-
7. Open webbrowser on phone to open the website and turn on PC by pressing the power on button.
78+
7. Open web browser on phone to open the website and turn on PC by pressing the power on button.
4179
8. PC should start.
4280

4381
![Front panel IO](./Assets/frontpanelIO.png)

server/src/src.ino

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
1+
// #define WEBSITE_ON_SD_CARD // Comment out this line when using external
2+
// webserver
3+
#define WEBSITE_ON_EXTERNAL_WEBSERVER // Comment this line out the using SD
4+
// card
5+
16
#include <Ethernet.h>
7+
#ifdef WEBSITE_ON_SD_CARD
28
#include <SD.h>
9+
#endif
310

411
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
5-
IPAddress ip(192, 168, 0, 10);
12+
IPAddress ip(192, 168, 0, 10); // Edit IP address here
613
EthernetServer server(80);
714
long delayStart;
815

@@ -30,6 +37,7 @@ void setup() {
3037
delayStart = millis();
3138

3239
// SD card
40+
#ifdef WEBSITE_ON_SD_CARD
3341
Serial.println("Initializing SD card...");
3442
if (!SD.begin(4)) {
3543
Serial.println("ERROR - SD card initialization failed!");
@@ -43,6 +51,7 @@ void setup() {
4351
return;
4452
}
4553
Serial.println("SUCCESS - Found file.");
54+
#endif
4655
}
4756

4857
void loop() {
@@ -110,9 +119,18 @@ void loop() {
110119

111120
void sendResponse(String request, EthernetClient client) {
112121
client.println("HTTP/1.1 200 OK");
122+
#ifdef WEBSITE_ON_EXTERNAL_WEBSERVER
123+
client.println("Access-Control-Allow-Origin: *");
124+
client.println("Access-Control-Allow-Methods: GET");
125+
client.println("Access-Control-Allow-Headers: Content-Type");
126+
client.println("Content-Type: text/plain");
127+
client.println("Connection: close");
128+
client.println();
129+
#endif
113130

114131
// Send file to client
115132
if (request == "") {
133+
#ifdef WEBSITE_ON_SD_CARD
116134
request = "index.htm";
117135
client.println("Content-Type: text/html\n\r\n\r");
118136
File webFile = SD.open(request);
@@ -122,6 +140,10 @@ void sendResponse(String request, EthernetClient client) {
122140
}
123141
webFile.close();
124142
}
143+
#endif
144+
#ifdef WEBSITE_ON_EXTERNAL_WEBSERVER
145+
client.println("HTTP/1.1 404 Not Found\n\r");
146+
#endif
125147
}
126148
// Button actions and status request
127149
else {
File renamed without changes.

web/Dockerfile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
FROM nginx:1.29.1-alpine
2+
ARG TAG=0.0.1
3+
COPY ./src /usr/share/nginx/html
4+
RUN mv /usr/share/nginx/html/index.htm /usr/share/nginx/html/index.html
5+
RUN sed -i "s/%version%/$TAG/g" /usr/share/nginx/html/index.html
6+
EXPOSE 80

web/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "arduino-remote-switch",
3-
"version": "1.0.0",
3+
"version": "0.0.1",
44
"main": "index.htm",
55
"repository": "https://github.com/MatiasG19/arduino-remote-switch",
66
"author": "Matiasg19",
@@ -14,7 +14,7 @@
1414
"prettier": "3.6.2"
1515
},
1616
"engines": {
17-
"node": "^22",
17+
"node": "^24",
1818
"npm": ">= 11"
1919
}
2020
}

web/src/config.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"title": "Arduino Remote Switch",
3+
"apiUrl": ""
4+
}

0 commit comments

Comments
 (0)