Skip to content

Commit 8180f03

Browse files
committed
Add Raspberry PI search
1 parent b2bd25b commit 8180f03

File tree

6 files changed

+152
-7
lines changed

6 files changed

+152
-7
lines changed

index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const MqttBroker = require("./src/background/MqttBroker");
1616
const Settings = require("./src/background/Settings");
1717
const Firmware = require("./src/background/Firmware");
1818
const Gateway = require("./src/background/Gateway");
19+
const Home = require("./src/background/Home");
1920

2021
let windows = [];
2122

@@ -113,13 +114,14 @@ NodeREDWorker.setup().finally(()=>{
113114
windows[i].reload();
114115
}
115116
})
117+
Home.setup();
116118

117119
// Quit when all windows are closed.
118120
app.on("window-all-closed", () => {
119121
console.log("window-all-closed");
120122
if (process.platform != 'darwin'){
121123
console.log("app.quit");
122-
app.quit();
124+
app.quit();
123125
}
124126
});
125127

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@
7171
"artifactName": "bigclown-playground-${version}-${os}-setup-${arch}.${ext}"
7272
},
7373
"dmg": {
74-
"contents": [{
74+
"contents": [
75+
{
7576
"x": 130,
7677
"y": 220
7778
},
@@ -121,13 +122,16 @@
121122
"electron-context-menu": "^0.10.0",
122123
"electron-prompt": "^1.2.0",
123124
"font-awesome": "^4.7.0",
125+
"ip": "^1.1.5",
124126
"is-port-reachable": "^2.0.0",
125127
"mosca": "^2.8.3",
126128
"mqtt": "^2.18.8",
129+
"node-arp": "^1.0.6",
127130
"node-red": "*",
128131
"node-red-contrib-blynk-ws": "^0.7.1",
129132
"node-red-contrib-ifttt": "^0.1.0",
130133
"node-red-dashboard": "*",
134+
"ping": "^0.2.2",
131135
"react": "^16.5.2",
132136
"react-dom": "^16.5.2",
133137
"react-router-dom": "^4.3.1",

src/background/Home.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"use strict";
2+
const { ipcMain, BrowserWindow } = require("electron");
3+
const { hub_list } = require("./../utils/hub");
4+
5+
function setup() {
6+
7+
ipcMain.on("hub/list/get", async (event) => {
8+
console.log("hub/list/get")
9+
hub_list((list)=>{
10+
console.log('hub_list', list);
11+
event.sender.send("hub/list", list);
12+
});
13+
});
14+
}
15+
16+
module.exports = { setup };

src/render/App.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import RadioManager from "./components/RadioManager";
1313
import Firmware from "./components/Firmware";
1414
import Gateway from "./components/Gateway";
1515
import Devices from "./components/Devices";
16+
import Home from "./components/Home";
17+
1618

1719
// Import SCSS
1820
import "../assets/scss/index.scss";
@@ -37,9 +39,9 @@ export default class extends Component {
3739
componentDidMount() {
3840
console.log("App:componentDidMount");
3941

40-
ipcRenderer.on("gateway/status", (sender, gatewayStatus) => {
41-
if (this.state.gatewayStatus != gatewayStatus) {
42-
this.setState({ gatewayStatus });
42+
ipcRenderer.on("gateway/status", (sender, payload) => {
43+
if (this.state.gatewayStatus != payload.status) {
44+
this.setState({ gatewayStatus: payload.status });
4345
}
4446
});
4547
ipcRenderer.on("nodered/status", (sender, noderedStatus) => {
@@ -85,7 +87,7 @@ export default class extends Component {
8587
<aside className={this.state.visible ? "fade-in" : "fade-out"}>
8688
<nav>
8789
<NavLink exact to="/">{i18n.__("home")}</NavLink>
88-
<NavLink to="/devices" title={gwOffline ? "No Radio USB Dongle connected" : null}>{i18n.__("Devices")} {gwOffline ? <i className="fa fa-warning"></i> : null}</NavLink>
90+
<NavLink to="/devices" title={gwOffline ? "No Radio Dongle connected" : null}>{i18n.__("Devices")} {gwOffline ? <i className="fa fa-warning"></i> : null}</NavLink>
8991
<NavLink to="/functions" title={nodeRedOffline ? "Node-RED is shut down": null}>{i18n.__("Functions")} {nodeRedOffline ? <i className="fa fa-warning"></i> : null}</NavLink>
9092
<NavLink to="/dashboard">{i18n.__("dashboard")}</NavLink>
9193
<NavLink to="/messages" title={mqttOffline ? "Mqtt brouker is shut down" : null}>{i18n.__("Messages")} {mqttOffline ?<i className="fa fa-warning"></i> : null}</NavLink>
@@ -102,7 +104,7 @@ export default class extends Component {
102104
</div>
103105

104106
<main key="main">
105-
<RouteIframe path="/" exact src="https://start.bigclown.com/" />
107+
<Home path="/" exact/>
106108
<Route path="/settings" component={Settings}/>
107109
<RouteWithProps path="/devices" component={Devices} model={this.radiomanager} />
108110
<RouteIframe path="/functions" src="http://localhost:1880/" id="node-red" />

src/render/components/Home.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import React, { Component } from "react";
2+
import PropTypes from 'prop-types'
3+
import { withRouter } from "react-router-dom";
4+
import { ipcRenderer, shell } from "electron";
5+
import { Alert } from 'reactstrap';
6+
7+
class HomeComponent extends Component {
8+
static propTypes = {
9+
match: PropTypes.object.isRequired,
10+
location: PropTypes.object.isRequired,
11+
history: PropTypes.object.isRequired,
12+
path: PropTypes.string.isRequired,
13+
}
14+
15+
constructor(props) {
16+
super(props);
17+
this.state = {
18+
hub_list : []
19+
}
20+
}
21+
22+
componentDidMount() {
23+
console.log("Home componentDidMount");
24+
ipcRenderer.on("hub/list", (sender, hub_list) => {
25+
console.log('hub_list', hub_list);
26+
this.setState({ hub_list });
27+
});
28+
ipcRenderer.send("hub/list/get");
29+
}
30+
31+
componentWillUnmount() {
32+
console.log("Home componentWillUnmount");
33+
ipcRenderer.removeAllListeners("hub/list");
34+
}
35+
36+
componentDidUpdate() {
37+
console.log("Home componentDidUpdate");
38+
}
39+
40+
render() {
41+
const { location, path } = this.props;
42+
43+
return (
44+
<div id="home" style={{display: location.pathname == path ? "block" : "none"}}>
45+
{this.state.hub_list.length ? <Alert color="primary">
46+
{this.state.hub_list.map((ip)=>{
47+
return <div key={ip}>Found Raspberry PI click for open in browser <b style={{cursor:"pointer"}} onClick={()=>{shell.openExternal("http://" + ip);}}>{ip}</b></div>
48+
})}
49+
</Alert> : null}
50+
<iframe src="https://start.bigclown.com/" className="route" ></iframe>
51+
</div>)
52+
}
53+
}
54+
55+
module.exports = withRouter(HomeComponent);

src/utils/hub.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
"use strict";
2+
3+
const os = require("os");
4+
const ip = require("ip");
5+
const ping = require('ping');
6+
const arp = require("node-arp");
7+
8+
function hub_list(callback) {
9+
let networks = [];
10+
let myAddress = [];
11+
12+
var interfaces = os.networkInterfaces();
13+
for (let name in interfaces) {
14+
interfaces[name].map((inet) => {
15+
if (inet.internal) return;
16+
if (inet.family != 'IPv4') return;
17+
18+
myAddress.push(inet.address);
19+
20+
for (let i in networks) {
21+
if (networks[i].contains(inet.address)) {
22+
return;
23+
}
24+
}
25+
26+
networks.push(ip.cidrSubnet(inet.cidr))
27+
});
28+
}
29+
30+
// console.log(networks);
31+
32+
let cnt = 0;
33+
let list = [];
34+
35+
networks.map(async (network) => {
36+
for(let i = ip.toLong(network.firstAddress), l = ip.toLong(network.lastAddress); i < l + 1; i++){
37+
let address = ip.fromLong(i)
38+
if (myAddress.indexOf(address) != -1) continue;
39+
40+
cnt++;
41+
42+
ping.sys.probe(address, function(isAlive){
43+
if (!isAlive){
44+
cnt--;
45+
if (cnt == 0) {
46+
callback(list);
47+
}
48+
return;
49+
}
50+
51+
arp.getMAC(address, (error, mac) => {
52+
if ( mac.startsWith("b8:27:eb")) {
53+
list.push(address);
54+
}
55+
cnt--;
56+
57+
if (cnt == 0) {
58+
callback(list);
59+
}
60+
});
61+
}, {timeout: 1});
62+
}
63+
});
64+
}
65+
66+
module.exports = { hub_list }

0 commit comments

Comments
 (0)