Looking For A Good Sports Tracker For Bicycling? So am I!

I did my homework via Google and web reviews, and tried the following: Garmin Vivosmart HR+, Fitbit Charge 2, TomTom Spark Cardio GPS, and Samsung Gear Fit 2.

Garmin Vivosmart HR+ – I chose this model because, c’mon, it’s Garmin, right? Built-in GPS, Move IQ: “automatically tell the difference between movements like walking, running, biking, swimming and even using an elliptical,” a quote from their site, and many other features. Turns out it’s not very bike friendly, so you’ll have to enter your miles into their tracking system manually.

When I contacted customer service, they told me their site never said anything about bicycling, and they don’t support power meters, cadence, etc., something which I never asked for, but whatever. I do have a copy of the correspondences between customer service and myself, should someone wish to see it.

Suggestions to Garmin: Make your device activities customizable – Bicyclists want to see their miles accrue, and their tracks, without having to manually enter them.

Verdict: Seemingly good tracking, except it doesn’t work for what I want (bicycling).

Disposition: Return!

Fitbit Charge 2 – Okay, here’s another famous company. To be sure they’re all famous, so I won’t repeat for the other two below. Anyway, thought that this would be a good one, because everyone knows that Fitbit is all about activity tracking, right? Yeah, not so much. Although it was not waterproof, irksome to say the least, it seemed to work right out of the box. It did rely on my phone’s GPS to do its tracking, but I’m a bicyclist, and I always carry my phone for emergencies, so not a big deal.

The first day it seemed to work okay. The second day I noticed that the device was having issues staying connected with my phone, thus losing GPS tracking. My rides started recording as ten cents on the dollar, so to speak (10 percent – an exaggeration to be sure, but you get the point).

When I started researching the issue, I encountered many people complaining of the same thing (mostly runners) on Fitbit’s own forums. Another issue that popped up is that it woke me from a sound sleep (around midnight ???) to tell me I had met a goal for burned calories. Seriously? You’re going to wake me from a sound sleep (it also does sleep tracking … for your health) to tell me about calories burned for the day? Wednesday, Thursday, Friday?

Suggestions to Fitbit: Fix your connection issues, and make sure they never raise their ugly heads again. Also, turn off notifications (by default) when someone is SLEEPING!

Verdict: Tracking is, how do I say it politely, for the birds. Unfinished UI app.

Disposition: Return!

TomTom Spark Cardio GPS – So, I ended up on their site (via some search agent), didn’t realize they had a newer model. Tried to place an order, and it was rejected because of a supposed bad CSV. I then tried to purchase the same item with another card, and it was accepted.

When I attempted to look at my order, it showed two orders outstanding. Note, this was on a Saturday, and you cannot call them on the weekends. So, I put in a support ticket, contacted support via e-mail, to make sure the bad CSV order was cancelled.

I later discovered the newer model on their site (let’s just say their site is not user friendly), and then put in another ticket to cancel both orders. There was no contact about either e-mail over the weekend.

Monday rolled around, and when I got home from work, I had a message on my answering machine from a shipping manager at TomTom. She suspected a duplicate order. I returned her call, and she said she would try to cancel the shipment. I asked why no one from customer service cancelled the order, or contacted me? She didn’t know, “they’re in India … although they are on the job 24 hours a day, 7 days a week.” The shipping manager said that if she could not cancel the order, I could always refuse the shipment (when the delivery was attempted).

I had some errands to run, and went out for a couple of hours. When I returned home, there was no message from the shipping manager, so I called customer service. The initial response was, the item had been shipped, the duplicate order was never completed, and thus cancelled, have a nice day. I asked why no one had contacted me, and he said he would have to look at each contact, speak with each agent that was dealing with my ticket, and then get back to me. He put me on hold for a short time, and when he answered again, he basically said it was due to call volume, and that he was closing all the tickets, have a nice day.

I asked if there was someone to whom I could complain. Was there a phone number or e-mail address, perhaps? He assured me that there was not, but that this was all noted in the system.

I would have liked to have spoken to him about their ticket system failure, vent my frustrations a bit, but his accent was so thick I could barely understand him. With that I decided to not have anything further to do with TomTom. I mean, if they don’t even care when you’re buying their product (and the service shows), how are they going to act once you have the item?

