Add insulin/glucose readings #89
Replies: 4 comments
-
What do you exactly do? |
Beta Was this translation helpful? Give feedback.
-
What do you exactly do?
I have added code to watchserver.cpp to accept a URL of the form:
http://192.168.0.61:17580/extras/setvalue?blood=89&fastinsulin=75&time=xxxxxxxxx
this will set BG to 89 and fast insulin to 75 at time = xxxxxxx (unix time)
What information does the bar scanner receive?
The scanner scans either the barcode or QR code on my insulin pens. I use
Lantus and Humalog. I don't know if other brands have bar codes on them.
If not, simple matter to go online generate a bar code, then print to a
sheet of
stickers, and then stick onto the pen, vial, or pill container.
Right now it only indicates an application, not the amount. In
the future might implement a feature where if you scan the barcode multiple
times
within 1 minute, take number of times and multiply by 10 to get insulin
units.
If you don't have a barcode reader, you could use stick-on NFC tags(would
need to write an app to read NFC tags)
For what do you monitor Bluetooth?
I have developed an app (written in c#) that connects and listens to
BLE enabled glucose readers(happy to share), once I get the BG reading
I update Juglucco using above URL
What do you do with finger-prick measurement?
I use the above URL to update Juggluco Linux app, I then mirror this
data to another phone running Juggluco which has the CGM data. This
phone merges the data and presents it to the user. Would be nice
not to have to run Juggluco app and update phone directly.
Yes, I am interested in the changes you made. From what version of Juggluco
is it a modification?
My best guess for version is 4.18.0 downloaded on 6/26/2023
Here are the changes I made, Insert the following in file watchserver.cpp
at approximately line 1000
(I am sure you can figure out exactly where to insert it)
It needs to be run every time the xdrip server receives a packet.
////////////////////////////////////////////////////////////////////////////////////////
std::string_view setvalue="extras/setvalue";
if(!memcmp(setvalue.data(), toget.data(), setvalue.size())) {
try {
time_t dataTime=time(NULL);
const char *end=toget.data()+setvalue.size();
if (*end=='?') {
string s = {toget.begin(), toget.end()};
int st=end-toget.data()+1;
int en = s.find(' ');
std::string* query = new std::string(s, st, en-st);
std::stringstream tStream;
std::string segment;
int iType=-1;
double dValue=-1.0;
std::string tLeft;
std::string tRight;
std::stringstream qStream;
qStream.clear();
qStream.str(query->data());
while(std::getline(qStream, segment, '&')) {
tStream.clear();
tStream.str(segment.data());
std::getline(tStream,tLeft,'=');
std::getline(tStream,tRight,'=');
if (!strcmp(tLeft.data(),"time")) {
dataTime=std::stol(tRight);
}
}
qStream.clear();
qStream.str(query->data());
while(std::getline(qStream, segment, '&')) {
tStream.clear();
tStream.str(segment.data());
std::getline(tStream,tLeft,'=');
std::getline(tStream,tRight,'=');
dValue=-1.0;
iType=-1;
if (!strcmp(tLeft.data(),"time")) {
}
else if (!strcmp(tLeft.data(),"fastinsulin")) {
iType=0; dValue = std::stold(tRight);
}
else if (!strcmp(tLeft.data(),"carbohydrate")) {
iType=1; dValue = std::stold(tRight);
}
else if (!strcmp(tLeft.data(),"dextrose")) {
iType=2; dValue = std::stold(tRight);
}
else if (!strcmp(tLeft.data(),"longinsulin")) {
iType=3; dValue = std::stold(tRight);
}
else if (!strcmp(tLeft.data(),"bike")) {
iType=4; dValue = std::stold(tRight);
}
else if (!strcmp(tLeft.data(),"walk")) {
iType=5; dValue = std::stold(tRight);
}
else if (!strcmp(tLeft.data(),"blood")) {
iType=6; dValue = std::stold(tRight);
}
else {
char *p;
int tInt=strtol(tLeft.c_str(), &p, 10);
if (*p == 0){
iType=tInt;
dValue = std::stold(tRight);
}
else {
cout<<"Could Not Find entry\n";
}
}
if (iType!=-1 && dValue!=-1.0){
cout<<"Settinmg IND: "<<iType<<" VALUE: "<<dValue<<"\n";
Numdata* kpfnumdata1=Numdata::getnumdata(
pathconcat(numbasedir,"here"),0,nummmaplen);
kpfnumdata1->numsave(dataTime, dValue, iType, 0);
}
}
return givenothing(outdata);
}
}
catch (...) {
cout<<"Exception Caught\n";
givenothing(outdata);
return false;
}
}
/////////////////////////////////////////////////////////////////////////////////////
…On Sat, Oct 21, 2023 at 5:21 AM Jaap Korthals Altes < ***@***.***> wrote:
What do you exactly do?
What information does the bar scanner receive?
For what do you monitor Bluetooth?
What do you do with finger-prick measurement?
Yes, I am interested in the changes you made. From what version of
Juggluco is it a modification?
—
Reply to this email directly, view it on GitHub
<#89 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AHIRDRVI3BSIHTEKKT7LWZLYAO45JAVCNFSM6AAAAAA6KCMXH6VHI2DSMVQWIX3LMV43SRDJONRXK43TNFXW4Q3PNVWWK3TUHM3TGNBWGE4DO>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
The mean problems I have with your code are the following: I have changed your code so that it can be used with arbitrary labels and makes use of numdata[0], plus some less important changes: I also made some other changes to make it work, for example I added "case toshort("20"): *uititer++=' ';break;" to rewriteperc, needed for labels with white space in them: int rewriteperc(char *start,int len) {
char *ends=start+len;
char *iter=start;
char *uititer=start,*next;
while(true) {
if((next=std::find(iter,ends,'%'))==ends) {
if(iter!=uititer) {
int left=(ends-iter);
memmove(uititer,iter,left);
return uititer+left-start;;
}
return len;
}
int bijlen=(next-iter);
memmove(uititer,iter,bijlen);
uititer+=bijlen;
++next;
switch(toshort(next)) {
case toshort("5B"): *uititer++='[';break;
case toshort("5D"): *uititer++=']';break;
case toshort("24"): *uititer++='$';break;
case toshort("3D"): *uititer++='=';break;
case toshort("20"): *uititer++=' ';break;
default: LOGGER(LOGID "strange char %.3s\n",next-1); memmove(uititer,next-1,3);uititer+=3;
}
iter=next+2;
}
}
EDIT: std::string_view setvalue="extras/setvalue";
if(!memcmp(setvalue.data(), toget.data(), setvalue.size())) {
try {
time_t dataTime=0;
const char *end=toget.data()+setvalue.size();
if (*end=='?') {
const char *start=end+1;
extern int rewriteperc(char *start,int len);
int newlen=rewriteperc(const_cast<char *>(start),toget.end()-start);
std::string_view rest(start, newlen);
auto en = rest.rfind(' ');
std::stringstream qStream({rest,0,en});
std::string segment;
while(std::getline(qStream, segment, '&')) {
std::stringstream tStream(segment);
std::string tLeft;
std::string tRight;
std::getline(tStream,tLeft,'=');
std::getline(tStream,tRight,'=');
if (!strcmp(tLeft.data(),"time")) {
dataTime=std::stol(tRight);
}
}
qStream.clear();
qStream.seekg(0,ios::beg);
while(std::getline(qStream, segment, '&')) {
std::string tLeft;
std::string tRight;
std::stringstream tStream(segment);
std::getline(tStream,tLeft,'=');
std::getline(tStream,tRight,'=');
float fValue=-1.0;
int iType=-1;
if(strcmp(tLeft.data(),"time")) {
const int labelnr=settings->getlabelcount();
LOGGERWEB("look for %s\n", tLeft.data());
if(!strcmp(tLeft.data(),"fastinsulin")) {
LOGARWEB("fast insulin");
for(int i=0;i<labelnr;++i) {
if(rapidNightWeight(i)!=0.0f ) {
iType=i;
fValue = std::stof(tRight);
break;
}
}
}
else {if (!strcmp(tLeft.data(),"carbohydrate")) {
for(int i=0;i<labelnr;++i) {
if(auto weight=carboNightWeight(i)) {
iType=i;
fValue = std::stod(tRight)/weight;
break;
}
}
}
else { if (!strcmp(tLeft.data(),"longinsulin")) {
for(int i=0;i<labelnr;++i) {
if(longNightWeight(i)!=0.0f ) {
iType=i;
fValue = std::stof(tRight);
break;
}
}
}
else {
for(int i=0;;++i) {
if(i==labelnr) {
char *p;
int tInt=strtol(tLeft.c_str(), &p, 10);
if (*p == 0){
iType=tInt;
fValue = std::stof(tRight);
}
else {
LOGGERWEB("Could Not Find entry %s\n",tLeft.c_str());
wrongpath(toget,outdata);
return false;
}
break;
}
std::string_view typestr=settings->getlabel(i);
if(!memcmp(tLeft.data(),typestr.data(),typestr.size())) {
iType=i;
fValue=std::stof(tRight);
break;
}
}
}
}
}
if (iType!=-1 && fValue!=-1.0){
LOGGERWEB("Setting IND: %s (%d) VALUE: %f\n",tLeft.c_str(),iType, fValue);
// Numdata* kpfnumdata1=Numdata::getnumdata( pathconcat(numbasedir,"here"),0,nummmaplen);
Numdata* kpfnumdata1=numdatas[0];
if(!dataTime)
dataTime=time(nullptr);
kpfnumdata1->numsave(dataTime, fValue, iType, 0);
}
}
}
}
return givenothing(outdata);
}
catch (...) {
LOGARWEB("Exception Caught");
givenothing(outdata);
return false;
}
}
|
Beta Was this translation helpful? Give feedback.
-
This functionality is exactly what I'm looking for. But I don't understand the details. Has this been incorporated in the official Juggluco version? Does it work with the Android version? Where do I find the IP address I have to use? I would like to automatically send insulin injections with units to Juggluco from Tasker on my phone. |
Beta Was this translation helpful? Give feedback.
-
I have modified the internal xdrip web server in juggluco
to accept new "values" The values include fast insulin, long insulin
and glucose readings(from a meter)
I use it as follows:
I have bar code scanner, and I scan my insulin pens when I take an injection, and update
juggluco. I monitor Bluetooth messages, and when I take a finger-prick measurement, I update
Juggluco
If there is any interest, I can post the changes I made to the linux version of Juggluco
Beta Was this translation helpful? Give feedback.
All reactions