Skip to content

Instantly share code, notes, and snippets.

@hurricanepkt
Forked from synaptiko/index.html
Last active December 22, 2015 00:58
Show Gist options
  • Save hurricanepkt/6392642 to your computer and use it in GitHub Desktop.
Save hurricanepkt/6392642 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<style>
label {
display: inline-block; width: 100px; height: 20px; float: left; text-align: left;
}
input {
display: inline-block; width: 25%; height: 20px;
}
input.value {
width: 60px;
}
input.checkbox {
width: 20px;
}
strong {
margin-left: 10px;
height: 20px;
}
</style>
</head>
<body>
<h1> Marks Servo</h1>
<label for="servo">Servo</label><input id="servo" type="range" min="0" max="348" value="180"><input id="servo_value" class="value" type="number" min="0" max="348" value="180">
<br />
<span>Real frequency<strong id="real_frequency">0</strong></span>
<script>
var servo = document.getElementById('servo');
var servoValue = document.getElementById('servo_value');
var allFields = [ servo];
bindRangeChange(servo, servoValue);
function bindRangeChange(rangeField, numericField) {
rangeField.addEventListener('change', onRangeChange.bind(rangeField, numericField), false);
numericField.addEventListener('change', onRangeChange.bind(numericField, rangeField), false);
}
function onRangeChange(valueEl) {
valueEl.value = this.value;
}
bindChange(servoValue);
function bindChange(field) {
field.addEventListener('change', onChange.bind(field), false);
}
function onChange() {
var id = this.id.replace(/_value$/, '');
var value = this.value;
sender(id, value);
}
function sender(str, val) {
var xhr = new XMLHttpRequest();
xhr.open('GET', ['/set?', str, '=', val].join(''), true);
xhr.addEventListener('readystatechange', function() {
if (xhr.readyState === 4) {
console.log('set:', str, '=', value, '->', 'result:', xhr.responseText);
}
}, false);
xhr.send();
}
function initialSettings() {
sender('active',1);
sender('delayed',0);
sender('mode', 'pwm');
sender('servo_max',360);
sender('servo',180);
sender('duty',50);
sender('frequency',100);
sender('mcf',16000);
allFields.forEach(function (field) {
onChange.call(field);
bindChange(field);
});
}
initialSettings();
</script>
<script>
var realFrequency = document.getElementById('real_frequency');
function connect() {
var source = new EventSource('/listen');
var eventName = 'real_frequency';
source.addEventListener(eventName, function(event) {
realFrequency.textContent = JSON.parse(event.data)[eventName];
}, false);
source.addEventListener('open', function(event) {
console.log('SSE connection opened');
}, false);
}
connect();
</script>
</body>
</html>
var fs = require('fs');
var path = require('path');
var basePath = '/sys/class/rpi-pwm/pwm0/';
//var basePath = path.join(__dirname, 'test-pwm0');
function set(object, callback) {
// code is written only for one key in object!!!
Object.keys(object).forEach(function(name) {
var value = object[name] + '';
fs.writeFile(path.join(basePath, name), value, { encoding: 'ascii' }, function(error) {
if (error) return console.error(error);
get(name, callback);
});
});
}
function get(name, callback) {
fs.readFile(path.join(basePath, name), { encoding: 'ascii' }, function(error, data) {
if (error) return console.error(error);
var result = {};
result[name] = data.trim();
callback(result);
});
}
module.exports = {
set: set,
get: get
};
#!/usr/bin/env node
var http = require('http');
var fs = require('fs');
var path = require('path');
var url = require('url');
var query = require('querystring');
var sse = require('./sse');
var rpiPwm = require('./rpiPwm');
var app = http.createServer(function(request, response) {
var parsedUrl = url.parse(request.url);
var parsedQuery;
var listenEvent = 'real_frequency';
if (parsedUrl.pathname === '/') {
response.writeHead(200);
fs.readFile(path.join(__dirname, 'index.html'), function(error, buffer) {
response.write(buffer);
response.end();
});
}
else if (parsedUrl.pathname === '/set' && parsedUrl.query) {
parsedQuery = query.parse(parsedUrl.query);
console.log('set', parsedQuery);
rpiPwm.set(parsedQuery, function(result) {
response.writeHead(200, { 'Content-Type': 'text/json' });
response.end(JSON.stringify(result));
});
}
else if (parsedUrl.pathname === '/listen') {
response.connection.setTimeout(1000 * 60 * 20); // max idle 20 min.
sse.writeHead(request, response, function(request, response) {
sse.writeDataContinuosly(request, response, listenEvent, rpiPwm.get, 500);
});
}
else if (parsedUrl.pathname === '/end') {
response.writeHead(200);
response.end();
process.nextTick(function() {
process.exit();
});
}
else {
response.writeHead(404);
response.end();
}
});
app.listen(8080);
function writeHead(request, response, callback) {
response.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
response.write('retry: 500\n');
return callback(request, response);
}
function writeData(request, response, event, data, callback) {
var id = (new Date().getTime());
response.write('id: ' + id + '\n');
response.write('event: ' + event + '\n');
response.write('data: ' + JSON.stringify(data) + '\n\n');
if (callback) {
return callback(request, response);
}
}
function writeDataContinuosly(request, response, event, fn, interval) {
var timeoutId;
var isClosed = false;
fn(event, function writeResult(result) {
if (isClosed) return;
writeData(request, response, event, result, function(request, response) {
if (isClosed) return;
timeoutId = setTimeout(fn.bind(null, event, writeResult), interval);
});
});
request.connection.addListener('close', function() {
isClosed = true;
if (timeoutId !== undefined) {
clearInterval(timeoutId);
}
});
}
module.exports = {
writeHead: writeHead,
writeData: writeData,
writeDataContinuosly: writeDataContinuosly
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment