Run a bash script on a Raspberry via NodeJS - javascript

I am running a local website with NodeJS on my Pi and I want to control a lamp via an 433MHz sender connected to the Pi. I have already written a bash script which works perfectly to control the lamp but I can't find a way to execute it through the HTML site on the node server.
So I am asking whether it is even possible because it doesn't really seem secure to me and how can I implement it in javascript as a function or only on the server side ?

there are many ways you could go about doing something like this but one way would be creating an api so your website can make api calls to the server to turn the light on and off
so here is a simple example
HTML
<html>
<head>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
</head>
<body>
<form>
<input type="button" Value="on" onclick="turnOn()">
<input type="button" value="off" onclick="turnOff()">
</form>
</body>
</html>
<script>
function turnOn(){
$.ajax({
url: 'http://localhost:3000/api/light/on',
type: "GET",
dataType: "json",
success: function (data) {
console.log(data);
},
error: function (error) {
console.log(`Error ${error}`);
}
});
}
function turnOff(){
$.ajax({
url: 'http://localhost:3000/api/light/off',
type: "GET",
dataType: "json",
success: function (data) {
console.log(data);
},
error: function (error) {
console.log(`Error ${error}`);
}
});
}
</script>
SERVER
//server.js
const app = require('express')();
const server = require('http').createServer(app);
var cors = require('cors');
const shell = require('shelljs')
var port = 3000;
server.listen(port, () => console.log(`API server running on ${port}!`))
app.use(cors())
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html')
})
app.get('/api/light/:status', (req, res) => {
var status = req.param('status')
if(status == 'on'){
shell.exec('./turn-light-on')
res.json({success:"light turned on"})
}else{
shell.exec('./turn-light-off')
res.json({success:"light turned off"})
}
})
all you would have to do is change the file that shell.exec() calls for it to work
this app reqires
express
cors
shelljs
to be installed just npm install the names as listed above

Related

AJAX POST request to node JS server not working from IPAD or IPHONE

I have an Apache server running with a website on Windows 10 OS. On button click on the website I make an AJAX POST request to an Express server in Node JS to run some code and return a JSON string. This works fine on my Windows 10 OS.
When I click the button on the website on my IPAD or IPHONE nothing happens. In the command prompt I see no console log of anything reaching the Express server.
Conditions:
Firewall on Windows 10 OS configured to allow incoming data on port 80 and 443 (Apache) and 8000 (Express).
On the IPAD and IPHONE cookies deleted and "Do not allow following" unchecked.
All on the same LAN.
What am I missing here? (next, some code)
Express Server JS
var express = require('express');
var path = require('path');
var app = express();
var cors = require("cors");
var bodyParser = require('body-parser');
const port = 8000;
app.use(bodyParser.json());
app.use(cors());
app.post('/FileName', function (req, res) {
var Fname = req.body.fname;
console.log("received filename: " + Fname);
// Require the module
var EasyFit = require('./dist/easy-fit.js').default;
// Read a .FIT file
var fs = require('fs');
fs.readFile('C:/xampp/htdocs/ATP/FIT/' + Fname + '', function (err, content) {
// Create a EasyFit instance (options argument is optional)
var easyFit = new EasyFit({
force: true,
speedUnit: 'km/h',
lengthUnit: 'km',
temperatureUnit: 'celcius',
elapsedRecordField: true,
mode: 'list',
});
// Parse your file
easyFit.parse(content, function (error, data) {
// Handle result of parse method
if (error) {
console.log(error);
} else {
//res.send(JSON.stringify(data));
res.send(data);
console.log('Parse ok');
}
});
});
})
app.listen(port, '0.0.0.0');
console.log(`FIT app listening at http://localhost:${port}`);
AJAX Request JS on client side
$.ajax({
cache: false,
url: 'http://localhost:8000/FileName',
type: 'POST',
contentType: "application/json",
data: JSON.stringify(data),
success: function(result) {
console.log('received fit in JSON');
console.log(result);
});
You can find out your ip address using a command like this:
ipconfig|findstr IPv4
Then substitute that for localhost
So you will have a line like
url: 'http://192.168.1.131:8000/FileName',
instead of the one that says localhost:8000
After turning off my firewall it worked like a charme. Found the answer in the following post.
https://stackoverflow.com/a/48270227/10440418
Allowed the node.js app to go through my firewall. It works perfectly!

Receive Axios response from POST

I am trying to receive a response from my Node/Express server after making an Axios POST request.
I am able to successfully send a message to my server, where it is logged in console. I am trying to log the server response from my browser (using the code in axios.post.then() below). Any ideas why the response is not logging anything to the console?
-- client side --
<html>
<head>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<button onclick="axiosPost()">Post Test</button>
<script>
function axiosPost() {
axios.post('http://localhost:3000/submitMessage', {
message: "sample message",
}).then(response => {
console.log(response);
})
.catch(error => {
console.log(error);
});
}
</script>
</div>
</body>
</html>
-- server side --
const express = require('express');
const app = express();
const port = 3000;
var path = require('path');
// serves index.html
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname + '/index.html'))
});
app.listen(port, () => console.log(`Listening at http://localhost:${port}`))
// Parse JSON bodies (as sent by API clients)
app.use(express.json());
app.post('/submitMessage', function(request, response){
message = request.body.message;
console.log("Message: " + message);
response.send('Server response message!!');
})
listen to response.data in your front end. Or use simple response.end('Message') at your server side
Well I've never used Axios, but I think you need to return JSON
app.post('/submitMessage', (request, response) => {
message = request.body.message;
console.log("Message: " + message);
response.status(200).json({
status: 200,
ok: true,
data: {
msg: message
// Any data for the response
}
})
})
You can also use Async/Await on the front-end
There's a nice post here you can checkout about it
Looking back, my error was not realizing that there are two consoles: one for my client and one for the server. I was searching my server console for a message logged to my client console.
The message was ultimately being logged to my client console. Thanks to everyone who helped a beginner!

Socket.io - Connect from client to server via https

I have created a socket.io chat application on my virtual server (Ubuntu), which runs as an systemd service and which is active running.
My server.js is located in:
/var/www/vhosts/mywebpage.de/w1.mywebpage.de/chat/
The server.js looks like this:
const io = require('socket.io')(3055);
io.on('connection', function(socket) {
// When the client emits 'addUser', this listens and executes
socket.on('addUser', function(username, room) {
...
});
// When the client emits 'sendMessage', this listens and executes
socket.on('sendMessage', function(msg) {
...
});
// Disconnect the user
socket.on('disconnectUser', function(username, room) {
...
});
});
In my website (https) I try to connect as follow:
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
<script type="text/javascript">
var loSocket;
$(document).ready(function() {
if(typeof(loSocket) == 'undefined') {
loSocket = io('https://w1.mywebpage.de:3055', {
reconnectionAttempts: 5,
forceNew: true
});
}
});
</script>
But I can't get a valid connection.
The developer tools say this:
(failed) ERR_CONNECTION_CLOSED with initiator polling-xhr.js:264.
What could be the error ?
From what I have done in the past I would create a https server which serves the SSL cert and create the socket server using the https server you created, this will allow you to connect via https and you will need to enable secure on socketio (use this question as a ref)
var app = require('http').createServer(handler)
var io = require('socket.io')(app);
var fs = require('fs');
app.listen(80);
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
Use this code as ref on how to create a socketio server using http
You can find this code on the socket.io docs
NOTE: You will need to you https not http like shown in the example

How to read the data from node js post ajax request?

I am trying to send a data from client to server (node js) . I am using ajax .
client :
$("#test_button").on("click",function(){
//alert("shit");
$.ajax(
{url: "http://localhost:4000/ajax_check",
async: false,
type: "POST",
data: "{user:balayya,password:hero}",
success: function(result){
alert("hooli");
}});
});
server:
var app = require('express')();
var express = require('express');
var http = require('http').Server(app);
http.listen(process.env.PORT || 4000, function() {
console.log('listening on *:4000');
});
app.use(express.static('publuc'));
app.get('/', function(req, res) {
console.log("new entry page serving");
res.sendFile(__dirname + '/main.html');
});
app.post('/ajax_check', function(req, res){
console.log("someone came in here");
console.log(req.query.data);
});
the console.log() is printing as "undefined" .
What is the correct way to receive a post request and it's data from the client in node js
Use this npm package - https://www.npmjs.com/package/body-parser
and so server site parse like this:
request.body.{some field name}
Try like this:
$.ajax({
url: "http://localhost:4000/ajax_check",
type: "POST",
data: {
user: "balayya",
password: "hero"
},
success: function(result) {
alert("hooli");
}
});
And on the server use req.body.param_name to read the corresponding parameter value:
app.post('/ajax_check', function(req, res){
console.log("someone came in here");
console.log(req.body.user);
console.log(req.body.password);
});
Also notice that I have removed async: false from your AJAX request because every time someone sets this property to false a poor kitten dies.

nodeJS get Error in simple code

i'm newbie in nodeJS, after successfully installing socket.io by npm command i'm create simple js as this code:
var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
fs = require('fs');
function handler( request, response ) {
fs.readFileSync( __dirname + '/index.html', function( error, data ) {
if( error ) throw error;
response.writeHead(200);
response.end( data );
});
};
app.listen( 1377 )
io.sockets.on( 'connection', function( socket ) {
socket.on( 'loginRequest', function( data ) {
login( data );
});
});
function login( data, socket) {
return socket.emit('loginAnswer', true)
};
this file can be run correctly by node application.js without any problem, now i'm create simple html code:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.socket.io/socket.io-1.3.4.js"></script>
<script>
var socket = io('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
</head>
<body>
<form onsubmit='requestLogin()'>
<input id='username' type='text'>
<input id='password' type='password'>
<input type='submit'>
</form>
</body>
</html>
name of this file is index.html, i'm using xampp and both of files are in htdocs root, htdocs is only have this files, now i'm open localhost:1337 in browser and i get error
after change address to localhost:1337 i get this error:
Unable to connect
Firefox can't establish a connection to the server at localhost:1337.
You use fs.readFileSync where you should use fs.readFile,
also realizing that you listen to port 1377, and try to use port 1337,
in index.html add the port to the socket connection io('http://localhost:1377');

Categories

Resources