initial commit
Signed-off-by: Jyri Genral <jyri.eerola@jrd.fi>
This commit is contained in:
commit
a9e1501e48
12 changed files with 6006 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fe/node_modules
|
||||
fe/dist
|
||||
fe/dist.*
|
||||
192
WebServer/WebServer.ino
Normal file
192
WebServer/WebServer.ino
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
// FukkenRF Web Server
|
||||
// inspired by a Web Server example from year 2009 by David A. Mellis.
|
||||
|
||||
#include <SPI.h>
|
||||
#include <Ethernet.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <HardwareSerial.h>
|
||||
HardwareSerial Serial;
|
||||
|
||||
// Set your desired MAC and IP addresses, you might want to change these below
|
||||
byte mac[] = { 0xCA, 0xFE, 0x01, 0x02, 0x03, 0x04 };
|
||||
IPAddress ip(10, 10, 10, 10);
|
||||
|
||||
// Set port
|
||||
EthernetServer server(80);
|
||||
|
||||
// REMEMBER TO CHECK THE RIGHT CHIP SELECT PIN!
|
||||
//
|
||||
|
||||
|
||||
#define HFENABLE 3
|
||||
|
||||
#define LOVHF1 54
|
||||
#define LOVHF2 2
|
||||
#define HF1 5
|
||||
#define HF2 6
|
||||
#define HF3 7
|
||||
#define HF4 8
|
||||
#define HF5 9
|
||||
#define HF6 11
|
||||
#define VHF1 12
|
||||
#define VHF2 13
|
||||
#define VHF3 14
|
||||
#define VHF4 15
|
||||
#define VHF5 16
|
||||
#define VHF6 17
|
||||
|
||||
|
||||
void setup() {
|
||||
pinMode(LOVHF1, OUTPUT);
|
||||
pinMode(LOVHF2, OUTPUT);
|
||||
pinMode(HF1, OUTPUT);
|
||||
pinMode(HF2, OUTPUT);
|
||||
pinMode(HF3, OUTPUT);
|
||||
pinMode(HF4, OUTPUT);
|
||||
pinMode(HF5, OUTPUT);
|
||||
pinMode(HF6, OUTPUT);
|
||||
pinMode(VHF1, OUTPUT);
|
||||
pinMode(VHF2, OUTPUT);
|
||||
pinMode(VHF3, OUTPUT);
|
||||
pinMode(VHF4, OUTPUT);
|
||||
pinMode(VHF5, OUTPUT);
|
||||
pinMode(VHF6, OUTPUT);
|
||||
|
||||
// REMEMBER TO CHECK THE RIGHT CHIP SELECT PIN!
|
||||
Ethernet.init(ETHERNET_CS_PIN);
|
||||
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {} // wait for it
|
||||
|
||||
// start the Ethernet connection and the server:
|
||||
Ethernet.begin(mac, ip);
|
||||
|
||||
// Check for Ethernet shield's presense
|
||||
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
|
||||
Serial.println("Ethernet: not found");
|
||||
while (true) {
|
||||
delay(1); // do nothing, no point running without Ethernet hardware
|
||||
}
|
||||
}
|
||||
if (Ethernet.linkStatus() == LinkOFF) {
|
||||
Serial.println("Ethernet: link down");
|
||||
}
|
||||
|
||||
// start the server
|
||||
server.begin();
|
||||
Serial.print("listening at ");
|
||||
Serial.println(Ethernet.localIP());
|
||||
}
|
||||
|
||||
|
||||
unsigned int newPin = 0;
|
||||
unsigned int currentPin = 0;
|
||||
|
||||
|
||||
void setPin() {
|
||||
if (newPin != currentPin) {
|
||||
digitalWrite(HFENABLE, LOW);
|
||||
digitalWrite(LOVHF1, LOW);
|
||||
digitalWrite(LOVHF2, LOW);
|
||||
digitalWrite(HF1, LOW);
|
||||
digitalWrite(HF2, LOW);
|
||||
digitalWrite(HF3, LOW);
|
||||
digitalWrite(HF4, LOW);
|
||||
digitalWrite(HF5, LOW);
|
||||
digitalWrite(HF6, LOW);
|
||||
digitalWrite(VHF1, LOW);
|
||||
digitalWrite(VHF2, LOW);
|
||||
digitalWrite(VHF3, LOW);
|
||||
digitalWrite(VHF4, LOW);
|
||||
digitalWrite(VHF5, LOW);
|
||||
digitalWrite(VHF6, LOW);
|
||||
|
||||
delay(100);
|
||||
|
||||
if ((HF1==newPin) ||
|
||||
(HF2==newPin) ||
|
||||
(HF3==newPin) ||
|
||||
(HF4==newPin) ||
|
||||
(HF5==newPin) ||
|
||||
(HF6==newPin)) {
|
||||
digitalWrite(HFENABLE, HIGH);
|
||||
}
|
||||
|
||||
digitalWrite(newPin, HIGH);
|
||||
}
|
||||
currentPin = newPin;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// listen for incoming clients
|
||||
EthernetClient client = server.available();
|
||||
if (client) {
|
||||
Serial.println("new client");
|
||||
|
||||
// an http request ends with a blank line
|
||||
boolean currentLineIsBlank = true;
|
||||
|
||||
boolean firstLine = true;
|
||||
unsigned int firstCharN = 0;
|
||||
char firstLineBuf[5] = "";
|
||||
char postCompare[5] = "POST";
|
||||
boolean wasPostReq = false;
|
||||
|
||||
while (client.connected()) {
|
||||
if (client.available()) {
|
||||
char c = client.read();
|
||||
Serial.write(c);
|
||||
// if you've gotten to the end of the line (received a newline
|
||||
// character) and the line is blank, the http request has ended,
|
||||
// so you can send a reply
|
||||
if (c == '\n' && currentLineIsBlank) {
|
||||
if (wasPostReq) {
|
||||
//pin = client.read() - 65;
|
||||
newPin = c - 65;
|
||||
}
|
||||
// send a standard http response header
|
||||
client.println("HTTP/1.1 200 OK");
|
||||
client.println("Content-Type: text/html");
|
||||
client.println("Access-Control-Allow-Origin: *");
|
||||
client.println("Connection: close"); // the connection will be closed after completion of the response
|
||||
client.println();
|
||||
client.println("<!DOCTYPE HTML>");
|
||||
client.println("<html>");
|
||||
if (wasPostReq) {
|
||||
client.println("Got POST!!");
|
||||
newPin = client.read() - 65;
|
||||
client.print("New pin: ");
|
||||
client.println(newPin);
|
||||
} else {
|
||||
client.println("Didn't get POST :(");
|
||||
}
|
||||
client.println("</html>");
|
||||
setPin();
|
||||
break;
|
||||
}
|
||||
if (c == '\n') {
|
||||
firstLine = false;
|
||||
// you're starting a new line
|
||||
currentLineIsBlank = true;
|
||||
} else if (c != '\r') {
|
||||
// you've gotten a character on the current line
|
||||
currentLineIsBlank = false;
|
||||
}
|
||||
|
||||
if (firstLine && firstCharN < sizeof(firstLineBuf)) {
|
||||
firstLineBuf[firstCharN] = c;
|
||||
if (0 == memcmp(firstLineBuf, postCompare, sizeof(postCompare))) {
|
||||
wasPostReq = true;
|
||||
}
|
||||
firstCharN++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// give the web browser time to receive the data
|
||||
delay(1);
|
||||
// close the connection:
|
||||
client.stop();
|
||||
Serial.println("client disconnected");
|
||||
}
|
||||
}
|
||||
23
fe/LICENSE
Normal file
23
fe/LICENSE
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Michel Weststrate
|
||||
Forked from: https://github.com/bvanreeven/react-typescript
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
13
fe/README.md
Normal file
13
fe/README.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
_Fork of https://github.com/mobxjs/mobx-react-typescript-boilerplate.git_
|
||||
|
||||
# React-TypeScript
|
||||
|
||||
Minimal boilerplate for a single-page app using MobX, React and TypeScript with TSX.
|
||||
|
||||
Initial run:
|
||||
|
||||
* Install Node.js
|
||||
* `yarn install`
|
||||
* `yarn start`
|
||||
|
||||
For simplicity sake Webpack Hot Module Reloading is disabled. If you want to use HMR, see the [Reactive2015 demo](https://github.com/mobxjs/mobx-reactive2015-demo) to see a valid setup.
|
||||
10
fe/index.html
Normal file
10
fe/index.html
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>FukkenRF</title>
|
||||
<link rel="stylesheet" href="/static/main.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script src="/static/bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
42
fe/package.json
Normal file
42
fe/package.json
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"name": "mobx-react-typescript-boilerplate",
|
||||
"version": "1.0.0",
|
||||
"description": "Boilerplate for MobX + React project with Typescript, ES6 compilation and hot code reloading",
|
||||
"scripts": {
|
||||
"start": "node server.js"
|
||||
},
|
||||
"keywords": [
|
||||
"react",
|
||||
"reactjs",
|
||||
"boilerplate",
|
||||
"mobx",
|
||||
"starter-kit"
|
||||
],
|
||||
"author": "Michel Weststrate <mweststrate@gmail.com> (http://github.com/mweststrate)",
|
||||
"license": "MIT",
|
||||
"homepage": "http://mobxjs.github.com/mobx",
|
||||
"devDependencies": {
|
||||
"@types/react-dom": "^16.9.6",
|
||||
"@types/react-router-dom": "^5.1.4",
|
||||
"@types/webpack": "^4.41.10",
|
||||
"css-loader": "^3.5.2",
|
||||
"extract-css-chunks-webpack-plugin": "^4.7.4",
|
||||
"less": "^3.11.1",
|
||||
"less-loader": "^5.0.0",
|
||||
"mini-css-extract-plugin": "^0.9.0",
|
||||
"ts-loader": "6.2.2",
|
||||
"typescript": "^3.8.3",
|
||||
"webpack": "^4.42.1",
|
||||
"webpack-bundle-analyzer": "^3.6.1",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"webpack-dev-server": "^3.10.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"antd": "^4.1.2",
|
||||
"mobx": "^5.15.4",
|
||||
"mobx-react": "^6.2.2",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-router-dom": "5.1.2"
|
||||
}
|
||||
}
|
||||
15
fe/server.js
Normal file
15
fe/server.js
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
var webpack = require('webpack');
|
||||
var WebpackDevServer = require('webpack-dev-server');
|
||||
var config = require('./webpack.config');
|
||||
|
||||
new WebpackDevServer(webpack(config), {
|
||||
publicPath: config.output.publicPath,
|
||||
hot: false,
|
||||
historyApiFallback: true
|
||||
}).listen(3000, 'localhost', function (err, result) {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
|
||||
console.log('Listening at localhost:3000');
|
||||
});
|
||||
16
fe/src/CRE.tsx
Normal file
16
fe/src/CRE.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
// Re-exporting components
|
||||
|
||||
import "antd/es/radio/style";
|
||||
export { default as Radio, RadioChangeEvent } from "antd/es/radio";
|
||||
|
||||
// import "antd/es/row/style";
|
||||
// export { default as Row } from "antd/es/row";
|
||||
|
||||
// import "antd/es/col/style";
|
||||
// export { default as Col } from "antd/es/col";
|
||||
|
||||
import "antd/es/divider/style";
|
||||
export { default as Divider } from "antd/es/divider";
|
||||
|
||||
import "antd/es/message/style";
|
||||
export { default as message } from "antd/es/message";
|
||||
116
fe/src/index.tsx
Normal file
116
fe/src/index.tsx
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import {observable, configure, action} from 'mobx';
|
||||
import {observer} from 'mobx-react';
|
||||
|
||||
import { Radio, RadioChangeEvent, Divider, message } from "./CRE";
|
||||
|
||||
configure({enforceActions: 'always'});
|
||||
|
||||
|
||||
enum HF {
|
||||
LOVHF1 = 54,
|
||||
LOVHF2 = 2,
|
||||
HF1 = 5,
|
||||
HF2 = 6,
|
||||
HF3 = 7,
|
||||
HF4 = 8,
|
||||
HF5 = 9,
|
||||
HF6 = 11
|
||||
}
|
||||
|
||||
enum VHF {
|
||||
VHF1 = 12,
|
||||
VHF2 = 13,
|
||||
VHF3 = 14,
|
||||
VHF4 = 15,
|
||||
VHF5 = 16,
|
||||
VHF6 = 17
|
||||
}
|
||||
|
||||
// const HFENABLEPIN = 5;
|
||||
|
||||
class AppState {
|
||||
|
||||
@observable hfSelection: HF;
|
||||
@observable vhfSelection: VHF;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
@action.bound
|
||||
setHF(selection: HF) {
|
||||
this.hfSelection = selection;
|
||||
}
|
||||
|
||||
@action.bound
|
||||
setVHF(selection: VHF) {
|
||||
this.vhfSelection = selection;
|
||||
}
|
||||
}
|
||||
|
||||
@observer
|
||||
class TimerView extends React.Component<{appState: AppState}, {}> {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Divider>LoVHF / HF selection</Divider>
|
||||
<Radio.Group buttonStyle="solid" onChange={this.changeHF}>
|
||||
<Radio.Button value={HF.LOVHF1}>LoVHF1</Radio.Button>
|
||||
<Radio.Button value={HF.LOVHF2}>LoVHF2</Radio.Button>
|
||||
<Radio.Button value={HF.HF1}>HF1</Radio.Button>
|
||||
<Radio.Button value={HF.HF2}>HF2</Radio.Button>
|
||||
<Radio.Button value={HF.HF3}>HF3</Radio.Button>
|
||||
<Radio.Button value={HF.HF4}>HF4</Radio.Button>
|
||||
<Radio.Button value={HF.HF5}>HF5</Radio.Button>
|
||||
<Radio.Button value={HF.HF6}>HF6</Radio.Button>
|
||||
</Radio.Group>
|
||||
|
||||
<Divider>VHF selection</Divider>
|
||||
<Radio.Group buttonStyle="solid" onChange={this.changeVHF}>
|
||||
<Radio.Button value={VHF.VHF1}>VHF1</Radio.Button>
|
||||
<Radio.Button value={VHF.VHF2}>VHF2</Radio.Button>
|
||||
<Radio.Button value={VHF.VHF3}>VHF3</Radio.Button>
|
||||
<Radio.Button value={VHF.VHF4}>VHF4</Radio.Button>
|
||||
<Radio.Button value={VHF.VHF5}>VHF5</Radio.Button>
|
||||
<Radio.Button value={VHF.VHF6}>VHF6</Radio.Button>
|
||||
</Radio.Group>
|
||||
<br></br>
|
||||
<br></br>
|
||||
<br></br>
|
||||
HF: {this.props.appState.hfSelection}
|
||||
<br></br>
|
||||
VHF: {this.props.appState.vhfSelection}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@action.bound
|
||||
async changeHF(e: RadioChangeEvent) {
|
||||
this.props.appState.setHF(e.target.value);
|
||||
const res = await fetch(`http://192.168.9.4/`, {
|
||||
method: "POST",
|
||||
headers: {},
|
||||
body: String.fromCharCode(Number(e.target.value) + 65)
|
||||
});
|
||||
if (res.ok) {
|
||||
message.success("HF change sent!");
|
||||
}
|
||||
}
|
||||
|
||||
@action.bound
|
||||
async changeVHF(e: RadioChangeEvent) {
|
||||
this.props.appState.setVHF(e.target.value);
|
||||
const res = await fetch(`http://192.168.9.4/`, {
|
||||
method: "POST",
|
||||
headers: {},
|
||||
body: String.fromCharCode(Number(e.target.value) + 65)
|
||||
});
|
||||
if (res.ok) {
|
||||
message.success("VHF change sent!");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const appState = new AppState();
|
||||
ReactDOM.render(<TimerView appState={appState} />, document.getElementById('root'));
|
||||
14
fe/tsconfig.json
Normal file
14
fe/tsconfig.json
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"removeComments": true,
|
||||
"experimentalDecorators": true,
|
||||
"jsx": "react",
|
||||
"outDir": "dist",
|
||||
"lib": ["dom", "es2015"]
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"static"
|
||||
]
|
||||
}
|
||||
59
fe/webpack.config.js
Normal file
59
fe/webpack.config.js
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
var path = require('path');
|
||||
var webpack = require('webpack');
|
||||
|
||||
const ExtractCssChunks = require('extract-css-chunks-webpack-plugin');
|
||||
// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
||||
|
||||
module.exports = {
|
||||
// devtool: 'eval',
|
||||
// mode: 'development',
|
||||
mode: 'production',
|
||||
entry: [
|
||||
// 'webpack-dev-server/client?http://localhost:3000',
|
||||
'./src/index'
|
||||
],
|
||||
output: {
|
||||
path: path.join(__dirname, 'dist'),
|
||||
filename: 'bundle.js',
|
||||
publicPath: '/static/'
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.ts', '.tsx'],
|
||||
alias: { mobx: __dirname + "/node_modules/mobx/lib/mobx.es6.js" }
|
||||
},
|
||||
plugins: [
|
||||
new ExtractCssChunks({
|
||||
filename: '[name].css',
|
||||
chunkFilename: '[id].css',
|
||||
})
|
||||
],
|
||||
module: {
|
||||
rules: [{
|
||||
test: /\.tsx?$/,
|
||||
loader: "ts-loader",
|
||||
include: path.join(__dirname, 'src')
|
||||
},
|
||||
{
|
||||
test: /\.less$/,
|
||||
use: [
|
||||
{
|
||||
loader: ExtractCssChunks.loader
|
||||
},
|
||||
{
|
||||
loader: 'css-loader'
|
||||
},
|
||||
{
|
||||
loader: 'less-loader',
|
||||
options: {
|
||||
javascriptEnabled: true
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.css$/i,
|
||||
use: [ExtractCssChunks.loader, 'css-loader'],
|
||||
},
|
||||
]
|
||||
}
|
||||
};
|
||||
5503
fe/yarn.lock
Normal file
5503
fe/yarn.lock
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue