123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435 |
- var messageQueue = [];
- var bConfigUpdate = false;
- var dateCheck = new Date();
- var secCurrent = dateCheck.getSeconds();
- // helper functions
- /** Omega -> MCU**/
- // perform the sending to mcu
- function sendMcuCmd (cmd, payload) {
- print ('sendMcuCmd, cmd.length = ' + cmd.length + ' payload.length = ' + payload.length);
- if (cmd.length === 1 && payload.length >= 1) {
- var data = '~' + cmd + payload + ';';
- print('Sending command to mcu: ' + data);
- serialWrite(String(data));
- }
- }
- // --- functions to send commands to the mcu --- //
- function setMcuTime (payload) {
- var serialCmd = 'T';
- sendMcuCmd(serialCmd, String(payload));
- }
- function setMcuHourMode (payload) {
- var serialCmd = 'H';
- var serialPayload = parseInt(payload);
- if (serialPayload === 12 || serialPayload === 24 ) {
- sendMcuCmd(serialCmd, String(serialPayload));
- }
- }
- function setMcuNightLight (payload) {
- var serialCmd = 'L';
- sendMcuCmd(serialCmd, String(parseInt(payload)));
- }
- function setMcuButton (id, payload) {
- var serialCmd = 'b';
- if (typeof id !== 'undefined') {
- var serialPayload = String(id) + String(parseInt(payload));
- sendMcuCmd(serialCmd, String(serialPayload));
- }
- }
- function setMcuButtons (value) {
- var serialCmd = 'l';
- var serialPayload = String(value[0]) + ':' + String(value[1]) + ':' + String(value[2]) + ':' + String(value[3]);
- sendMcuCmd(serialCmd, String(serialPayload));
- }
- function setMcuTimeDisplayBrightness (payload) {
- var serialCmd = 'B';
- sendMcuCmd(serialCmd, String(parseInt(payload)));
- }
- function setMcuDayNightLed (payload) {
- var serialCmd = 'D';
- var serialPayload = ((payload === true || payload === 'true') ? 1 : 0);
- sendMcuCmd(serialCmd, String(serialPayload));
- }
- function setMcuInit () {
- var serialCmd = 'B';
- var serialPayload = '1';
- sendMcuCmd(serialCmd, String(serialPayload));
- }
- // parse mqtt messages
- function handleSetProperty (e) {
- if (typeof e.cmd !== 'undefined' && typeof e.value !== 'undefined') {
- // var serialCmd = '';
- // var serialPayload = '';
- switch (e.cmd) {
- case 'rtc':
- case 'time':
- setMcuTime (e.value);
- break;
- case 'hour mode':
- case 'hourMode':
- // serialPayload = parseInt(e.value);
- // if (serialPayload === 12 || serialPayload === 24 ) {
- // serialCmd = 'H';
- // }
- setMcuHourMode(e.value);
- break;
- case 'nightlight':
- // serialPayload = parseInt(e.value);
- // serialCmd = 'L';
- setMcuNightLight(e.value)
- break;
- case 'button':
- if (typeof e.id !== 'undefined') {
- // serialCmd = 'b';
- // serialPayload = String(e.id) + String(parseInt(e.value));
- setMcuButton(e.id, e.value)
- }
- break;
- case 'buttons':
- if (Array.isArray(e.value) && e.value.length === 4) {
- print('value IS TOTALLY an array of length 4') // debug
- // serialCmd = 'l';
- // serialPayload = String(e.value[0]) + ':' + String(e.value[1]) + ':' + String(e.value[2]) + ':' + String(e.value[3]);
- setMcuButtons(e.value);
- }
- // debug
- else {
- print('value is NOT an array of length 4')
- }
- break;
- case 'brightnessTime':
- case 'timeDisplay':
- // serialCmd = 'B';
- // serialPayload = parseInt(e.value);
- setMcuTimeDisplayBrightness(e.value);
- break;
- case 'day-night-indicator':
- case 'dayNightLed':
- // serialCmd = 'D';
- // serialPayload = ((e.value === true || e.value === 'true') ? 1 : 0);
- setMcuDayNightLed(e.value);
- break;
- case 'init':
- // serialCmd = 'I';
- // serialPayload = '1';
- setMcuInit();
- break;
- default:
- break;
- }
- // if (serialPayload === '') {
- // serialPayload = e.value;
- // }
- //
- // sendMcuCmd(serialCmd, String(serialPayload));
- // TODO: publish ack to set
- }
- }
- /** MCU -> Omega **/
- // decode received button messages
- function decodeButtons(inputStr) {
- var buttons = [];
- var payload = parseInt(inputStr.slice(0,2), 16);
- var duration = parseInt(inputStr.slice(2));
- print('button payload is ' + payload + ', pressed for ' + duration + ' milliseconds');
- // check which buttons have been pressed
- if (payload & 0x01) {
- buttons.push(0);
- }
- if (payload & 0x02) {
- buttons.push(1);
- }
- if (payload & 0x04) {
- buttons.push(2);
- }
- if (payload & 0x08) {
- buttons.push(3);
- }
- if (buttons.length > 0) {
- var obj = {
- id: buttons[0],
- action: 'press',
- duration: duration,
- multitouch: false
- }
- // adjustments for multi-touch case
- if (buttons.length > 1) {
- obj['id'] = payload;
- obj['multitouch'] = true;
- }
- print ('button: ' + JSON.stringify(obj));
- publish('/button', JSON.stringify(obj));
- }
- }
- // decode received gesture messages
- function decodeGesture(inputStr) {
- var direction = ''
- // publish to gesture topic
- switch (inputStr) {
- case 'L':
- direction = 'left';
- break;
- case 'R':
- direction = 'right';
- break;
- case 'U':
- direction = 'up';
- break;
- case 'D':
- direction = 'down';
- break;
- case 'X':
- default:
- direction = 'none';
- break;
- }
- publish('/gesture', JSON.stringify({
- direction: direction
- }))
- // implement card switching
- // TODO: this functionality should be moved to the card manager
- switch (inputStr) {
- // more natural input:
- // gesture left makes card animate leftward
- case 'L':
- direction = 'right';
- break;
- case 'R':
- direction = 'left';
- break;
- default:
- direction = '';
- break;
- }
- if (direction !== '') {
- var msg = {
- cmd: 'select_card',
- action: direction
- };
- print ('gesture: ' + direction)
- publish('/card', JSON.stringify(msg));
- }
- }
- // calculate battery percentage
- var batterySteps = [
- 3.65,
- 3.7,
- 3.78,
- 3.9,
- 4.15
- ];
- function calculateBatteryPercentage(a) {
- var detectedVoltage = a * 3.3 / 1024.0;
- var batteryVoltage = detectedVoltage * 1.49;
- for (var i = batterySteps.length; i >= 0; i--) {
- if (batteryVoltage >= batterySteps[i]) {
- return i;
- }
- }
- // default is empty
- return 0;
- }
- // decode battery voltage(
- function decodeBattery (input) {
- var payload = {
- cmd: 'update',
- elements: [{
- type: 'battery',
- value: calculateBatteryPercentage(input)
- }]
- };
- publish('/status', JSON.stringify(payload));
- }
- function wifiStatus (input) {
- var payload = {
- cmd: 'update',
- elements: [{
- type: 'wifi',
- value: input
- }]
- };
- publish('/status', JSON.stringify(payload));
- }
- // decode time from MCU
- function decodeTime (inputTime) {
- if (inputTime.match(/^\d+$/) !== null) {
- print('received date: ' + inputTime);
- updateSystemTime(inputTime);
- }
- }
- // parse property received from MCU
- function handleReceivedProperty(cmd, payload) {
- switch (cmd) {
- case 'V':
- // battery voltage (0-1023)
- decodeBattery(payload);
- break;
- case 'A':
- // ambient light (0-?)
- // TODO: implement this when supported by hw
- break;
- case 't':
- // touch button
- decodeButtons(payload);
- break;
- case 'G':
- // gesture
- decodeGesture(payload);
- break;
- case 'i':
- // time from RTC
- decodeTime(payload);
- break;
- default:
- print ('Unrecognized command');
- break;
- }
- }
- // parse string of received messages from MCU
- function handleReceivedProperties (msg) {
- var props = msg.split(/\r?\n/);
- props.forEach(function(element) {
- if (element) {
- var components = element.match(/^~(.)(.+);/);
- if (components != null && components.length === 3) {
- print ('cmd: ' + components[1] + ', value: ' + components[2]);
- handleReceivedProperty(components[1], components[2]);
- }
- }
- });
- }
- // config functions to read and implement config changes
- function readConfig() {
- readFile('/etc/config.json', '', function (err, data) {
- if (!err) {
- var config;
- try {
- state = JSON.parse(data);
- } catch(e) {
- print(e); // error in the above string!
- return null;
- }
- // apply the settings from the config file
- if (state.config.hourMode) setMcuHourMode(state.config.hourMode);
- if (typeof(state.config.dayNightLed) == typeof(true)) setMcuDayNightLed(state.config.dayNightLed);
- if (state.config.brightnessTime) setMcuTimeDisplayBrightness(state.config.brightnessTime);
- }
- print('configuration: hourMode = ' + state.config.hourMode + '; dayNightLed = ' + state.config.dayNightLed + '; brightnessTime = ' + state.config.brightnessTime);
- });
- }
- function readWifiHelper(){
- var status;
- readFile('/tmp/wifi-active', '', function (err, data) {
- if (!err) {
- try {
- status = data;
- } catch(e) {
- print(e); // error in the above string!
- return null;
- }
- }
- print('status ' + status);
- });
- if(status.includes("1")){
- wifiStatus(1);
- } else {
- wifiStatus(0);
- }
- }
- // base functions
- function setup() {
- connect('localhost', 1883, null, function () {
- print('subscribing to topic');
- subscribe('/set');
- subscribe('/config/update');
- print('opening serial port');
- openSerialPort("/dev/ttyS1");
- sendMcuCmd ("I", "0");
- });
- sleep(2);
- }
- function loop() {
- // handle any config updates
- if (bConfigUpdate) {
- readConfig()
- bConfigUpdate = false;
- }
- // handle any incoming mqtt messages
- if (messageQueue.length > 0) {
- for (var i = 0; i < messageQueue.length; i++) {
- handleSetProperty(messageQueue[i]);
- }
- messageQueue = [];
- }
- // look for new messages from mcu -- this is a blocking call
- var msg = serialRead();
- if (msg !== null && msg.length > 0) {
- print("received serial message of length " + msg.length + " value is " + msg);
- handleReceivedProperties(msg);
- }
- dateLocal = new Date();
- if((dateLocal.getSeconds() % 15) == 0 && secCurrent != dateLocal.getSeconds()){
- print("update wifi status");
- secCurrent = dateLocal.getSeconds();
- readWifiHelper();
- // check if connected
- // send status message
- }
- }
- function onMessage(e) {
- if (typeof e.topic !== 'undefined' && typeof e.payload !== 'undefined' ) {
- print('message! topic: ' + e.topic + ', value: ' + JSON.stringify(e.payload));
- if (e.topic === '/set') {
- messageQueue.push(e.payload);
- } else if (e.topic === '/config/update') {
- bConfigUpdate = true;
- }
- }
- }
|