VirtualBox Audio on 6.1 for MacOSX solved

Posted on

After upgrading to the latest version of VirtualBox for Mac, with a Windows 7 as the client, I have struggled to get audio working with a USB audio device.

I have a Presonus Studio192 device, and it’s a fantastic piece of kit, but in the current setup, VB doesn’t want to play nice.

I am running Mojave on a 4,1->5,1.

The way around this problem with the audio not working is quite simple.

Download VoiceMeeter Banana and a program called VBAN Receptor from the Apple App store, and you should be right to go.

It’s basically and IP Audio Codec where you can route streams of the audio to different IP addresses. Rather impressive.

https://www.vb-audio.com/Voicemeeter/banana.htm

Screen Shot 2020-06-16 at 22.12.50

Set up the outgoing streams to the computer it should go to.

Screen Shot 2020-06-16 at 22.13.19

https://apps.apple.com/au/app/vban-receptor/id1462414931?mt=12

This costs about $10 Australian.

Screen Shot 2020-06-16 at 22.13.34

 

Amazing what the internet can find

Posted on Updated on

I’ve recently got a vinyl cutter, and so have gone down the path of trying things out. I bought some software to use with it, and played with a few drivers and boom, it worked… until the other day.

Yesterday, I thought I’d swap things over to my laptop on High Sierra. Suddenly, the cutter didn’t work on the MacPro, or the MacBookPro laptop. So… what do you do?

Well, originally, (I think) I had used the drivers from here, as suggested from this site

This appears to be a very common driver for mac, which is needed to emulator a serial port via USB (even though my cutter is actually coming via a USB cable anyway).

So,  today after hunting around for a very long time and eventually establishing that the software was fine and the printer was fine, it pin-pointed it to a driver problem.

The rabbit hole went a long way down, to the point where I eventually entered the apple hardware id of my cutter, and stumbled across this post who had my exact numbers and the same problem, only it was outlined with even more detail:

https://www.silabs.com/community/interface/forum.topic.html/cp210x_usb_to_uartb-y2X3

The link at the bottom was the final key to the solution which pointed me to the following site with a driver!

https://blog.sengotta.net/signed-mac-os-driver-for-winchiphead-ch340-serial-bridge/

It appears to be working on the laptop for the moment in High Sierra!

I have a HL-721 Vinyl Cutter, which I think is a Chinese generic brand, and it works in the software Sure Cuts a Lot as a GoldCut JK. “Plotter Generic”, with the model being HPGL.

This site also pointed to the suggestion of using a generic cutter too: https://discourse.southlondonmakerspace.org/t/vinyl-cutter-cutter-plotter-m721/797

So, now the update for Mojave on the MacPro4,1->5,1.

I have a USB 3 Hub, with a mixture of USB 2 and 3 ports. It doesn’t want to work through the hub, using the various drivers – FTDI, ch340 etc.

But, it started working for me again, when I took it out of the hub, and ran directly in to a USB 2 port via an extension lead.

At the moment, I’ve got the FTDI driver active, and the GoldCut JK plotter set.

Strange. But, that’s computers for you!

 

 

Latest update: 20200620.

I did try and use those settings originally for the cutter, however, I found that the GoldCut settings weren’t right for me, and that while doing a test cut, there were directions given somehow, that made the cutter go on it’s own weird path.

I remembered that on the tablet I’d used a different setting. So, I changed the MacPro to the following, where it was successful!

My Cutter: Plotter Generic
Model: HPGL
Port: Auto (or the serial one) usbserial-320

Get MP3 ID3 Metadata from remote URLS

Posted on

Firstly, I didn’t create this, I’ve just making it easy to understand with a full example.

You can read more of it here, but only because of archive.org.

To begin, download this library from here: http://getid3.sourceforge.net/

when you open the zip folder, you’ll see ‘getid3’. Save that folder in to your working folder.

Next, create a folder called “temp” in that working folder that the following script is going to be running from.

Basically, what it does is download the first 64k of the file, and then read the metadata from the file.

I enjoy a simple example. I hope this helps.


<?php

require_once("getid3/getid3.php");

$url_media = "http://domain.com/myfile.mp3"

$a=getfileinfo($url_media);

echo"<pre>";

echo $a['tags']['id3v2']['album'][0] . "\n";  
echo $a['tags']['id3v2']['artist'][0] . "\n";  
echo $a['tags']['id3v2']['title'][0] . "\n";  
echo $a['tags']['id3v2']['year'][0] . "\n"; 
echo $a['tags']['id3v2']['year'][0] . "\n";  

echo "\n-----------------\n";

//print_r($a['tags']['id3v2']['album']);

echo "-----------------\n";

//print_r($a);

echo"</pre>";

function getfileinfo($remoteFile)