Suggestions to TomTom: Get better customer service, or maybe put the shipping manager in charge. At least she seemed to care enough not to just phone it in.

Verdict: Customer service is so bad, I just sent it back without opening the box. Not going to take a chance.

Disposition: Return!

Samsung Gear Fit 2 – Beautiful color screen, although it’s not viewable in bright sunlight. Can tailor the activity to bicycle – great! And then the issue of connecting to my phone reared its ugly head.

I guess Samsung is not really all that keen to support users when it comes to connectivity. This really sucks, because you cannot directly connect to it from your computer. Read that as “Hello, Samsung, we should be able to connect the activity tracker to our computer.” I wrote that out, because they don’t seem to be smart enough to have figured it out on their own.

Anyway, when I tried contacting customer service for a list of compatible phones, I was told that all Android phones that have Android 4.4 and above, 2 Gig of RAM, should work. When I asked about sites that had lists, including one of their own, I was told that different countries have different spec’s for phones.

I looked into upgrading my phone and found the cost prohibitive.

Suggestions to Samsung: Try to make your app more phone friendly. Also, crazy idea here, but how about making an app that tells a person if their phone is compatible with a given device or not. Maybe even suggest a potential customer download and run the app before considering a purchase. And if the app finds the phone lacking, suggests a list of alternatives. Wouldn’t that be wild?

Verdict: If you have a Galaxy S5 or higher already, you’re probably okay. Probably. If you don’t, you might not want to take a chance, unless a new phone is what you really want.

Disposition: Return!

I only touched on the highlights of my experiences, and although I fully expect you to ignore my post, perhaps there will be some of you smart enough to learn from my misfortunes. At this point I am going to stop pursuing this idea any further. I guess the market is just not mature enough to give me what I want for the price I’m willing to pay at present. Anyone who tells you different has either never really used one, or has very low standards indeed.

A shame.

Posted in Reviews | Tagged , , , , | Leave a comment

Doing Work While Playing

Taking a queue from Google, I have come up with an idea (that I’d like to get paid for) for doing work while playing: Put seeds (grass, tree, flower, etc.) in pellets/paintballs, so when people are playing (practicing war ???), they can at least be doing something useful, like planting food. The pellets/paintballs (depends on what type of weapon you’re using) can be biodegradable, and when coming in contact with water (can you say rain?), melt, yielding up the see contained within.

Posted in Useful Thoughts (as Opposed to Off Thoughts) | Leave a comment

Snow Crunches When You Walk On It Because …

It occurred to me that snow and leaves are similar in that they crunch when you walk on them. Why, I wondered. Why?

They both fall from the sky, albeit most often from different heights. Perhaps this is a clue, falling? Thinking on this a moment, I realized that maybe it’s not the fall that (kills you) causes said crunchiness, but what transpires during said descent. Maybe, unbeknownst to us, snowflakes scream as they plummet headlong toward the earth, and because their terminal velocity is so low (they fall slowly when compared to other objects), the scream, which lasts an eternity in the life cycle of a snowflake, causes their little voice boxes to go hoarse. And the crunch is representative of the hoarseness of the little creatures.

And while leaves do not fall anywhere near as long (distance or time), they are much larger, so their hoarseness is like a deafening roar when compared to a snowflake. The only reason you can hear snow at all, is there are just so many of them. So darned many of them!

Yes, yes, this must be the reason.

Posted in Off Thoughts (Off as in Not Quite Right) | Tagged , , , | Leave a comment

Quick And Easy Music Command Generator In PHP

I won’t go in to the convoluted reason why I needed to write this script, but I will tell you that I recently used it to convert over 540 music files (using FFMPEG) from wma to mp3. You see, when I ripped my CD’s I used the wma format (at the time a higher quality for smaller file size codec), and now I need them in mp3 format.

My first try was to do dir command (dir folderName /s > fileList.txt) from console, open the resultant text file in Notepad++, and search and replace (can you say REGEX?) to construct a list of commands to run as a batch file (again from console). This worked fine, but when I realized the scope of the project, I decided to resort to my favorite fallback, PHP.

Here is the script I generated, and it worked flawlessly (for me). Feel free to use it as you see fit. If you like it (my script), give my blog props or e-mail me.


