Maker API, Driver or somthing simple

Hi All,
I think I know the answer to this but am hoping I am wrong.
My wife is a Type 1 diabetic and has a continuous glucose monitor. I am currently using an open source herokuapp called nightscout to interact with IFTTT. That allows me to turn on sirens, flash lights etc if her blood sugar goes too low or high. that is all working fine. I would ultimately like to remove the IFTTT portion, but that is a ways down the road as I am not a programmer.
My initial goal is just to get her blood sugar number displayed on the dashboard.
I can get a json file from nightscout which looks like this:
[{"_id":"xxxxxxxxxxxxxxxxxxxxxxx","sgv":111,"date":1573489999000,"dateString":"2019-11-11T16:33:19.000Z","trend":4,"direction":"Flat","device":"share2","type":"sgv"}]

All I need from that is to somehow parse the sgv value.

To my question, am I going to have to create a driver to make this happen? Hoping that isn't the case, but i'm pretty sure it is.

Thank you.
Chris

You might be able do this with Rule Machine. Can you send these to an endpoint that you specify (e.g., IFTTT)? If so, you could send it to an RM endpoint that sets a Global Variable. From that you could pull out the field of the json text that you want to examine, etc...

Thanks for the response. I don't think so, all the nightscout app sends are notifications; ns-level-low, ns-level-high etc to IFTTT. Pretty much out of my skill level with this whole thing. I have gotten a driver kinda going based on another thread I found. Just getting stuck trying to parse the json result from the httpget().

Thanks

Paste your code and the response you're getting and I'm sure someone here will guide you through extracting what you need. :wink:

Fair warning be gentle I have no idea what most of this stuff means, basically just copying and pasting stuff from groovy websites/forums to try and get it to work. :slight_smile:

![jsonerror|690x25]

I would just like to get the sgv value in a variable.
Thanks for any help/suggestions.
Chris

I only just saw your response here.
Ithought you were already getting the apprpriate response from the server and only needed to parse the response and extract the data you needed. It may be difficiult to assist without knowledge of wha the server requires.

Based on your post above it looks like you need to send a http GET request. See my best guess below:

def sendSyncCmd(){
	def params = [
        uri: "http://appname.herokuapp.com/api/v1/entries/current.json",
        contentType: "application/json",
        requestContentType: "application/json",
    ]
	try{
		httpGet(params){response ->
			if(response.status != 200) {
				log.warn "Did not received valid data!"
			}
			else {
                        def jsontext = response.data
				log.debug "Received: " + jsontext
                            def jsonSlurper = new JsonSlurper()
                            def object = jsonSlurper.parse(jsontext)
                            log.debug "Object: " + object
                            log.debug "SGV: " object.sgv
			}
		}
	}
	catch (Exception e) {
        log.debug "HttpGet Error: ${e}"
	}  
}

Thanks so much for the assistance. When I type the uri into a browser, this is the page I get back:

This is the error in the error logs. It is getting data back but looks like jsonSlurper doesn't like the format?

Thanks again!

You may not need jsonSlurper at all. Comment out those lines and add
log.debug jsontext.sgv

If that fails try
log.debug jsontext[0].sgv

Also, if you want me to be notified of your replies, you need to use the reply icon directly below my post:

or tag me directly with the "@" symbol. For example, I will tag you now and you should notice 2 notifications in blue next to your avatar in the top right. One for the reply and one for me tagging you directly.
@cfunk30

@stephack Thank You! That worked. I have cobbled together some other "guesses" based on other user drivers to get her number to show on the dashboard.
Now on to figuring out how to change the tile color based on that number. Now that I have the blood glucose number I can git rid of my iFTTT stuff. All very cool.
Thanks Again.
Chris

1 Like

Glad to help.

Iā€™m a Type 1 diabetic and would love to add this to my dashboard. Were you able to get it working? Would you be willing to share your code so I could use it? Thanks!

