Skip to content

Instantly share code, notes, and snippets.

@Hexagon
Created November 24, 2014 19:00
Show Gist options
  • Save Hexagon/7e4230a58807304c61ec to your computer and use it in GitHub Desktop.
Save Hexagon/7e4230a58807304c61ec to your computer and use it in GitHub Desktop.
var sqlite3 = require('sqlite3'),
config = require('./config.json'),
datasource = require('./datasource.js'),
util = require('util');
module.exports = {
Init: function (callback) {
this.queries = Array();
this.queries['create_log_value_table'] = 'CREATE TABLE %s (id INTEGER PRIMARY KEY, value INT, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP)';
this.queries['create_state_value_table'] = 'CREATE TABLE states (id INTEGER PRIMARY KEY, name TEXT, value INT)';
this.queries['store_state_value'] = 'INSERT INTO states (name, value) VALUES ("%s", "%s")';
this.queries['update_state_value'] = 'UPDATE states SET value = "%s" WHERE name = "%s"';
this.queries['remove_state_value'] = 'DELETE FROM states WHERE name = "%s"';
this.queries['store_log_value'] = 'INSERT INTO %s (value) VALUES ("%s")';
this.queries['create_command_table_query'] = 'CREATE TABLE commands (command_string TEXT)';
this.queries['get_commands_query'] = 'SELECT * FROM commands';
this.queries['clear_command_table'] = 'DELETE FROM commands';
callback();
},
readSerialLine: function (device, callback) {
var recv = "",
ch = '';
while(true) {
ch = device.read();
if (ch != '\r')
recv += ch;
if (ch == '\n')
callback(recv);
return;
}
},
createLogTable: function (table, callback) {
datasource.db.run(util.format(create_log_value_table,table), function() {
callback();
});
},
createStateTable: function (callback) {
datasource.db.run(create_state_value_table, function () {
callback();
});
},
createCommandTable: function (callback) {
datasource.db.run(create_command_table_query, function() {
callback();
});
},
insertState: function (name, value, callback) {
datasource.db.run(util.format(remove_state_value,name),function () {
datasource.db.run(util.format(store_state_value,name,value),function () {
callback();
});
});
},
insertLogRow: function (table, value, callback) {
datasource.db.run(util.format(store_log_value,table,value), function() {
callback();
});
},
storeLogRow: function (data, callback) {
var result = data.split("=");
try {
insertLogRow(result[0], result[1], callback);
} catch (e) {
createLogTable(table);
insertLogRow(result[0], result[1], callback);
}
},
storeState: function (data,callback) {
var result = data.split("=");
try {
insertState(result[0], result[1], callback);
} catch (e) {
createStateTable(table);
insertState(result[0], result[1], callback);
}
},
parseReport: function (report, callback) {
for (row in report) {
var result = row.split(' ');
if (result[0] == 'log_value') {
storeLogRow(result[1],callback);
}
if (result[0] == 'state') {
storeState(result[1],callback);
}
}
},
parseResponse: function (device, callback) {
var done = false,
report = Array();
while(!done) {
recv = readSerialLine(device);
if (recv == '\n') {
done = true;
} else {
report.push(recv);
}
}
if (report.length > 0) {
parseReport(report,callback);
} else {
callback();
}
},
getReport: function (device, callback) {
// ToDo: Node-agnostic
device.write('get-report\n');
// ToDo: Run callback on success
},
getStates: function (device, callback) {
// ToDo: Node-agnostic
device.write('get-states\n');
// ToDo: Run callback on success
},
getCommands: function (callback,err) {
datasource.db.all(get_commands_query,
function(err, data){
if(!err)
{
callback(data);
} else {
err();
}
}
);
},
doCommandsCallback: function (commands, callback) {
var commands = [],
anythingDone = false;
for (command in commands) {
device.write(str(command))
device.write('\n')
anything_done = true;
}
datasource.db.run(clear_command_table);
if (anything_done) {
getStates(device,callback());
} else {
callback();
}
},
doCommands: function (device, callback) {
getCommands(
function(data) {
doCommandsCallback(data);
},
function(err) {
createCommandTable(function() {
getCommands(function(data) {
doCommandsCallback(data);
});
});
}
);
},
updateLight: function (device, callback) {
// TODO: The rest
var day_secs = 86400.0,
hour_secs = 3600.0,
now = datetime.datetime.now(),
midnight = datetime.datetime.combine(now.date(), datetime.time(0)),
delta = now - midnight,
light = 0.0,
current_hour = delta.seconds / 3600.0 - 12;
if math.fabs(current_hour) < config.light_hours / 2:
light = config.light_max
elif math.fabs(current_hour) < (config.light_hours/2) + config.light_fade_hours:
sign = current_hour / current_hour
fade_amount = (math.fabs(current_hour) - (config.light_hours/2)) * sign
fade_amount = fade_amount / config.light_fade_hours
light = (math.cos(fade_amount * math.pi) + 1.0) / 2.0 * config.light_max
else:
light = 0.0
device.write("set-light-value " + str(light) + "\n");
}
};
def update_light(device):
day_secs = 86400.0
hour_secs = 3600.0
now = datetime.datetime.now()
midnight = datetime.datetime.combine(now.date(), datetime.time(0))
delta = now - midnight
light = 0.0
current_hour = delta.seconds / 3600.0 - 12
if math.fabs(current_hour) < config.light_hours / 2:
light = config.light_max
elif math.fabs(current_hour) < (config.light_hours/2) + config.light_fade_hours:
sign = current_hour / current_hour
fade_amount = (math.fabs(current_hour) - (config.light_hours/2)) * sign
fade_amount = fade_amount / config.light_fade_hours
light = (math.cos(fade_amount * math.pi) + 1.0) / 2.0 * config.light_max
else:
light = 0.0
device.write("set-light-value " + str(light) + "\n");
dev = serial.Serial(config.serial_device, baudrate=115200, timeout=3.0)
next_update = datetime.datetime.now()
dev.flushInput()
# Wait for the Arduino to boot...
time.sleep(5)
while True:
current_time = datetime.datetime.now()
if current_time > next_update:
update_light(dev)
get_report(dev)
next_update = current_time + config.update_interval
else:
do_commands(dev)
time.sleep(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment