Wednesday, May 1, 2019

How to fix: Missing third party device support for nRF51422xx

In this post we will address the following error, which can happen even if you do have the packs installed for the nRF51/52.

You will see something like this:
"Missing Devices - The Project references devices, files or libraries that are not installed.  Download and install: Third Party Device Support for Nordic Semiconductor: nRF51422_xxAC" or similar.



After you've pressed "OK" on both dialogue boxes, the first thing to check (although you may have already done this) is locate the pack installer and install the packs for the devices that are missing.


1. Click the pack installer.


2. Locate the manufacturer and specific device you are using on the left-hand pane of the Pack installer (click for larger image).


3. On the right-hand pane, select the 'Packs' tab, and install all the packs.  In this example, you can see drivers, soft devices, software modules and so on.  Install them all.  From the "Generic" section below, install all the ARM (CMSIS, etc.) packs.  Ignore all the other generic packs.  Do not install any examples from the 'Examples' tab.



4. Close down Keil uVision and re-open your project file.  If the error no longer appears then you can stop reading here.  If the same error message re-appears, the most likely culprit is that you're opening a project file from an older version of uVision that what you have installed on your machine.  Click "Project > Manage > Migrate To...".

Then you'll get a dialog box telling you that your project file's migration has completed.


5. Close down your uVision IDE.  You'll notice a new project file.  Open that.  Now you'll (hopefully) notice that the device support error message has gone.


Saturday, March 30, 2019

Woocommerce: How to control inventory of product variations

Lets say you have some t-shirts, and they come in many sizes; S, M, L, XL,  or lets say you have some socks, and they come in different colours: Blue, Grey, Pink and Yellow.



If you run an online store, you'll most likely want to manage your inventory or stock on a colour or size level.  In other words on a product  variation  level.

It would be no good if you had 4 t-shirts left in stock, one of each size, and someone bought one, and customers did not know from the 3 left in stock, which sizes were left.

Well now that you've come across this page, I will show you exactly how to manage your stock on a product variation level for Woocommerce, using plugins and tools that are completely free and easily available.

Let's return to our socks example.


Step 1:  Firstly go to your plugin manager and install this plugin: Woocommerce Stock Manager.  Click 'Install Now' and then 'Activate'.


Step 2:  Go to 'Products', locate the product you want to manage and click 'Edit'.






Step 3:  Under 'Product Data', click the 'Attributes' tab.













Step 4: In our socks case, we will add a new custom product attribute called 'colour' and add 4 values; Blue, Grey, Pink and Yellow.  Make sure you don't forget to check 'also used for Variations'.  While you're here, edit your product to give it a price, sale price (if applicable), shipping weight and shipping sizes, and so on.

















Step 5: Now go to up to Product Data and select 'Variable Product'.









Step 6: Go to 'Variations'.  Click 'Add Variation' for as many variations as you have, and add them all.  In this case, we have added all of our sock colours mentioned in the introductory paragraph.   Click 'Save Changes'.













Step 7:  Go back to the Woocommerce Stock Manager plugin, and click 'Show variables' under 'Product Type'.  Add a price, weight and amount in stock for each variation.  Let's pretend we have only one in stock for each colour, except Pink, which has 2 in stock.













Step 8: Click 'Save All' and go to your Product Page.  Now you should see a drop-down box with your product variation, and you should see the amount in stock change as you change the stock variation.  In the below screenshot we show Yellow socks, which have 1 left in stock.






Wednesday, March 20, 2019

Ubuntu: How to get passphrase-less / password-less SSH set up with GoDaddy

Step 1: Login to GoDaddy with your credentials.
Step 2: Click on "My Products", then click "Manage" on the website you wish to use SSH with.
Step 3: Click "Manage Hosting"








Step 4: Once on the Hosting page, click "Settings" on the website whose hosting you want to access via SSH.











Step 5: Click "cPanel Admin".  Now you're on the cPanel for your website's hosting. Click on "SSH Access", then "Manage SSH Keys".





Step 6: Delete any Public and Private keys that you may already have there.  Open a terminal window.  Navigate to your home directory, and then to the .ssh/ directory.
cd ~
cd .ssh