Here is the driver code. It stopped working a while back because Heroku (which is where I had nightscout running) changed their licensing or something like that. I haven't looked into an alternative or what it would take to get it working again.

import groovy.transform.Field
metadata {
definition (
name: "CariCGM",
namespace: "CariCGM",
author: "Chris" )
{
capability "Refresh"
attribute "SGV", "number"
attribute "CustomTile2", "string"
}
}

def refresh() { ( sendSyncCmd() ) }

def sendSyncCmd() {
def params = [
uri: "http://NAMEOFYOURINSTANCE.herokuapp.com/api/v1/entries/current.json",
contentType: "application/json",
requestContentType: "application/json",
]
try{
httpGet(params){response ->
if(response.status != 200) {
log.warn "Did not received valid data!"
}
else {
def jsontext = response.data
// log.debug "Received: " + jsontext
// log.debug "Cari's number is: " + jsontext[0].sgv
def SGV1 = jsontext[0].sgv
def SGV2 = "65"
def int SGV = SGV1 as Integer
def SGVdir = jsontext [0].direction
// log.debug SGVdir
def int low1 = "70" as Integer
def int low2 = "59" as Integer
def int high1 = "200" as Integer
def int high2 = "260" as Integer
def SGVstate1 = "unset"
def SGVarrow = ""
// def last = device.currentValue("last_num2")
// log.debug SGV
sendEvent(name: "SGV", value: SGV, display: true , displayed: true)
if(SGV < low2) {
SGVstate1 = "VeryLow"
SGVbackground = " rgba(255, 0, 0, 0.65) }"
SGVshadow = " #DD0048 "
} else {
if(SGV < low1) {
SGVstate1 = "Low"
SGVbackground = " rgba(255, 0, 0, 0.65) }"
SGVshadow = " #DD0048 "
} else {
if(SGV > high1) {
SGVstate1 = "High"
SGVbackground = " rgba(255, 0, 0, 0.65) }"
SGVshadow = " #DD0048 "
} else {
SGVstate1 = "Normal"
SGVbackground = " #39ff14 "
SGVbackground = " rgba(0, 255, 0, 0.5) }"
SGVshadow = " #39ff14 "

                }
                }
           }
           
            if(SGVdir == "NOT COMPUTABLE") {
               SGVdir1 = 'DATA Received '
               SGVstate1 = "NO"
               SGVcolor = " #DD0048 "
               SGVshadow = " #DD0048 "
 //              SGV = 000
                //  SGVarrow = '<img src="https://192.168.10.1/singlearrowright.png"></img>'
            }
            SGVcolor = "#FFFFFF"
            if(SGVdir == "Flat") {
               SGVdir1 = 'Steady '
               SGVarrow = '<img src="https://192.168.10.1/singlearrowright.png"></img>'
            }
            if(SGVdir == "FortyFiveUp") {
               SGVdir1 = 'Rising '
                SGVarrow = '<img src="https://192.168.10.1/45uparrow.png"></img>'
            }
            if(SGVdir == "SingleUp") {
               SGVdir1 = 'Rising '
                SGVarrow = '<img src="https://192.168.10.1/singlearrowup.png"></img>'
            }
            if(SGVdir == "DoubleUp") {
               SGVdir1 = 'Rising '
                SGVarrow = '<img src="https://192.168.10.1/doublearrowup.png"></img>'
            }
            if(SGVdir == "FortyFiveDown") {
               SGVdir1 = 'Falling '
                SGVarrow = '<img src="https://192.168.10.1/45downarrow.png"></img>'
            }
            if(SGVdir == "SingleDown") {
               SGVdir1 = 'Falling '
                SGVarrow = '<img src="https://192.168.10.1/singlearrowdown.png"></img>'
            }
            if(SGVdir == "DoubleDown") {
               SGVdir1 = 'Falling '
                SGVarrow = '<img src="https://192.168.10.1/doublearrowdown.png"></img>'
            }
             sendEvent(name: "SGVstate1", value: SGVstate1, display: true , displayed: true)

            def CustomTile1Text = '<style>'

        CustomTile1Text += '.CGMInfo {'
   CustomTile1Text += ' font-size: 15px;'
        CustomTile1Text += ' color: ' + SGVcolor
        CustomTile1Text += '}'
       
        CustomTile1Text += '.CGMrow {'
        CustomTile1Text += ' font-size: 40px;'
       // CustomTile1Text += '    text-shadow: 0px 0px 0px ' + SGVshadow + ';'
        CustomTile1Text += ' color: ' + SGVcolor + ';'
        CustomTile1Text += '}'
   CustomTile1Text += '#tile-63 { background-color: ' + SGVbackground
            //+ '; text-shadow: none;}'
           
        CustomTile1Text += '</style>'
           
   CustomTile1Text += '<div class="CGMrow">'
        CustomTile1Text += '' + SGV + ' ' + SGVarrow
        CustomTile1Text += '<div class="CGMInfo">'
   CustomTile1Text += ' ' + SGVstate1
   CustomTile1Text += ' ' + SGVdir1  
   CustomTile1Text += '</div>'
   CustomTile1Text += '</div>'

   sendEvent(name:"CustomTile2", value:CustomTile1Text, descriptionText:"CustomTile2")
        }

}
}
catch (Exception e) {
log.debug "HttpGet Error: ${e}"
}
}