{

$url=$remoteFile;
$uuid=uniqid("designaeon_", true);
$file="temp/".$uuid.".mp3";
$size=0;
$ch = curl_init($remoteFile);
//==============================Get Size==========================//
$contentLength = 'unknown';
$ch1 = curl_init($remoteFile);
curl_setopt($ch1, CURLOPT_NOBODY, true);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch1, CURLOPT_HEADER, true);
curl_setopt($ch1, CURLOPT_FOLLOWLOCATION, true); //not necessary unless the file redirects (like the PHP example we're using here)
$data = curl_exec($ch1);
curl_close($ch1);
if (preg_match('/Content-Length: (\d+)/', $data, $matches)) {
$contentLength = (int)$matches[1];
$size=$contentLength;
}
//==============================Get Size==========================//


if (!$fp = fopen($file, "wb")) {
echo 'Error opening temp file for binary writing';
return false;
} else if (!$urlp = fopen($url, "r")) {
echo 'Error opening URL for reading';
return false;
}
try {
$to_get = 65536; // 64 KB
$chunk_size = 4096; // Haven't bothered to tune this, maybe other values would work better??
$got = 0; $data = null;

// Grab the first 64 KB of the file
while(!feof($urlp) && $got < $to_get) { $data = $data . fgets($urlp, $chunk_size); $got += $chunk_size; } fwrite($fp, $data); // Grab the last 64 KB of the file, if we know how big it is. 
if ($size > 0) {
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RESUME_FROM, $size - $to_get);
curl_exec($ch);
}

// Now $fp should be the first and last 64KB of the file!!

@fclose($fp);
@fclose($urlp);
} 
catch (Exception $e) {
@fclose($fp);
@fclose($urlp);
echo 'Error transfering file using fopen and cURL !!';
return false;
}

$getID3 = new getID3;
$filename=$file;
$ThisFileInfo = $getID3->analyze($filename);
getid3_lib::CopyTagsToComments($ThisFileInfo);
unlink($file);
return $ThisFileInfo;
}

?>

RGB Lights for the MAC

Posted on Updated on

I have bought this for 3 bucks.

https://www.ebay.com.au/itm/282231990280

I’ll be combining the knowledge from this post:

https://www.instructables.com/id/USB-NeoPixel-Deco-Lights-via-Digispark-ATtiny85/

And this video:

 

And will look at getting some RGB lights

https://www.ebay.com.au/itm/5V-LED-Strip-WS2812B-5050-RGB-30-60-144LEDs-M-ws2812-IC-Individual-Addressable/253054192813?var=552124369523

And this
https://www.ebay.com.au/itm/324032880391

As well as some joiners.

https://www.ebay.com.au/itm/5Pcs-3-pin-connectors-PCB-Solderless-for-WS2811-WS2812B-SK6812-led-pixel-strip/112087601742?hash=item1a18f1124e:g:Xs0AAOSwMtxXqWWg

This could be a bit of fun to brighten up my desk set up. ūüėÄ

I plan on putting these lights behind the screens, and under the desk glass to create ambient lighting, that I can change the colour of, using the computer. Should be pretty sweet.

Now to wait 2 months for them in the post…

UPDATE:
It’s now the 28th of May, and all of the final bits have arrived. In this process, I’ve already lost the cable connectors, so I’ll look in to either getting new ones or ripping apart the office… But, testing will happen soon.

IONIC Build Errors with solutions

Posted on Updated on

Hi friends,

As I’m working on different apps, on multiple platforms and things, I thought I’d start a list of some of the errors I’d been getting, and how I solved them in IONIC.

Some of these solutions may help you. Most of these are for v3 of IONIC. Other settings vary.

I’m sure I’ll keep adding to this.

It’s a very messy file, but if Google brings you here, I hope it will help you.

 


Failed to install ‘cordova-sqlite-storage’: CordovaError: Using “requireCordovaModule” to load non-cordova module “q” is not supported.
https://github.com/xpbrew/cordova-sqlite-storage/issues/856#issuecomment-497298630

Cordova error: Using ‚ÄúrequireCordovaModule‚ÄĚ to load non-cordova module ‚Äúq‚ÄĚ is not supported
https://stackoverflow.com/a/55321875/1190051


https://github.com/crosswalk-project/cordova-plugin-crosswalk-webview/issues/205#issuecomment-405052996

simply add this
cordova plugin add cordova-android-support-gradle-release –variable ANDROID_SUPPORT_VERSION=27.+
and run/build again.


ERROR ITMS-90174: “Missing Provisioning Profile – Apps must contain a provisioning profile in a file named embedded.mobileprovision.”
https://stackoverflow.com/a/52654888/1190051