Step 7:  Once here, you may notice that there are already some files, such as id_rsa, id_rsa.pub and known_hosts.  If you wish to back them up, rename them.  Otherwise we will proceed to generate a new key pair (public and private), and overwrite the ones that already exist.
Type the command ssh-keygen -t rsa -b 4096 and press enter.  When prompted for the file name just press <enter> to use the default name (id_rsa), and if prompted to overwrite press y and then <enter>.  When prompted for a passphrase, just press <enter> twice, unless you want to enter in a pesky password every time you login to your hosting in addition to the public/private key pair.  You now have a public and private key pair which you will use to login to your GoDaddy hosting.



Step 8:  Now that you have your public/private key pair, it's time to provide them to GoDaddy so that you're able to login using SSH.  Under "SSH Access" (where we were before), click "Import Key".





Step 9: Type cat id_rsa to print your private key to your terminal window.  Copy it and paste it into the text box provided (shown below).  Leave the first textbox (name) empty, and the passphrase box empty.  Repeat the same process for id_rsa.pub, which is your private key.  Copy that into the last textbox on the page.  Click "Import" at the bottom of the page.


















Step 10: Important! Click "Back to Manage Keys", then under Public Keys, click "Manage", and then "Authorize".  If you don't authorize the key, you won't be able to login.


Step 11: Repeat steps 1-4 to get back onto the GoDaddy Hosting page for your domain.  You'll notice a section on the bottom right called "Settings".  Under that section you'll see "SSH access".  If it is turned off, you'll need to turn it on.  Upon turning it on, you'll be presented with the IP address and username that you'll need to log in using SSH.  Note these down.





















Step 11:  Open a new terminal window.  Type ssh myusername@<hosting_ip_address>.  Use the username and IP address you picked up in the previous step and press <enter>.  Enter yes when prompted about an unknown host.  And voila!  You're in!  Now you'll be able to access and manage your files from your Ubuntu terminal without ever being asked for a password again!

Wednesday, August 1, 2018

HOW TO: Mongoose OS (mos) local build on Windows.

For those of you who are just getting started with mgos, you might have noticed that you would typically compile your app, or an example app, with a command like this:

mos build --arch <arch> 

For example to build the c_hello firmware example for the esp8266 arch, you would navigate to the c_hello app directory, and build it like so:

cd ~/mongoose-os/fw/examples/c_hello/
mos build --arch esp8266

The output will look like this:
$ mos build --arch esp8266
Connecting to https://mongoose.cloud, user test
Uploading sources (2331 bytes)
Firmware saved to build\fw.zip

fw.zip is the file ready to be flashed onto your device, but where did it come from?  How and where did it get built?  What's actually happening here is that it's connecting to the mongoose cloud, uploading your app's source files building it on the cloud (using their build environment, libraries and OS sources) and spitting it back to you when it's done.

But what if, say, you want to modify a driver or library to suit your needs, or insert some debug printouts to figure out why your device won't work?  Or what happens if you want to build your app without relying on someone else's cloud service?

Then you'll need local build.  Mongoose OS does facilitate this, and it's quite easy, but there are some little hiccups along the way for some users.

Step 1:  Docker CE for Windows
The first thing you're going to need to do is download and install Docker CE (Community Edition) for Windows.  It's free, but you're going to have to sign up (I know.... a pain...); and it's pretty hefty too at about 500MB or so.

Docker will probably ask you to enable the above features in Windows in order for Docker to work.  Keep in mind that if you enable these, VirtualBox will no longer work.


Open the Performance tab of Task Manager and check that Virtualization is enabled.  If it's not, enable it from your BIOS settings.  You may need to do a quick Google search to confirm that your CPU supports virtualization and how to enable it.

In my case I had to go to Windows Features, disable Hyper-V, restart, re-enable Hyper-V, and restart before it would show up as 'Enabled' in the Performance tab.  Some other users report having to do this too.

Step 2:  Install Go for Windows
This should be pretty easy.  Just go to https://golang.org/dl/ and select an x86 or x86_64 self-extracting installer for Windows.

To verify the installation:
> go version
go version go1.10.3 windows/amd64

If this doesn't work.  Add the go path to your environment.

Step 3: Run the local build command

mos build --local --arch --esp8266 --libs-dir ../../../libs/ --repo ../../../../mongoose-os/ --verbose

Verbose is optional.  I like to have it enabled so I can see what's going on.  --libs-dir and --repo are both compulsory.  --libs-dir needs to point to the "libs" directory where you have cloned all your Mongoose OS libs (click for a link to the github), and --repo just simply points to the source of your actual Mongoose OS source which you would clone from here.