I've been using the CariCGM Driver Code and it works great, however it returns SGV as mg/dL regardless of what you've got the units set as in Heroku. I'm in Australia where we use mmol/L.

How can I get this code to return mmol/L?

Thanks in advance!

Hi,
I haven't used this for quite a while since licensing changed. I am by no means a programmer so I'm not really sure. If you paste this " http://nameofyourinstance.herokuapp.com/api/v1/entries/current.json) into your browser does the json file return the correct MMol/L? if not then it is something in Heroku. if it does then I would suggest looking at this line def SGV1 = jsontext[0].sgv the json file should be labeled for the element, may just be a simple as changing .svg to whatever the MMol/L element is labeled as.
Hope that helps.

Chris

Thanks Chris. The code actually still works quite well.

To answer your question, the json file returns mg/dL despite me having my units set to mmol in Heroku.

Would it be possible to have the code divide the mg/dL by 18 somehow? (This is the conversation from mg/dL to mmol/L)

I "think" all you need to do is add
SGV = SGV/18
right above the line that starts "sendEvent(name: "SGV", value: SGV, display: true...."
Someone more familiar with groovy can probably help if that doesn't work.
You probably also need to adjust the
def int low1 = "70" as Integer
def int low2 = "59" as Integer
def int high1 = "200" as Integer
def int high2 = "260" as Integer
numbers as well.

Just go into the drivers code tab then click on the name and you can edit right there.
The low and high numbers above are obviously subjective and can be changed for your needs

If you don't mind my asking how are you your number? dashboard tile? rules tied to it?
I had Lights, sirens and echo-speaks setup for low and high conditions. Sirens woke us up a couple times when neither one of us heard her dexcom alarm.
Chris

So that worked, but introduced a new issue. It's rounding up the value to the whole number, but it needs to be to 1 decimal place.

I've tried changing attribute "SGV", "number" to attribute "SGV", "decimal" thinking maybe that might work, but it didn't.

Any ideas how to format the results to 1 decimal place??

And yes, I'm using the results in a Rule Machine automation that speaks out my blood glucose on my Chromecast speakers when I ask Google Assistant. (For those times I'm too god-damn lazy to get my phone, which is probably already in my pocket anyway. LOL)

Getting way out of my depth here, try
def float SGV = SGV1 as float.
if that doesn't work, try
def float SGV = SGV1

Chris

Blockquote
Getting way out of my depth here,

You and me both!

Wasn't sure where to put the def float command so I put it above where I put SGV = SGV/18 but it gives an error ("The current scope already contains a variable of the name SGV @ line 45, column 11")