function h_pr($array) {
    if (is_array($array)) {
        echo '<pre>';
        echo '</pre>';

$path = realpath('music/'); // realpath used to get whole pathway, not relative
//$path = 'music/'; // use if relative pathway is okay
$searchFor = '.wma'; // include leading dot
$replaceWith = '.mp3'; // include leading dot

try { // just in case there's an error - such as directory is empty
    $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
catch (Exception $e) {
    $msg[] = 'Error: ' . $e->getMessage();

if (isset($objects)) {
    foreach ($objects as $name => $object) {
        $fileNameListArr[] = $name; // let's put all the names (folder/files) in an array

//h_pr($fileNameListArr); // use for debugging

    $matchText = '~\\' . $searchFor . '$~i'; // should yield ~\.wma$~i
    // regex patten starts (and ends) with ~ followed by escaped . , wma, $ (at string end) case insensitive i

    foreach ($fileNameListArr as $kF => $vF) {
        if (preg_match($matchText, $vF)) {
            $wmaFileListArr[] = $vF; // let's put all our wma's in a new array

//h_pr($wmaFileListArr); // use for debugging

    if (isset($wmaFileListArr) && count($wmaFileListArr)) {
        foreach ($wmaFileListArr as $kW => $vW) {
            // replace wma with mp3 and add to new array
            $mp3FileListArr[] = str_ireplace($searchFor, $replaceWith, $vW);

//h_pr($mp3FileListArr); // use for debugging
        // command pieces put in one place so you can tweak to your desire
        $beginCommand = 'ffmpeg -i "'; // beginning of ffmpeg conversion command
        $middleCommand = '" "'; // middle joining/between input file and output file
        $endCommand = '"'; // end of conversion command

        if (count($wmaFileListArr) == count($mp3FileListArr)) {
            for ($i = 0; $i < count($wmaFileListArr); $i += 1) {
                // assemble commands and put in new array
                $commands[] = $beginCommand . $wmaFileListArr[$i] . $middleCommand . $mp3FileListArr[$i] . $endCommand;
                // could have skipped making mp3FileListArr and just done conversion on the fly here
                // ex: str_ireplace($searchFor, $replaceWith, $wmaFileListArr[$i])
        else {
            $msg[] = 'Something went wrong!  Counts do not match!';
    else {
        $msg[] = 'No files found.';
else {
    $msg[] = 'Nothing to display.  Not sure why.';

if (isset($msg) && count($msg)) {
    h_pr($msg); // print messages

if (isset($commands) && count($commands)) {
    foreach ($commands as $kC => $vC) {
        // print out commands with new lines only (will look cluttered but necessary for batch file)
        echo $vC . PHP_EOL;

That’s all there is to it. Change the folder location as needed, run the script, save the page as text. Now change the extension of the saved text file to .bat and invoke from the console. Assuming you have FFMPEG in the environment path (I do), it should start chugging away. After the batch file is done, verify the files are where they should be, and delete the unneeded (wma’s) if desired.

Posted in PHP | Tagged , , , , , | Leave a comment

MySQL Difference Between Dates In Days, Hours, Minutes

I was researching how to make a JavaScript countdown timer for a personal webpage, because that’s the only way to go if you want interactivity (client-side scripting at its best), and I thought, ‘how can I do this in MySQL?’ Researching that a bit, I ran into a lot of similar minded queries on forums. So, I decided to write some sql.

Below is one of the versions of sql that I came up with. Note that there are many ways to do the same thing in sql, so my script may not be consistent (even to itself). Hopefully, the comments are sufficient to explain what I was doing.

set @tOffset = TIMEDIFF(NOW(), UTC_TIMESTAMP); -- get time offset from UTC
set @tOffsetTrim = substring_index(@tOffset, ':', 2); -- trim off unneeded chars
set @@session.time_zone = @tOffsetTrim; -- set time zone or else date1 and date2 may be different tz's
set @date1 = UNIX_TIMESTAMP('2017-01-20 12:00:00'); -- Obama checks out
set @date2 = UNIX_TIMESTAMP(); -- now
set @dateDiffSecs = @date1 - @date2; -- difference in seconds between dates
set @oneDaySecs = 24 * 60 * 60; -- seconds in a day (86,400)
set @dtDiffDaysReal = @dateDiffSecs / @oneDaySecs; -- real number (float)
set @daysIntTtl = floor(@dtDiffDaysReal); -- convert to whole number
set @yearsInt = floor(@daysIntTtl / 365); -- will cause error (day/leap year) during leap years (not addressed here)
set @daysInt = floor(@daysIntTtl - (@yearsInt * 365)); -- days remaining after years subtracted
set @daysRemainder = (concat('.', (SUBSTRING_INDEX(@dtDiffDaysReal, '.', -1)))) * @oneDaySecs; -- remainder * seconds in day
set @hrsMinsSecs = SEC_TO_TIME(@daysRemainder); -- built-in func to convert seconds to time
set @hrs = SUBSTR(@hrsMinsSecs, 1, 2); -- get hours
set @mins = SUBSTR(@hrsMinsSecs, 4, 2); -- get mins
set @secs = SUBSTR(@hrsMinsSecs, 7, 2); -- get seconds

	if(@yearsInt < 0, cast((@yearsInt + 1) as signed), @yearsInt) as `yrs` -- signed, in case years are negative
	 -- , floor(@daysInt / (365.25 / 12)) as `mthAp` -- approximate number of months
	 -- , (((from_unixtime(@date1, '%Y') - year(now())) * 12) + from_unixtime(@date1, '%m')) - month(now()) as `mths`
	 -- counts actual months, adjust as necessary (plus or minus a month, depending on how you count)
	-- , @daysIntTtl as `daysTtl` -- days (without sutracting years)
	, @daysInt as `daysMYrs` -- daysMinusYears, days remaining after subtracting years
	, @hrs as `hrs`
	, @mins as `mins`
	, @secs as `secs`;
Posted in MySQL | Tagged , , , | Leave a comment

All Your Base Are Belong To Us

So, I was out riding my bike today and ran across this lovely little fellow:

Green multi-eyed creature with a long tongue wrapping around it's body.

This appeared to be painted on the utility box (not a decal). I have no idea who designed or painted this, but if you can prove it’s yours, I’m more than willing to give you credit. Fairly cool, by the way!

After thinking about it a while, I believe I’ve seen this on a sticker (or somewhere) before. However, this was hand painted, and not a mass produced sticker (or the likes).

Posted in Art | Tagged , , , , | Leave a comment

Cigarette Butts In The Wild

So it was pretty windy yesterday, and while riding my bike (undisclosed location) I noticed two cigarette butts (one white, one undisclosed color) running for their lives (as though the wind was chasing them). I wanted to ask them where they were going, but they were in such a hurry, I thought it best not to interrupt them. Born free …

Posted in Off Thoughts (Off as in Not Quite Right) | Tagged , | Leave a comment

No WMC No Windows 10

With a push to get everyone back on the Microsoft wagon, Microsoft is offering Windows 10 for free to Windows 7 and up users. I was initially excited while simultaneously worried. I mean, nothing in this life is free. There’s a catch. You know it, I know it. However, I was still on board for the upgrade until I found out that Windows 10 will not contain Windows Media Center.

I guess I’m one of the few to use it with a cable card and decoder box (to match my cable provider). I’m not sure why it didn’t catch on (wasn’t more popular). I can’t see it being the price, because after the initial investment in the decoder box (about $100.00), the cable card only costs about $2.00 per month to rent. That’s one-fifth the cost to rent a cable company converter box (so that means I broke even around a year after purchase). I can’t imagine it’s the lack of features. I can set up my favorite shows to record automatically (series record), watch live TV (don’t do that very often–can’t stand commercials), search for shows to record via search or by manually perusing the station listing (up to 2 weeks in advance), as well as watch streaming TV from the likes of Netflix. Too difficult to set up for most, I guess. It’s too bad.

Anyway, to the point, no Windows Media Center in Windows 10, no Windows 10.

Posted in Complaints, Computer Stuff | Tagged , , , | Leave a comment

Working With XML/XSLT, JSON, And PHP

So, this tale, which for your sake I will attempt to make brief, is typical of my experiences in web development. As one of my old bosses used to say (and I’m paraphrasing), “if there’s a hard way to do it, you’ll try that way first.”

To begin, I have as my personal homepage, a calendar page that is scripted with PHP and MySQL. The calendar not only displays date information, but also displays things like birthdays, Sun and Moon information, bills, and a to-do list. As I constantly visit weather sites I decided it was time to bring the weather information to my calendar. Searching an API link site I found that the NOAA provides just what I needed: NOAA Weather API. While it was fun setting up the SOAP call, the resulting information (returned) was in XML format. Not the biggest fan of XML, but it’s what we’re given to work with in this situation.

Fast forward through scripting the SOAP call, caching data locally for X amount of hours (NOAA would appreciate not being queried over once per hour), writing the initial XSL for XSLT, and wrapping it as an object for display in my calendar. Everything seemed to be fine till I decided to look at my calendar with my smart phone. Turns out the smart phone (an old one) running Android 2.2.2 wouldn’t translate the XML in it’s built in browser. I have no idea if newer phones will deal with XML (maybe with a different browser?), but that didn’t matter to me, it has to run everywhere.

Researching the subject someone pointed out that whenever possible all XML transformation should be done server-side. I understood what he was talking about, browser compatibility issues being the bane of every web developer, but that adds to server-side load, not to mention the fact that if done server-side, there’s not much advantage of using XML in the first place (for information transmission). One of the perks (perquisites) of transmitting data in XML format is being able to display it in virtually any manner with a simple change of XSL (because all of the data is already there).

Okay, so now I’ve set out to do the transformation server-side. Great. Not that big a deal. The one sticking point was that I needed to include the following line (which took some research):

<xsl:output method="html"></xsl:output>

That and a couple other changes to my PHP script, and everything was being delivered as (X)HTML to the browser. Even works on my cell phone. Great, score one for me!

A while goes by and I decide to change the SOAP call to get 12 hour data as opposed to 24 hour data. That would help to narrow down when rain, for example, was to be expected. This turned out to be a lot more work once I jumped back into the XSL(T). You see, the data is presented in 12 hour blocks, sequentially, in one section, day – night – day – night, etc., and grouped in another, high temperatures (group one) and low temperatures (group two). While this may not have presented a problem to someone more adept with XSL, it was a stumbling block for me, to say the least. After beating my head against the wall for some time, not sure how much exactly, I did get it to work … mostly. And to be sure, had I not decided it simply was not worth my effort, I would have hammered out the remaining issues. However, it suddenly dawned on me, to heck with XML, convert it to an array, and then I can do whatever I want in PHP.

Initial searches turned up suggestions to turn it into JSON. I was okay with that. I mean, javascript is cool, and besides from there I could convert it to an array if I still wanted. Unfortunately, some of the data I needed was in attributes of the XML, which simple code, like below, would not get. Mostly worked.

$xml = simplexml_load_string($xml_string);
$json = json_encode($xml);
$array = json_decode($json,TRUE);

Further research and several failed attempts (read that as code did not work) and I happened across a PHP class at: XML To Array With PHP which works. Include the class and add the following, and I was off to the races.

$weatherArr = new simpleXml2Array($weatherXML, null);
$arr = $weatherArr->arr['data'][0]['parameters'][0]['content'];

$arr now held everything I needed and could be dealt with in a straight forward fashion. Well, to be fair, straight forward to me.

tldr; XML is overly complicated and is not as useful as was originally intended (my opinion). XSLT should be done server-side. Better yet, convert XML to JSON or an array (for PHP consumption) and life will be much easier.

Posted in PHP | Tagged , , , , , , , , , , , , , , | Leave a comment

Rainy Day Fun With Photoshop

So, it’s raining off and on, and taking a moment’s break from my usual tasks I decided to do something different. Looking at the weather map to see the rain occurring in the area always shows blank corridors. Obviously, these blank areas are either deliberate or caused by obstruction (radar being line of sight and all). Anyway, a screengrab and a couple stroked paths later and I have this:

Map of Long Island and parts of New York, Connecticut, showing cloud cover as depicted by radar

Triangulating radar station location using Photoshop

A quick look at google maps and the location appears to be the NOAA station here:

Closeup map view of Long Island centering around NOAA

NOAA as per Google Maps

Fun stuff!

Posted in Fun With Photoshop | Tagged , , | Leave a comment