You run this command from the root directory of the app that you want to compile.  To check that local build is truly working, you will want to disconnect yourself from the World Wide Web before running the command again.  Enjoy.

Saturday, June 30, 2018

Cronjobs on the ESP8266 with Mongoose OS

This is a copy of a post I made on StackOverflow helping another user getting a Cronjob up and going on mgos, but I thought it might be useful to add it here also, with a bit more info.  All it does is turn on an LED at a particular time of the day and turn it off at another time of the day.
There are 6 steps.  They're all pretty easy.  But if you're less experienced with Mongoose OS or experience a bug, please let me know the comments below.
Step 1: Add wifi setup to your mos.yml so it can connect to your wireless AP.  If you don't do this you won't be able to successfully pull the time from the NTP server using SNTP.
config_schema:
  - ["wifi.sta.enable", true]
  - ["wifi.sta.ssid", "MyAP"]
  - ["wifi.sta.pass", "Passwd"]
Step 2: Add these to your mos.yml. Leave off rpc-uart if you have no intention of making rpc calls over UART.  You'll notice there's a lib sntp in here.  There's nothing that needs to be done after adding it to your mos.yml. You don't need to add anything into your app code.  As soon as an internet connection is established it grabs the latest time.  It uses time.google.com by default.
libs:
  - origin: https://github.com/mongoose-os-libs/sntp
  - origin: https://github.com/mongoose-os-libs/crontab
  - origin: https://github.com/mongoose-os-libs/rpc-service-cron
  - origin: https://github.com/mongoose-os-libs/wifi
  - origin: https://github.com/mongoose-os-libs/rpc-uart
Step 3: In your application code, in the entry point for your app (mgos_app_init()), add crontab handlers.  In this case we're just going to add two cronjobs, one for LED on, and LED off. mgos_crontab_register_handler() takes three arguments, the name of the action (we will get to this in step 6), and the exact name of the callback function, which we will define in the next step.  The third argument is void *userdata. For now it's safe to leave this as NULL, because we don't intend of passing any extra data into our callback functions.
enum mgos_app_init_result mgos_app_init(void) {
  /* Set LED GPIOs as outputs */
  mgos_gpio_set_mode(YOUR_LED_GPIO, MGOS_GPIO_MODE_OUTPUT);

  /* Register crontab handler - LED OFF */
  mgos_crontab_register_handler(mg_mk_str("ledoff"), ledoff, NULL);

  /* Register crontab handler - LED ON */
  mgos_crontab_register_handler(mg_mk_str("ledon"), ledon, NULL);

  return MGOS_APP_INIT_SUCCESS;
}
Step 4: Add callbacks.  These callback functions need to match the name of the second argument of mgos_crontab_register_handler() in the previous step.  It's worth noting that the mos-tool build system is extremely pedantic and with error out if you pass a parameter into a function and don't utilize it.  This is why we use (void) parameter; to trick the compiler into letting us pass.
void ledoff(struct mg_str action, struct mg_str payload, void *userdata) {
  mgos_gpio_write(YOUR_LED_GPIO, 0);
  (void) payload;
  (void) userdata;
  (void) action;
}

void ledon(struct mg_str action, struct mg_str payload, void *userdata) {
  mgos_gpio_write(YOUR_LED_GPIO, 1);
  (void) payload;
  (void) userdata;
  (void) action;
}
Step 5: From your app's main directory, build the app as you normally would (eg. mos build --arch esp8266 --verbose).
Step 6: Add your cronjobs from the web UI or UART:
call Cron.Add '{"at":"0 0 10 00 * *, "action":"ledon"}'
call Cron.Add '{"at":"0 0 16 00 * *, "action":"ledoff"}'
The format of cronjob times on Unix-like systems typically looks like this:
# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12)
# │ │ │ │ ┌───────────── day of week (0 - 6) (Sunday to Saturday;
# │ │ │ │ │                                  7 is also Sunday on some systems)
# │ │ │ │ │
# │ │ │ │ │
# * * * * *  command to execute
But Mongoose OS's cron lib specifies a slightly different format:
# ┌───────────── seconds (0 - 59)
# │ ┌───────────── minutes (0 - 59)
# │ │ ┌───────────── hours (0 - 23)
# │ │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ │ ┌───────────── month 1-12 or JAN-DEC
# │ │ │ │ │ ┌───────────── day of week 0-6 or SUN-SAT
# │ │ │ │ │ │
# │ │ │ │ │ │ 
# * * * * * *