Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Bugfixes and improvements (#17)
* Fix for low number of BGs and offset

Fixes crash when actual number of BGs in monitor/glucose.json is fewer than the number we want to display (72 or 120). Thanks to @mhaeberli for catching & patching! Also fixes graph offset so we have a continuous line of BGs.

* customizations for jon's production rig

* various personalizations and possible improvements

* revert screenoff code and add pump status to screen

* status screen improvements and bugfixes

* Update README.md

* improvements, bugfixes, and exit on display malfunction

* Clearer error messages

* comments

* fixing error handling when only writing to the screen once

* bugfixes

* stop calling status scripts from the commandline

* use socket server to control display

* improvements and bugfixes

* status screen for cas

* nice typo

* Remove custom rig code

* revert readme

* fixes and improvements

* Revert "upgrade jon-dev with node pi buttons"

* Don't crash if buttons are pressed & screen broken

This should help keep openaps-menu from crashing when the screen is broken.

* bugfixes and add preferences toggle for status

* more preferences, update big_bg_status.js

* Update README.md

* Update menu.json

* Delete casstatus.js

* Revert package.json

Bryan merged upstream bugfixes...

* Remove comma

Random comma?

* Add preferences switch info

* Add 8am-8pm invert display option.

* Add 8am-8pm invert display option.

* Variable name bugfix

* Logic fix for day/night inversion

* Logic fix for day/night inversion
  • Loading branch information
cluckj authored Jan 30, 2019
commit 7c7ca4dae2624af2cc276877ae6e59d470921d87
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@ This is the repository holding the menu-based software code, which you may choos

See [here](https://github.com/EnhancedRadioDevices/Explorer-HAT) for more details on the Explorer HAT hardware.

You can set your preferred auto-updating status screen using the following setting in your `~/myopenaps/preferences.json`:

`"status_screen": "bigbgstatus"` will display the big BG status screen (no graph).

`"status_screen": "off"` will turn the auto-updating screen off.


By default, the auto-updating status script will invert the display about 50% of the time, to prevent burn-in on the OLED screen. You can turn this off with the following setting in your `~/myopenaps/preferences.json`:

`"wearOLEDevenly": "off"`

Or you can have it invert the display from 8pm to 8am with:

`"wearOLEDevenly": "nightandday"`


## Example screen outputs (Note: these are examples. The latest code may yield different menu items and screen displays)

### Status screen:
Expand Down
10 changes: 6 additions & 4 deletions config/menus/menu.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
"menu": [
{
"label": "Status Graph",
"command": "node scripts/status.js",
"emit": "nothing"
"emit": "showgraphstatus"
},
{
"label": "Big BG Status",
"emit": "showbigBGstatus"
},
{
"label": "Set Temp Target",
Expand Down Expand Up @@ -54,8 +57,7 @@
},
{
"label": "Unicorn Logo",
"command": "node scripts/unicorn.js",
"emit": "nothing"
"emit": "showlogo"
}
]
},
Expand Down
76 changes: 58 additions & 18 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,22 @@ const i2c = require('i2c-bus');
const path = require('path');
const pngparse = require('pngparse');
const extend = require('extend');
var fs = require('fs');

var i2cBus = i2c.openSync(1);

var openapsDir = "/root/myopenaps"; //if you're using a nonstandard OpenAPS directory, set that here. NOT RECOMMENDED.

// setup the display
var displayConfig = require('./config/display.json');
displayConfig.i2cBus = i2cBus;
var display = require('./lib/display/ssd1306')(displayConfig);

// display the logo
pngparse.parseFile('./static/unicorn.png', function(err, image) {
if(err)
throw err
display.clear();
display.oled.drawBitmap(image.data);
});
try {
var display = require('./lib/display/ssd1306')(displayConfig);
displayImage('./static/unicorn.png'); //display logo
} catch (e) {
console.warn("Could not setup display:", e);
}

// setup battery voltage monitor
var voltageConfig = require('./config/voltage.json')
Expand All @@ -44,8 +45,36 @@ socketServer
.on('warning', (warn) => {
console.log('socket-server warning: ', warn.reason)
})
.on('displaystatus', function () {
if (display) {
var preferences;
fs.readFile(openapsDir+'/preferences.json', function (err, data) {
if (err) throw err;
preferences = JSON.parse(data);
if (preferences.status_screen == "bigbgstatus") {
bigBGStatus(display, openapsDir);
} else if (preferences.status_screen == "off") {
//don't auto-update the screen if it's turned off
} else {
graphStatus(display, openapsDir); //default to graph status
}
});
}
})

function displayImage(pathToImage) {
pngparse.parseFile(pathToImage, function(err, image) {
if(err)
throw err
display.clear();
display.oled.drawBitmap(image.data);
});
}

// load up graphical status scripts
const graphStatus = require('./scripts/status.js');
const bigBGStatus = require('./scripts/big_bg_status.js');
// if you want to add your own status display script, it will be easiest to replace one of the above!

// setup the menus
var buttonsConfig = require('./config/buttons.json');
Expand All @@ -64,6 +93,15 @@ var hidMenu = require('./lib/hid-menu/hid-menu')(buttonsConfig, menuConfig);
hidMenu
.on('nothing', function () {
})
.on('showgraphstatus', function () {
graphStatus(display, openapsDir);
})
.on('showbigBGstatus', function () {
bigBGStatus(display, openapsDir);
})
.on('showlogo', function () {
displayImage('./static/unicorn.png');
})
.on('showvoltage', function () {
voltage()
.then(function (v) {
Expand All @@ -85,16 +123,18 @@ hidMenu

// display the current menu on the display
function showMenu(menu) {
display.clear();
var text = '';
if (display) {
display.clear();
var text = '';

var p = menu.getParentSelect();
text += p ? '[' + p.label + ']\n' : '';
var c = menu.getCurrentSelect();
menu.getActiveMenu().forEach(function (m) {
text += (m.selected ? '>' : ' ') + m.label + '\n';
});
var p = menu.getParentSelect();
text += p ? '[' + p.label + ']\n' : '';
var c = menu.getCurrentSelect();
menu.getActiveMenu().forEach(function (m) {
text += (m.selected ? '>' : ' ') + m.label + '\n';
});

// console.log(text);
display.write(text);
// console.log(text);
display.write(text);
}
}
5 changes: 5 additions & 0 deletions lib/socket-server/socket-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ module.exports = function (config) {

try {
switch (cmd.command) {
case 'status':
emitter.emit('displaystatus');
socketServer.clientWrite(client, 200, 'Success', 'HAT Display Updated');
break;

case 'read_voltage':
require('./commands/read_voltage')(config)
.then((response) => {
Expand Down
166 changes: 166 additions & 0 deletions scripts/big_bg_status.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
var fs = require('fs');
var font = require('oled-font-5x7');

// Rounds value to 'digits' decimal places
function round(value, digits)
{
if (! digits) { digits = 0; }
var scale = Math.pow(10, digits);
return Math.round(value * scale) / scale;
}

function convert_bg(value, profile)
{
if (profile != null && profile.out_units == "mmol/L")
{
return round(value / 18, 1).toFixed(1);
}
else
{
return Math.round(value);
}
}

function stripLeadingZero(value)
{
var re = /^(-)?0+(?=[\.\d])/;
return value.toString().replace( re, '$1');
}

module.exports = bigbgstatus;

//
//Start of status display function
//

function bigbgstatus(display, openapsDir) {

display.oled.clearDisplay(true); //clear the buffer

//Parse all the .json files we need
try {
var profile = JSON.parse(fs.readFileSync(openapsDir+"/settings/profile.json"));
} catch (e) {
// Note: profile.json is optional as it's only needed for mmol conversion for now. Print an error, but not return
console.error("Status screen display error: could not parse profile.json: ", e);
}
try {
var batterylevel = JSON.parse(fs.readFileSync(openapsDir+"/monitor/edison-battery.json"));
} catch (e) {
console.error("Status screen display error: could not parse edison-battery.json: ", e);
}
try {
var suggested = JSON.parse(fs.readFileSync(openapsDir+"/enact/suggested.json"));
} catch (e) {
console.error("Status screen display error: could not parse suggested.json: ", e);
}
try {
var bg = JSON.parse(fs.readFileSync(openapsDir+"/monitor/glucose.json"));
} catch (e) {
console.error("Status screen display error: could not parse glucose.json: ", e);
}
try {
var iob = JSON.parse(fs.readFileSync(openapsDir+"/monitor/iob.json"));
} catch (e) {
console.error("Status screen display error: could not parse iob.json: ", e);
}
try {
var cob = JSON.parse(fs.readFileSync(openapsDir+"/monitor/meal.json"));
} catch (e) {
console.error("Status screen display error: could not parse meal.json: ", e);
}
try {
var stats = fs.statSync("/tmp/pump_loop_success");
} catch (e) {
console.error("Status screen display error: could not find pump_loop_success");
}

if(batterylevel) {
//Process and display battery gauge
display.oled.drawLine(116, 57, 127, 57, 1, false); //top
display.oled.drawLine(116, 63, 127, 63, 1, false); //bottom
display.oled.drawLine(116, 57, 116, 63, 1, false); //left
display.oled.drawLine(127, 57, 127, 63, 1, false); //right
display.oled.drawLine(115, 59, 115, 61, 1, false); //iconify
var batt = Math.round(batterylevel.battery / 10);
display.oled.fillRect(127-batt, 58, batt, 5, 1, false); //fill battery gauge
}

//calculate timeago for BG
if(bg && profile) {
var startDate = new Date(bg[0].date);
var endDate = new Date();
var minutes = Math.round(( (endDate.getTime() - startDate.getTime()) / 1000) / 60);
if (bg[0].delta) {
var delta = Math.round(bg[0].delta);
} else if (bg[1] && bg[0].date - bg[1].date > 200000 ) {
var delta = Math.round(bg[0].glucose - bg[1].glucose);
} else if (bg[2] && bg[0].date - bg[2].date > 200000 ) {
var delta = Math.round(bg[0].glucose - bg[2].glucose);
} else if (bg[3] && bg[0].date - bg[3].date > 200000 ) {
var delta = Math.round(bg[0].glucose - bg[3].glucose);
} else {
var delta = 0;
}

//display BG number, add plus sign if delta is positive
display.oled.setCursor(0,0);
if (delta >= 0) {
display.oled.writeString(font, 3, ""+convert_bg(bg[0].glucose, profile), 1, false, 0, false);
display.oled.writeString(font, 1, "+"+stripLeadingZero(convert_bg(delta, profile)), 1, false, 0, false);
display.oled.writeString(font, 2, " "+minutes+"m", 1, false, 0, false);
} else {
display.oled.writeString(font, 3, ""+convert_bg(bg[0].glucose, profile), 1, false, 0, false);
display.oled.writeString(font, 1, ""+stripLeadingZero(convert_bg(delta, profile)), 1, false, 0, false);
display.oled.writeString(font, 2, " "+minutes+"m", 1, false, 0, false);
}
}

//calculate timeago for last successful loop
if(stats) {
var date = new Date(stats.mtime);
var hour = date.getHours();
hour = (hour < 10 ? "0" : "") + hour;
var min = date.getMinutes();
min = (min < 10 ? "0" : "") + min;

//display last loop time
display.oled.setCursor(0,57);
display.oled.writeString(font, 1, "Last loop at: "+hour+":"+min, 1, false, 0, false);
}

//parse and render COB/IOB
if(iob && cob) {
display.oled.setCursor(0,23);
display.oled.writeString(font, 1, "IOB:", 1, false, 0, false);
display.oled.writeString(font, 2, " "+iob[0].iob+'U', 1, false, 0, false);
display.oled.setCursor(0,39);
display.oled.writeString(font, 1, "COB:", 1, false, 0, false);
display.oled.writeString(font, 2, " "+cob.mealCOB+'g', 1, false, 0, false);
}

display.oled.dimDisplay(true); //dim the display
display.oled.update(); // write buffer to the screen

fs.readFile(openapsDir+"/preferences.json", function (err, data) {
if (err) throw err;
preferences = JSON.parse(data);
if (preferences.wearOLEDevenly.includes("off")) {
display.oled.invertDisplay(false);
}
else if (preferences.wearOLEDevenly.includes("nightandday") && (hour >= 20 || hour <= 8)) {
display.oled.invertDisplay(false);
}
else if (preferences.wearOLEDevenly.includes("nightandday") && (hour <= 20 && hour >= 8)) {
display.oled.invertDisplay(true);
}
else {
display.oled.invertDisplay((endDate % 2 == 1));
}
});

//
}//End of status display function
//


7 changes: 4 additions & 3 deletions scripts/getip.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/bin/bash

IP=$(ip -f inet -o addr show wlan0|cut -d\ -f 7 | cut -d/ -f 1)
echo -e "Current IP Address:\n$IP\n"
echo -e "To connect: ssh\npi@$IP\n"
wlan0IP=$(ip -f inet -o addr show wlan0|cut -d\ -f 7 | cut -d/ -f 1)
bnep0IP=$(ip -f inet -o addr show bnep0|cut -d\ -f 7 | cut -d/ -f 1)
echo -e "Current WiFi IP:\n$wlan0IP\n"
echo -e "Current BT IP:\n$bnep0IP\n"
Loading