> cordova build ios –release
CordovaError: Promise rejected with non-error: ‘ios-deploy was not found. Please download, build and install version 1.9.2 or greater from https://github.com/ios-control/ios-deploy into your path, or do \’npm install -g ios-deploy\”
at cli.catch.err (/Users/stephenmonro/ionicApps/C4I International/node_modules/cordova/bin/cordova:29:15)
at process._tickCallback (internal/process/next_tick.js:68:7)
[ERROR] An error occurred while running subprocess cordova.

cordova build ios –release exited with exit code 1.

Re-running this command with the –verbose flag may provide more information.
Analyzing dependencies
Downloading dependencies
Generating Pods project
Integrating client project
Pod installation complete! There is 1 dependency from the Podfile and 1 total pod installed.
Updating spec repo `master`
$ /usr/bin/git -C /Users/stephenmonro/.cocoapods/repos/master fetch origin –progress
remote: Enumerating objects: 1441, done.
remote: Counting objects: 100% (1441/1441), done.
remote: Compressing objects: 100% (236/236), done.
remote: Total 2771 (delta 1275), reused 1191 (delta 1191), pack-reused 1330
Receiving objects: 100% (2771/2771), 320.66 KiB | 767.00 KiB/s, done.
Resolving deltas: 100% (1828/1828), completed with 553 local objects.
From https://github.com/CocoaPods/Specs
5bdc3da58dc..70702dce5ff master -> origin/master
$ /usr/bin/git -C /Users/stephenmonro/.cocoapods/repos/master rev-parse –abbrev-ref HEAD
master
$ /usr/bin/git -C /Users/stephenmonro/.cocoapods/repos/master reset –hard origin/master
HEAD is now at 70702dce5ff [Add] TidySplits 1.0.4
Updating spec repo `trunk`

CocoaPods 1.9.0.beta.3 is available.
To update use: `sudo gem install cocoapods –pre`
[!] This is a test version we’d love you to try.

For more information, see https://blog.cocoapods.org and the CHANGELOG for this version at https://github.com/CocoaPods/CocoaPods/releases/tag/1.9.0.beta.3

The file /Users/stephenmonro/ionicApps/C4I International/platforms/ios/Christians for Israel.xcworkspace does not exist.
Problem solved here: unplug the ipad, or the device.
https://github.com/ios-control/ios-deploy/issues/332#issuecomment-552854357

Solution:

I experience this error if my phone is connected to my computer (via cable) when I am running the build command.

Simply unplugging the cable solved the problem.

 


npm update


ERROR:
[app-scripts] fs.js:114
[app-scripts] throw err;
[app-scripts] ^
[app-scripts] Error: ENOENT: no such file or directory, scandir ‘/Users/stephenmonro/ionicApps/wpimportsqlite/node_modules/node-sass/vendor’
[app-scripts] at Object.readdirSync (fs.js:785:3)

SOURCE:
https://github.com/sass/node-sass/issues/1579#issuecomment-452181858

FIX:
node ./node_modules/node-sass/scripts/install.js


ERRORS:

