Titanium HealthKit Module - Cant create StatisticsQuery with Cumulative & Separate by source - javascript

Im trying to create a Ti.Healthkit.StatisticsCollection where I can fetch number of steps taken, grouped per day. The thing is that I also need all sources, so I can filter ("manually") all steps added through Apple Health (manually) and other sources than the device and apple watch.
So; I've set up the Statistics query, everything looks fine. I can fetch all sources for each date. BUT, here's the thing, I can't no matter what, get the number of steps taken, per source.
var query = HealthKit.createStatisticsCollectionQuery(
{
type : HealthKit.OBJECT_TYPE_STEP_COUNT,
filter : HealthKit.createFilterForSamples(
{
startDate : date_from,
endDate : date_to
}),
options : HealthKit.STATISTICS_OPTION_CUMULATIVE_SUM | HealthKit.STATISTICS_OPTION_SEPARATE_BY_SOURCE,
anchorDate : anchorDate,
interval : 3600*24, // 24 hours
onInitialResults : function(e)
{
if (e.errorCode !== undefined)
{
//Utils.showError(e);
}
else
{
for(var i in e.statisticsCollection.statistics)
{
var statistics = e.statisticsCollection.statistics[i];
console.log(statistics.sources[0]);
var quantity = statistics.getSumQuantityForSource(statistics.sources[0]);
var stepCount = quantity.valueForUnit(HealthKit.createUnit('count'));
console.log(statistics.sources);
//console.log(statistics.startDate);
console.log(stepCount);
for(var k in statistics.sources)
{
var _source = statistics.sources[k];
var quantity = statistics.getSumQuantity(_source);
console.log(_source);
console.log(quantity);
I have tried to follow the Apple docs as well as the Ti.HealthKit docs, and as far as I can see I've tried everything now. I've also tried to fetch the steps while I iterate all sources, to put it inside the statistics method;
sumQuantityForSource(_source)
but that only returns "null".
I can get the number of steps for a day, but it contains all sources steps..
Does anyone have any suggestion what to try? I feel like I've tried everything possible.

well okey, I worked with this for 5 hours and 10 min after this post I found out what I did wrong. I should have checked if "quantity" was null (var quantity = statistics.getSumQuantity(_source);) and just continue to the next iteration, because down the results array, i hit sources with steps..

Related

How to save WebSql COUNT output as javascript variable?

I am looking for suggestions on how to best complete this task, and have found nothing on the web.
I am wanting to count the number of results that are returned from an SQL SELECT query and output that on my HTML page using JS/Jquery. Feel free to tell me there is a quicker and easier way than what I have done!!
I have found some suggestions using node.js, but I do not want to use that, as this is for a small school project.
This is the function that I am using when the select box is clicked. I am using it in conjunction with the 'onchange' in HTML (I think its HTML) and that works.
function placesLeft(val) {
let time = document.getElementById("placesLeft");
//time.innerHTML = val;
let selected = val;
db.transaction(function(tx) {
tx.executeSql('SELECT COUNT ( * ) FROM Sessions WHERE sessiontime = (?)', [selected], function(x, results) {
for (let i=0; i < 50; i++) {
const u = results.rows.item(i);
let count = 50 - i;
console.log(count);
console.log(i);
console.log(u);
time.innerHTML = count;
console.log(time.innerHTML);
};
});
});
}
Currently, it outputs the correct number of results when the query is run if I console.log 'u'. However, it outputs as this in the console: {COUNT ( * ): 2}.
When I try and add it to the tag I am using, it looks like this on the webpage:
[object, Object].
I am using WebSQL if you haven't realised, JS, and HTML. Fairly proficient in jQuery too, if that helps.
Here is a link to my code:
https://webucate.com.au/project/8sBxh4dPQ42fYB7viODZ/share
To get to the page I am talking about, click: book a session -> Scroll down to 'Choose a time' -> pick something. (10:00am and 1:00pm are the values I have in my database, and they appear 1 and 2 instances in the databases, respectively) In the console, you should see what u, I and count outputs.
The SQL Query uses a COUNT() function. It will return only one row and one column in the results.
As such there is no need to iterate the result set.
Is there a reason why you use an i-loop that iterates 50 times?
I would suggest changing the SQL command to
SELECT COUNT ( * ) AS COUNT FROM Sessions WHERE sessiontime = (?)
So that the column name of the value you need will be set as COUNT.
After that, retrieving the required value from the result set will be easier.
You can simply get the first row with results.rows[0].
Then retrieve the value at the column "COUNT".
var count = results.rows[0]["COUNT"]
time.innerHTML = count;
Hopefully this is solves your problem.

ActionScript 3.0: How to get the use count of a library item in Animate?

In an Animate project, I can see the use count of each item in the library. I open the library with Ctrl + L and I can see that some items are used 1 time, 19 times, or 0 times.
I want to use CS5 JavaScript to get the use count for each item.
There seems to be no way to just do this:
let count = fl.getDocumentDom().library.items[1].getData('useCount');
Or
let count = fl.getDocumentDom().library.items[1].useCount
I have attempted to make the item the selection of the document and then get how many items are selected, as in the code below, but an error shows up saying that the first argument in line 6 is invalid.
var doc = fl.getDocumentDOM();
var library = doc.library;
var item = library.items[1];
library.selectItem(item.name);
doc.selectNone();
doc.selection = [item]; // Error: selection: Argument number 1 is invalid.
fl.trace(doc.selection.length);
I have searched around on the internet and haven't yet found an answer to this exact question.
How do I do this?

Google apps script - Mapping arrays

I am working on a project where I take multiple column/row inventory sheets and turn them into a multi-row/2-column format for order picking.
I have a switch for selecting the appropriate inventory sheet and a map() function that copies the imported information from the inventory DataRange().
However, not all the data is in consistent columns. What I would like to do is find an expression that maps the next column in if the column it was mapping has a zero or "" value.
I won't give you the full body of code unless you need it, but hopefully just the important parts.
This is what I have:
var source = SpreadsheetApp.openById("1xixIOWw2yGd1aX_2HeguZnt8G_UfiFOfG-W6Fk8OSTs"); //This sheet
var srcSht = SpreadsheetApp.getActive();
var sourceMenu = srcSht.getRange('A1');//This is the cell cotaining the dropdown
var menuTest = sourceMenu.getValue();
// Variable for the vars sheet. If it doesn't exist, create it
var varsTest = source.getSheetByName('vars');
if (!varsTest){source.insertSheet('vars');}
var importedA1 = varsTest.getDataRange().getA1Notation();
varsTest.clearContents();
var t1Imp = '=ImportRange("test1_Id", "Stock!A1:F11")';
var varsData = varsTest.getRange('A1');// This is the cell we fill with the importRange formula
varsData.setValue(t1Imp);
var imported = varsTest.getDataRange().getValues();
var newOrder = imported.map(function(item) {
if (item[4] !== NaN){return [[item[0]],[item[4]]];};
if (item[4] === NaN){return [[item[0]],[item[3]]];};}
var orderRange = source.getSheetByName('Sheet1').getRange(10,1,newOrder.length, newOrder[0].length);
orderRange.setValues(newOrder);
Logger.log("\t" + newOrder);
Logger.log(newOrder):
[(timestamp omitted)] items1,order,caramel,6,c&c,2,mint,3,PB,0,,,items2,,caramel,,strawberry,,mint,,PB,
It seems to be skipping the if statements, or I told it that I mean to test the index as NaN, which will obviously never be true.
I also tried replacing 'NaN' with 'undefined'. Same result. I tried finding the item[4].Values, but it gave me an error. I also tried the same logic using filter() instead of map() but it copied the entire data set.
I pull these values onto a new 'vars' sheet in the workbook (to minimize calls to the web service):
test1
reduce them to the first and last columns, then output:
test
The cells in the 'order' column for the second set of items in the 'test' sheet are blank. The values for that order column should be in item[3] of that array, but I can't get the script to identify that that the blank cells are blank.
I am new to Google Apps Script and JS, but I am watching a lot of tuts and learning by doing. If I find a solution, I will post it.
Thank you StackOverflow, I could not have learned as much as I have without this community!
I have a working function that does what I want. In short:
I had to create a duplicate of the order column in a new column, so that all the values would line up. It's not technically a JS answer, but was the simplest and follows good spreadsheet rules.
function rmZeroOrderPS(item){
var source = SpreadsheetApp.openById("<sheetId>"); //This sheet
var varsTest = source.getSheetByName('vars');
var imported = varsTest.getDataRange().getValues();
var i=-1;
while (i <= imported.length){
if(item[8]!= 0) {return [item[0],item[8]]};
i+=1;
};

Store data from an array and use it later

I had this problem which Cooper helped me to solve it (thanks again for that), but now I'm struggling with a different one. The following script will count how many times a client code will appear on another Spreadsheet using as a second condition yesterday date.
function countSheets()
{
var vA = appSh();
var td = Utilities.formatDate(subDaysFromDate(new Date(),2), Session.getScriptTimeZone(), "dd/MM/yyyy");
var mbs=getAllSheets();
//var s='';
for (var i=2;i<vA.length;i++)
{
var d = Utilities.formatDate(new Date(vA[i][12]), Session.getScriptTimeZone(), "dd/MM/yyyy");
for(var key in mbs)
{
if(vA[i][0]==key && d==td)
{
mbs[key]+=1;
}
}
}
return mbs;
}
Then I have the below code which will search in the main spreadsheet (a table) a string and when was found will return row number, also will search for the date yesterday and return the column number. Based on these information I'll get the range where I need to paste the count result from the first script.
function runScript()
{
var ss=SpreadsheetApp.openById('ID');
var mbs=countSheets();
for(var key in mbs)
{
var sh=ss.getSheetByName(key);
var rg=sh.getDataRange();
var vA=rg.getValues();
for(var i=0;i<vA.length;i++)
{
if(vA[i][1]=='Total Number of Applications')
{
var nr=i;
break;//by terminating as soon as we find a match we should get improved performance. Which is something you cant do in a map.
}
}
if(typeof(nr)!='undefined')//If we don't find a match this is undefined
{
var today=subDaysFromDate(new Date(),2).setHours(0,0,0,0);
for(var i=0;i<vA[3].length;i++)
{
if(vA[3][i])//Some cells in this range have no contents
{
if(today.valueOf()==new Date(vA[3][i]).valueOf())
{
sh.getRange(nr+1,i+1,1,1).setValue(Number(mbs[key]));
}
}
}
}
}
return sh;
}
PROBLEM: I have 24 rows on the main Spreadsheet. So I will need to write the same script 24 times. As example, I need to count Total Number of Applications, Total Number of Calls, Number of Live Adverts and so on. If I do this it will exceed execution time since each script takes on average 25 seconds to run.
I did some researches on this website and internet and read about storing values and re-use them over and over. At the moment my script will have to go every time through the same file and count for each condition.
Q1: Is there any chance to create another array that contain all those strings from the second script?
Q2: How to use PropertiesService or anything else to store data and don't have to run over and over getValues() ? I've read Google Documentation but couldn't understand that much from it.
I hope it all make sense and can fix this problem.
My best regards,
Thank you!
My Approach to your Problem
You probably should write it for a couple of rows and then look at the two of them and see what is unique to each one. What is unique about each one is what you have to figure out how to store or access via an external function call.
The issue of time may require that you run these functions separately. I have a dialog which I use to load databases which does exactly that. It loads 800 lines and waits for 10 seconds then loads another 800 lines and wait for ten seconds and keeps doing that until there are no more lines. True it takes about 10 minutes to do this but I can be doing something else while it's working so I don't really care how long it takes. I do care about minimizing my impact to the Google Server though and so I don't run something like this just for fun.
By the way the 10 second delay is external to the gs function.

Get DST/STD dates and times for a given timezone (Javascript)

I am developping an embedded website contained within a windows CE device.
See it as if it was the web configuration interface of your router.
Everything is contained within a really small footprint of memory, the entire website is less than 500KB with every script, html, css and icons.
We have to assume that the user that is going to 'browse' into that interface does not have access to the internet (LAN only) so no 'online' solution here.
I am looking for a solution so the user choose his timezone and the code will get all the DST/STD times and dates for the next 10-20 years at least and downloaded them to the device that will run autonomously after that and at specific dates, will change its time to DST/STD by itself. Current application is custom (not windowce api related) and needs the DST/STD date pairs.
iana.org is maintaining a db for like every location in the world. I also saw that moment-timezone (javascript interface) is 'packaging' this data in a very compact package 25kb zipped.
I need to know if it is possible to:
'Extract' a main tz list from this DB so the user can choose its own tz. I looked at their doc but example didn't work:
var itsTimeZones = moment.tz.names();
2- Extract the next 10-20 years of DST/STD dates/times for a chosen zone ? I haven't saw any documentation anywhere on this topic. But since it's kind of the purpose of such a database, i would say it must be burried in there somewhere, need a way to dig it out.
3- If moment timezone is not the right track to go, anybody has a solution that will fullfill that requirement ?
Thanxs
My solution for extracting DST list for a given zone from moment-timezone.
1. "theTz" is a numerical index from a change on a select in the webpage.
2. select is populated with "List".
var itsTz =
{
"List" : moment.tz.names(), // Get all zone 'Names'
"Transitions" : [],
};
function TimeZoneChanged(theTz)
{
var myZone = moment.tz.zone(itsTz.List[theTz]); // Get zone by its name from List
var myTime = moment.tz(moment(), myZone.name); // Start today
var myResult;
// Build transition list according to new zone selected
itsTz.Transitions = [];
do
{
myResult = GetNextTransition(myZone, myTime);
if(myResult != null)
{
itsTz.Transitions.push(moment(myResult).format("YYYY/MM/DD"));
myTime = moment.tz(myResult, myZone.name); // Get next from date found
}
}while(myResult != null);
}
function GetNextTransition(theZone, theTime)
{
var myResult;
for(var i = 0; i < theZone.untils.length; i++)
{
if(theZone.untils[i] > theTime)
{
theZone.untils[i] == Infinity ? myResult = null : myResult = new moment(theZone.untils[i]).format();
return myResult;
}
}
}
Results for 'America/Toronto:
2017/03/12,
2017/11/05,
2018/03/11,
2018/11/04,
2019/03/10,
2019/11/03,
2020/03/08,
2020/11/01,
2021/03/14,
2021/11/07,
2022/03/13,
2022/11/06,
2023/03/12,
2023/11/05,
2024/03/10,
2024/11/03,
2025/03/09,
2025/11/02,
2026/03/08,
2026/11/01,
2027/03/14,
2027/11/07,
2028/03/12,
2028/11/05,
2029/03/11,
2029/11/04,
2030/03/10,
2030/11/03,
2031/03/09,
2031/11/02,
2032/03/14,
2032/11/07,
2033/03/13,
2033/11/06,
2034/03/12,
2034/11/05,
2035/03/11,
2035/11/04,
2036/03/09,
2036/11/02,
2037/03/08,
2037/11/01,

Categories