stephenmonro@SMMMacPro:~/ionicApps/wpimportsqlite$ ionic serve
> ionic-app-scripts serve –address localhost –port 8101 –livereload-port 35730 –dev-logger-port 53704 –nobrowser
[app-scripts] [23:24:14] ionic-app-scripts 3.2.4
[app-scripts] [23:24:14] watch started …
[app-scripts] [23:24:14] build dev started …
[app-scripts] [23:24:14] Proxy added:/wp-json => https://www.c4israel.org/wp-json
[app-scripts] [23:24:14] Proxy added:/resources/app/pdf => https://www.c4israel.com.au/resources/app/pdf/
[app-scripts] [23:24:14] clean started …
[app-scripts] [23:24:14] clean finished in 2 ms
[app-scripts] [23:24:14] copy started …
[app-scripts] [23:24:14] deeplinks started …
[app-scripts] [23:24:15] deeplinks finished in 336 ms
[app-scripts] [23:24:15] transpile started …
[app-scripts] [23:24:22] typescript: node_modules/@types/node/events.d.ts, line: 21
[app-scripts] ‘=’ expected.
[app-scripts] L20: function on(emitter: EventEmitter, event: string): AsyncIterableIterator<any>;
[app-scripts] L21: const captureRejectionSymbol: unique symbol;
[app-scripts] ‘=’ expected.
[app-scripts] [23:24:22] typescript: node_modules/@types/node/events.d.ts, line: 32
[app-scripts] L32: const errorMonitor: unique symbol;
[app-scripts] [23:24:23] typescript: node_modules/@types/node/repl.d.ts, line: 361
[app-scripts] ‘=’ expected.
[app-scripts] L361: const REPL_MODE_SLOPPY: unique symbol;
[app-scripts] ‘=’ expected.
[app-scripts] [23:24:23] typescript: node_modules/@types/node/repl.d.ts, line: 367
[app-scripts] [23:24:23] typescript: node_modules/@types/node/util.d.ts, line: 26
[app-scripts] L367: const REPL_MODE_STRICT: unique symbol;
[app-scripts] ‘=’ expected.
[app-scripts] L25: let replDefaults: InspectOptions;
[app-scripts] L26: const custom: unique symbol;
[app-scripts] ‘=’ expected.
[app-scripts] L120: namespace promisify {
[app-scripts] L121: const custom: unique symbol;
[app-scripts] [23:24:23] typescript: node_modules/@types/node/util.d.ts, line: 121
[app-scripts] [23:24:23] typescript: node_modules/@types/node/events.d.ts, line: 21
[app-scripts] Cannot find name ‘unique’.
[app-scripts] L20: function on(emitter: EventEmitter, event: string): AsyncIterableIterator<any>;
[app-scripts] L21: const captureRejectionSymbol: unique symbol;
[app-scripts] [23:24:23] typescript: node_modules/@types/node/events.d.ts, line: 21
[app-scripts] Cannot find name ‘symbol’. Did you mean ‘Symbol’?
[app-scripts] L20: function on(emitter: EventEmitter, event: string): AsyncIterableIterator<any>;
[app-scripts] L21: const captureRejectionSymbol: unique symbol;
[app-scripts] Cannot find name ‘unique’.
[app-scripts] [23:24:23] typescript: node_modules/@types/node/events.d.ts, line: 32
[app-scripts] L32: const errorMonitor: unique symbol;
[app-scripts] [23:24:23] typescript: node_modules/@types/node/events.d.ts, line: 32
[app-scripts] Cannot find name ‘symbol’. Did you mean ‘Symbol’?
[app-scripts] L32: const errorMonitor: unique symbol;
[app-scripts] Cannot find name ‘unique’.
[app-scripts] [23:24:23] typescript: node_modules/@types/node/repl.d.ts, line: 361
[app-scripts] L361: const REPL_MODE_SLOPPY: unique symbol;
[app-scripts] Cannot find name ‘symbol’. Did you mean ‘Symbol’?
[app-scripts] [23:24:23] typescript: node_modules/@types/node/repl.d.ts, line: 361
[app-scripts] L361: const REPL_MODE_SLOPPY: unique symbol;
[app-scripts] Cannot find name ‘unique’.
[app-scripts] [23:24:23] typescript: node_modules/@types/node/repl.d.ts, line: 367
[app-scripts] [23:24:23] typescript: node_modules/@types/node/repl.d.ts, line: 367
[app-scripts] L367: const REPL_MODE_STRICT: unique symbol;
[app-scripts] Cannot find name ‘symbol’. Did you mean ‘Symbol’?
[app-scripts] L367: const REPL_MODE_STRICT: unique symbol;
[app-scripts] Cannot find name ‘unique’.
[app-scripts] L25: let replDefaults: InspectOptions;
[app-scripts] [23:24:23] typescript: node_modules/@types/node/util.d.ts, line: 26
[app-scripts] [23:24:23] typescript: node_modules/@types/node/util.d.ts, line: 26
[app-scripts] L26: const custom: unique symbol;
[app-scripts] Cannot find name ‘symbol’. Did you mean ‘isSymbol’?
[app-scripts] L25: let replDefaults: InspectOptions;
[app-scripts] L26: const custom: unique symbol;
[app-scripts] Cannot find name ‘unique’.
[app-scripts] L120: namespace promisify {
[app-scripts] L121: const custom: unique symbol;
[app-scripts] [23:24:23] typescript: node_modules/@types/node/util.d.ts, line: 121
[app-scripts] [23:24:23] typescript: node_modules/@types/node/util.d.ts, line: 121
[app-scripts] Cannot find name ‘symbol’.
[app-scripts] L120: namespace promisify {
[app-scripts] L121: const custom: unique symbol;

[INFO] Development server running!

Local: http://localhost:8101

Use Ctrl+C to quit this process

[INFO] Browser window opened to http://localhost:8101!

[app-scripts] [23:24:23] watch ready in 8.56 s
[app-scripts] [23:24:23] copy finished in 8.53 s

SOURCE:
https://forum.ionicframework.com/t/typescript-error-expected-and-more/181140/10?u=stephenmonro
FIX:
npm install typescript@2.7.2


Error:

[23:51:47] typescript error
Cannot find type definition file for ‘@types’.

[23:51:47] ionic-app-script task: “build”
[23:51:47] Error: Failed to transpile TypeScript
Error: Failed to transpile TypeScript
at errorCheckProgram (/Users/stephenmonro/ionicApps/wpimportsqlite/node_modules/@ionic/app-scripts/dist/aot/aot-compiler.js:119:39)
at Object.<anonymous> (/Users/stephenmonro/ionicApps/wpimportsqlite/node_modules/@ionic/app-scripts/dist/aot/aot-compiler.js:89:21)
at step (/Users/stephenmonro/ionicApps/wpimportsqlite/node_modules/@ionic/app-scripts/dist/aot/aot-compiler.js:32:23)
at Object.next (/Users/stephenmonro/ionicApps/wpimportsqlite/node_modules/@ionic/app-scripts/dist/aot/aot-compiler.js:13:53)
at fulfilled (/Users/stephenmonro/ionicApps/wpimportsqlite/node_modules/@ionic/app-scripts/dist/aot/aot-compiler.js:4:58)
[ERROR] An error occurred while running subprocess ionic-app-scripts.

LINK:
https://github.com/ionic-team/ionic-app-scripts/issues/1529#issuecomment-496652630

SOLUTION:
What seems to fix it is to add
“types”: []
to the
tsconfig.json’s compilerOptions.


 

High Sierra Security Update Jan 2020 Problem

Posted on Updated on

Today, I followed the update procedure of Apple to update to the latest MacOS Security updates. And… it didn’t go so well…

I tried the old PRAM reset and also an SMC reset as well. It still didn’t work. I got in to the recovery part as well, and was able to do a first aid on the disk. It all checked out well.

I also tried Safe Mode, but that didn’t really work properly, but it did spit out a lot of good information. I spotted something along lines of it hanging on a KEXT or similar.

Nothing really worked and it just stayed on this window, it basically looks like it’s hung…

After a few hours, nothing.

So I went to an Apple store, and asked for the most geeky non-retail person. They didn’t have what I needed, so have now booked in to see a genius.

I came home and thought I’d try and fix it again.

I came across this website.

https://www.justinsilver.com/technology/os-x-el-capitan-10-11-1-hanging-on-boot-fixed/

So, instead I tried this and logged in via Single User mode and followed this section.

The OS X Fix You’ve Been Looking For

I was ultimately able to surmise that the issue was an incompatible kernel extension (kext file). After booting into Recovery Mode, I opened Terminal. First I mounted the filesystem as read write, then navigated to /Volumes/Macintosh HD/Library/Extensions, created a new folder named ‚ÄúUnsupported‚ÄĚ and moved all the kext files into it, then rebooted.

Note: see the updated script at the very bottom of this post to automatically remove non-default kexts. If you have renamed your hard drive to something other than ‚ÄúMacintosh HD‚ÄĚ use the new name in the following commands.

1
2
3
4
5
mount -rw /
cd /Volumes/Macintosh\ HD/Library/Extensions/
mkdir Unsupported
mv *.kext Unsupported
reboot

 

So, in short, it was as I suspected, to be a suspect KEXT file.

This will get you out of trouble.

 

0-02-07-59cfb6b6844a7f864f3dd4525a69a9b6cf4b124766e54b4c2c553dc3aa21be28_1c6d9a9fe8e0ff

I hate asynchronous JS programming

Posted on Updated on

This has to be the biggest problem I face when using JS.

It’s not like VB, VBScript, BAT, BAS, C# or other serial, linear programming languages.

It drives me crazy.

I’m still of the opinion that all code should still be sequential by default, and if you want a function to be async, then you should just tell that specific call to be async, rather than the other way around. An opt in, rather than “you’re already in and tough luck”.

To make like easier (and I’ve stolen this code to post here, as it makes life easier and so I can find it again later) here is some code of a working practical example.

 

Serial or Chaining Flow

If you want to execute different promise methods sequential i.e. execute one by one, it is easy using Async/Await and the code looks like synchronous.

async function SerialFlow(){
let result1 = await doJob(1,1);
let result2 = await doJob(2,2);
let result3 = await doJob(3,3);
let finalResult = result1+result2+result3;
console.log(finalResult);
return finalResult;
}
SerialFlow();

In above method first 1 is executed and wait for one sec then 2 is started wait for 2 seconds after that 3 started to execute. 1,2,3 are executed sequentially, hence the total time is 6 seconds.

Console Output:

Start: 1
End: 1
Start: 2
End: 2
Start: 3
End: 3
6

 

Just about every other example online gives non-practical examples and use promises, observables, awaits, asyncs, call-back hell, jargon that mostly doesn’t make sense. I hope this very simple example will help you.

 

Here is my very crude example of partially working code, of which you can see there are things going on.

async function getpostcoderegion(state)
{
¬†¬†var¬†dataselection¬†=¬†document.getElementById(“dataselection”).value;
¬†¬†var¬†dateparams¬†=¬†“&date=”¬†+¬†dataselection;
// Confirm as CITY
// Confirm as REGIONAL
¬†¬†var¬†params¬†=¬†“state=”¬†+¬†state¬†+¬†dateparams;
  var xhttp =  new XMLHttpRequest();
    xhttp.onreadystatechange = await function() {
    if (this.readyState == 4 && this.status == 200) {
      citystations = JSON.parse(xhttp.responseText);
      console.log(citystations);
    }
  };
¬†¬†xhttp.open(“POST”,¬†“getpostcodecitystate.php”,¬†true);
¬†¬†xhttp.setRequestHeader(‘X-Requested-With’,¬†‘XMLHttpRequest’);
¬†¬†xhttp.setRequestHeader(‘Content-Type’,¬†‘application/x-www-form-urlencoded’);
  xhttp.send(params);
  return 1;
}

async  function postcodeboundariesshow(state_location)

{
  // Collected the postcodes of those that are for the city/metor areas in that state.
    //getpostcoderegion(state_location);
¬†¬†¬†¬†var¬†file_location¬†=¬†“../../geo_json/”¬†+¬†state_location¬†+¬†“.postcode.json”;
 geojsonLayer[state_location] = new L.GeoJSON.AJAX(file_location, {
    onEachFeature: onEachFeature,
¬†¬†¬†¬†“fillOpacity”:¬†.05,
¬†¬†¬†¬†color:¬†“#F00”,
    weight: 1,
  })
  .addTo(mymap);
¬†¬†¬†return¬†“2”;
}

 

// RUN THE MAGIC FROM THIS FUNCTION.
async function postcodeboundaries(state_location)
{

  // Collected the postcodes of those that are for the city/metor areas in that state.
    let a = await getpostcoderegion(state_location);
    let b = await postcodeboundariesshow(state_location);
}

Ionic 3 Background Geolocation

Posted on

It’s taken a long time to get to this stage, but this is just the start…

After having followed the instructions on this site, I got a long way.

But, I also only got so far as well… Here is a copy of my “home.ts” file for an app.

 

import { Component } from '@angular/core';
import { NavController, Platform } from 'ionic-angular';
import { BackgroundGeolocation, BackgroundGeolocationConfig, BackgroundGeolocationResponse, BackgroundGeolocationEvents } from '@ionic-native/background-geolocation';
import { LocalNotifications } from '@ionic-native/local-notifications';

@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {

config: BackgroundGeolocationConfig = {
desiredAccuracy: 10,
stationaryRadius: 20,
distanceFilter: 30,
debug: true, // enable this hear sounds for background-geolocation life-cycle.
stopOnTerminate: false, // enable this to clear background location settings when the app terminates
};

missionCode: string = "";
userId: string = "";

constructor(public navCtrl: NavController,

private plt: Platform, 
private backgroundGeolocation: BackgroundGeolocation,
public globals: GlobalsProvider,
private localNotifications: LocalNotifications) {


if(this.plt.is('core') || this.plt.is('mobileweb')) {

// NO. It's a browser.
// Use a different GPS method.

} else 
{
// YES. It's a a compilerd app.


this.backgroundGeolocation.configure(this.config)
.then(() => {

this.backgroundGeolocation.on(BackgroundGeolocationEvents.location).
subscribe((location: BackgroundGeolocationResponse) => {
console.log(location);


this.showNotification(location);


// IMPORTANT: You must execute the finish method here to inform the native plugin that you're finished,
// and the background-task may be completed. You must do this regardless if your HTTP request is successful or not.
// IF YOU DON'T, ios will CRASH YOUR APP for spending too much time in the background. 
this.backgroundGeolocation.finish(); // FOR IOS ONLY
});

}); 
}

}

startBackgroundGeolocation() {
// start recording location
this.backgroundGeolocation.start();
}

stopBackgroundGeolocation() {
// If you wish to turn OFF background-tracking, call the #stop method.
this.backgroundGeolocation.stop();
}

showNotification(data){
// Schedule a single notification
this.localNotifications.schedule({
id: 1,
text: JSON.stringify(data),
sound: 'file://sound.mp3',
data: { secret: "key" }
});
}

}

 

My packages.json file looks like this:

{
"name": "My App",
"version": "0.0.1",
"author": "Ionic Framework",
"homepage": "http://ionicframework.com/",
"private": true,
"scripts": {
"start": "ionic-app-scripts serve",
"clean": "ionic-app-scripts clean",
"build": "ionic-app-scripts build",
"lint": "ionic-app-scripts lint"
},
"dependencies": {
"@angular/animations": "5.2.11",
"@angular/common": "5.2.11",
"@angular/compiler": "5.2.11",
"@angular/compiler-cli": "5.2.11",
"@angular/core": "5.2.11",
"@angular/forms": "5.2.11",
"@angular/http": "^5.2.11",
"@angular/platform-browser": "5.2.11",
"@angular/platform-browser-dynamic": "5.2.11",
"@auth0/angular-jwt": "^1.2.0",
"@babel/core": "^7.8.4",
"@ionic-native/background-geolocation": "^4.20.0",
"@ionic-native/core": "~4.11.0",
"@ionic-native/geolocation": "^4.20.0",
"@ionic-native/http": "^4.20.0",
"@ionic-native/local-notifications": "^4.20.0",
"@ionic-native/splash-screen": "~4.11.0",
"@ionic-native/status-bar": "~4.11.0",
"@ionic/storage": "^2.2.0",
"cordova-android": "^7.1.1",
"cordova-browser": "^6.0.0",
"cordova-plugin-advanced-http": "^2.4.0",
"cordova-plugin-badge": "^0.8.8",
"cordova-plugin-device": "^2.0.3",
"cordova-plugin-file": "^6.0.2",
"cordova-plugin-geolocation": "^4.0.2",
"cordova-plugin-ionic-keyboard": "^2.2.0",
"cordova-plugin-ionic-webview": "^2.5.3",
"cordova-plugin-local-notification": "^0.9.0-beta.2",
"cordova-plugin-mauron85-background-geolocation": "^3.0.1",
"cordova-plugin-splashscreen": "^5.0.3",
"cordova-plugin-whitelist": "^1.3.4",
"cordova-sqlite-storage": "^4.0.0",
"emulator": "0.1.0",
"glob": "^7.1.6",
"ionic-angular": "3.9.2",
"ionicons": "3.0.0",
"leaflet": "^1.6.0",
"leaflet-ant-path": "^1.3.0",
"leaflet-draw": "^1.0.4",
"leaflet-gps-tracker": "^1.2.1",
"leaflet-polyline": "0.0.2",
"leaflet.freedraw": "^2.0.1",
"native-run": "^0.3.0",
"node-sass": "^4.13.1",
"resolve": "^1.15.0",
"rxjs": "5.5.11",
"sw-toolbox": "3.6.0",
"zone.js": "0.8.26"
},
"devDependencies": {
"@ionic/app-scripts": "^3.2.4",
"typescript": "~2.6.2"
},
"description": "The best way to manage your searches from an emergency management control point.",
"cordova": {
"plugins": {
"cordova-plugin-geolocation": {
"GEOLOCATION_USAGE_DESCRIPTION": "To locate you"
},
"cordova-plugin-whitelist": {},
"cordova-plugin-device": {},
"cordova-plugin-splashscreen": {},
"cordova-plugin-ionic-webview": {},
"cordova-plugin-ionic-keyboard": {},
"cordova-sqlite-storage": {},
"cordova-plugin-advanced-http": {},
"cordova-plugin-mauron85-background-geolocation": {},
"cordova-plugin-local-notification": {}
},
"platforms": [
"browser",
"android"
]
}
}

 

This code is a little old, but please note, the version numbers in my packages.json file.

Leaflet Performance issues

Posted on Updated on

I’m really enjoying working with Leaflet at the moment, but this problem had plagued me for days, where all of a sudden, my performance levels dropped to almost nothing.

Basically I went from this:

this.globals.map.locate(
{ 
maxZoom: 111,
drawControl: true,
watch:true,
enableHighAccuracy:true
}).on('locationfound', (e) => {

this.locationdata = { "coords":{"latitude": e.latlng.lat, 
"longitude": e.latlng.lng,
"accuracy" : e.accuracy, 
"altitude" : e.altitude, 
"heading" : e.heading,
"speed" : e.speed,
"timestamp" : e.timestamp
}};

}

 

To this:

this.map.locate(
{
maxZoom: 111,
drawControl: true,
enableHighAccuracy:true
}).on('locationfound', (e) => {

this.locationdata = { "coords":{"latitude": e.latlng.lat,
"longitude": e.latlng.lng,
"accuracy" : e.accuracy,
"altitude" : e.altitude,
"heading" : e.heading,
"speed" : e.speed,
"timestamp" : e.timestamp
}};
}

 

What’s the difference you say?

” watch:true,”

Basically, if you have have this running like this, it will keep on checking the GPS signal in the background, and eventually cripple everything, because your phone device can’t keep up with the app. GPS time-outs will occur and things won’t complete. So, if you remove the watch:true statement, things will still work well, and you can call it every second, or every 10 seconds, or whatever your tracking needs are.

My full issue was that exponentially, the app was just slowing down to a complete halt and anything to do with the map would slow and stop working. It would begin fine, but within a few minutes, the app was unusable.

So, this is my (partial) solution. It should be enough to help you get by.

I’ve found it’s easier to do something like this:

this.subscr = Observable.interval(1000) 
.flatMap(() => this.getData())
.subscribe(data => { 
//console.log("App 1 second heartbeat"); 
// Call the GPS tracker bit
this.GetRealTimeLocationNow(); /// THIS FUNCTION INCLUDES THAT GPS METHOD
if(this.trackedRoute.length >0)
{
this.redrawPath(this.trackedRoute); 
}
});

 

So, after a couple of days thinking it was layer and mapping problems (with showing hiding markers or tracking lines and rewriting that entire part), and optimising the app even more, I think it’s pretty good now. This will be more or less confirmed over time though.

You can draw a tracking line like this too:

current_positionTrack: any [];


somefunction_etc()
{
// Show the current location on the map
if (this.current_positionTrack != undefined) 
{
 if(this.map)
  {
   this.map.removeLayer(this.current_positionTrack);
  } 
 }; 

this.current_positionTrack = leaflet.polyline(path, {color: 'red', weight: 1, opacity: 0.7, smoothFactor: 1});
this.map.addLayer(this.current_positionTrack); 
}

And even have a marker that stays on the screen on your location too, like this:

marker = null;


some_other_function_etc () //or whatever
{

// Probably should go after this in the GPS tracker bit:
// }).on('locationfound', (e) => {
// You'll figure it out.
 
 if (!this.marker) {
  this.marker = leaflet.marker(e.latlng).addTo(this.map);
 }

 if(e.latlng != null)
 {
  this.marker.setLatLng(e.latlng);
 }
}

node-sass ionic nodejs error fix

Posted on Updated on

Sometimes you go on a bug fixing journey and get no-where. Like always, when I find a solution to a lengthy problem, I write it up so I can remember it later.

I had this error show up, after doing an update to the latest version of Ionic, and for over an hour and a half, I upgraded NPM packages and everything, changed and updated code and got no-where.

I then went back and reverted to my last commit, rerun this command: (as found here)

node node_modules/node-sass/scripts/install.js

Where it eventually started working again.

Happy, but rather frustrated that it has to happen.

stephenmonro@SMMMacPro:~/ionicApps/project$ ionic serve
> ionic-app-scripts serve --address localhost --port 8100 --livereload-port 35729 --dev-logger-port 53703 --nobrowser
[app-scripts] fs.js:114
[app-scripts] throw err;
[app-scripts] ^
[app-scripts] Error: ENOENT: no such file or directory, scandir '/Users/stephenmonro/ionicApps/project/node_modules/node-sass/vendor'
[app-scripts] at Object.readdirSync (fs.js:785:3)
[app-scripts] at Object.getInstalledBinaries (/Users/stephenmonro/ionicApps/project/node_modules/node-sass/lib/extensions.js:132:13)
[app-scripts] at foundBinariesList (/Users/stephenmonro/ionicApps/project/node_modules/node-sass/lib/errors.js:20:15)
[app-scripts] at foundBinaries (/Users/stephenmonro/ionicApps/project/node_modules/node-sass/lib/errors.js:15:5)
[app-scripts] at Object.module.exports.missingBinary (/Users/stephenmonro/ionicApps/project/node_modules/node-sass/lib/errors.js:45:5)
[app-scripts] at module.exports (/Users/stephenmonro/ionicApps/project/node_modules/node-sass/lib/binding.js:15:30)
[app-scripts] at Object.<anonymous> (/Users/stephenmonro/ionicApps/project/node_modules/node-sass/lib/index.js:14:35)
[app-scripts] at Module._compile (internal/modules/cjs/loader.js:701:30)
[app-scripts] at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
[app-scripts] at Module.load (internal/modules/cjs/loader.js:600:32)

[ERROR] ionic-app-scripts has unexpectedly closed (exit code 1).

The Ionic CLI will exit. Please check any output above for error details.
stephenmonro@SMMMacPro:~/ionicApps/project$ nodejs node_modules/node-sass/scripts/install.js
-bash: nodejs: command not found
stephenmonro@SMMMacPro:~/ionicApps/project$ node node_modules/node-sass/scripts/install.js
Downloading binary from https://github.com/sass/node-sass/releases/download/v4.13.1/darwin-x64-64_binding.node
Download complete
Binary saved to /Users/stephenmonro/ionicApps/project/node_modules/node-sass/vendor/darwin-x64-64/binding.node
stephenmonro@SMMMacPro:~/ionicApps/project$ ionic serve
> ionic-app-scripts serve --address localhost --port 8100 --livereload-port 35729 --dev-logger-port 53703 --nobrowser
[app-scripts] [01:26:03] ionic-app-scripts 3.2.4

 

Also, another fun bug you could be chasing for a long this is to do with the .subscribe method.

‚ÄúERROR TypeError: Object(‚Ķ) is not a function‚ÄĚ.

For example, the following code:

this.httpClient.post( this.globals.apiserver + "post_user_track_location.php", trackstringdata, options)
.subscribe(data => { 
this.returned = data; 
//console.log (this.items); 
console.log (data); 
});

If you are running off a “localhost” change it to 127.0.0.1.

It may just work for you.