Pebble Timeline node for Node-RED

Nathan - Sun, 22/11/2015 - 14:55
Pin Notification

The reason behind the last post was so that I could create a node for Node-RED to send pins to the Timeline on a Pebble smartwatch.

To use this you obviously need a Pebble Time (or a classic Pebble once the Timeline update is available) but you will also need a Timeline user token which is unique to you the user and an installed Pebble app. I detailed in the last post about how you can create a simple app to get a token or you can just install my Timeline Token app on your watch and get one that way.

The Timeline User Token is entered into the node and is stored in the credentials file in your .node-red directory.

To send a pin into the Timeline msg.time needs to be set, this is the time that the pin will show in the Timeline and in the example flow above it is coming from the Inject node. The title of the pin can either be set in the msg.payload or in the title of the Pebble node itself.

Optionally the following additional items can be set:

msg.duration is an integer of the time in minutes that the pin will remain in the now view of the timeline.

msg.body can be used to set the body text of the pin.

If msg.notify is set to true then a notification will appear on the watch when the pin is created, otherwise it will be silently inserted into the timeline.

I’ve added it to npm so you can install it easily with npm install node-red-contrib-pebble and it can also be found on my github here.

Other things that could be implemented in the future are reminders and updating pins although the latter would require knowing the id of the pin, the id isn’t required for a basic pin but is for the notifications, I’m just using a UTC timestamp for that here.

Pin Notification Pin in Timeline Opened pin


Node setup Simple function example



Categories: Community Blog posts

Sending Pins to the Pebble Timeline

Nathan - Sun, 22/11/2015 - 14:49
Pins added via Node.js

There are a number of different libraries available for sending pins to the Timeline on a Pebble watch, including those for Javascript, Node.js, Ruby, Python, PHP and C.  To use any of these you need a unique user token which is a UUID unique to both an app installed on the watch and the user, I couldn’t find a straightforward description of what is required to get a token so I’ve detailed what needs to be done below.

Getting a token the easy way

If you just want to do it the easy way I’ve created a Timeline Token app which is available on the Pebble Appstore, once installed on your Pebble it will display the token and give you a short URL to view it on the web (to save retyping the lengthy UUID from the Pebble screen).

My Timeline Token app, aka the easy way

If you use my app you can jump straight to step 5 below to test it.

Regardless of whether you use my app or create one using the process below it will need to remain installed in the Pebble phone app for pins using the resulting token to come through to your watch.

Step by step guide

This is the process to create your own simple app to get a Timeline user token.

Step 1: Create an app

The app serves two purposes, it gets us the unique user token and enables pins to be sent to the watch.

Creating an app is easy to do online, no need to install an SDK or dev environment, first log in to CloudPebble.

Create a new app with the project type of “Pebble.js (beta)” and give it a name, eg. Timeline Token

Click on app.js under SOURCE FILES, delete the default code it gives you and replace it with the following:

/** * Just gets the Timeline token */ var UI = require('ui'); var myToken; Pebble.getTimelineToken( function (token) { console.log('My timeline token is ' + token); myToken = token; var tokenDisplay = new UI.Card({ subtitle: 'Timeline Token', body: myToken });; }, function (error) { console.log('Error getting timeline token: ' + error); } );

Then go to COMPILATION on the left and then click BUILD, when that is done click GET PBW to download the .pbw file.

Step 2: Add the app to the Pebble app store

This step is required so that Pebble have the UUID of your app and allows you to enable timeline support for it. You don’t need to publish the app, just uploading it and enabling timeline is sufficient.

Create a Pebble developer profile if you don’t already have one.

Click “Create a Watchapp”

Give it a name and click create

On the next page click “Add a release” and upload the .pbw file you downloaded from step 1 above.

You do not need to publish the application, it just needs to be uploaded so that Pebble have the apps UUID which is required for sending the pins.

If the release status says “Validation pending” wait a few seconds and refresh the page and you should now see it showing Ready and you will now see the UUID in the Application data section above.

Now click Enable timeline button.

Step 3. Get the timeline token

Now back in CloudPebble, under COMPILATION click the BASALT button at the top to run the app in the Pebble Time emulator.

When it runs and shows the token on the emulated Pebble’s screen click the “VIEW APP LOGS” button where you will see your timeline token in the log, eg.

My timeline token is e6b41993c9604c458f7bee3cd501d0ec

Copy the token and save it in a safe place.

You need never use CloudPebble or the Developer Portal again once you have the token.

Step 4. Install the app on your phone

The final step is to load the app on to your phone as the pins will only work while the app is installed in the Pebble Time app.

Step 5. Test it

Now we can try a test, there are a number of libraries available or you can do a PUT to the web API with Curl.

As an example, to test it with the node.js:

Install with: npm install pebble-api

Create a file eg. pebble.js with the following (inserting your user token where indicated)

var Timeline = require('pebble-api').Timeline; var timeline = new Timeline(); var userToken = 'ENTER YOUR USER TOKEN HERE'; var pin = new Timeline.Pin({ time: new Date(), duration: 10, layout: new Timeline.Pin.Layout({ type: Timeline.Pin.LayoutType.GENERIC_PIN, tinyIcon: Timeline.Pin.Icon.NOTIFICATION_FLAG, title: 'Pin Title' }) }); timeline.sendUserPin(userToken, pin, function (err) { if (err) { return console.error(err); } console.log('Pin sent successfully!'); });

Then run it with node pebble.js and you should shortly see the pin arrive on your Pebble.

The help page here details how you can create notifications, reminders and open apps using the pins as well as the names for the different icons that are available.

In the next post I’ll talk about the node I created for Node-RED to do this.


Categories: Community Blog posts

Programmer PCB Triple Play

JeeLabs - Wed, 18/11/2015 - 00:01

To follow up on last week’s upload articles, I’m going to turn a couple of these boards into Black Magic Probe programmers:

From left to right: an STM Nucleo F103RB (any Nucleo will do, though), a board from eBay (many vendors, search for “STM32F103C8T6 board”), and Haoyu’s HY-TinySTM103T.

And let’s do it right, with a couple of custom PCB’s – here are three versions (the first one will keep its original firmware, actually). Each does have slightly different usage properties:

Each of these supports uploading, serial “pass-through” connection, and h/w debugging. Building one of these, or getting a pre-built & pre-loaded one, is a really good investment.

(For comments, visit the forum area)

Categories: Community Blog posts

Spectrum analysis with RFM12B

mharizanov - Mon, 16/11/2015 - 21:48

The comments to my last blog post got me thinking if I had chosen the right RFM channel at home, obviously if the channel is noisy that directly affects reception and increases the error rates. I use the default 868Mhz setting for the RFM12B/RFM69s at home and decided to check if the channel is clear from other transmissions. I remembered seeing a RFM12B spectrum analyzer project over at Jeelab some years ago, and 5 minutes later was running the spectrum analyzer using one of my Funky v3s equipped with a 868Mhz RFM12B.

The result is as follows:

There are strange peeks at 864 and 870Mhz, the signal level is weak, less than -97dBm, but other than that it is very clean spectrum. And no wonder, I live in a small suburban village. That’s good result, the default 868Mhz band seems clear. I was curious about the two peaks and took another scan at my office in downtown Sofia, the result is much noisier spectrum, but oddly the peaks are there too, in fact couple more are clearly visible as well plus a faint trace of third one:

Most probably these are harmonics from DVB-T or other strong signal, but the area around 868Mhz seems clear both in the city and at home. Good to know. Scanning the spectrum and choosing a free channel to use is an effort well worth when initially setting up a wireless sensor network.



Page views: 703

Categories: Community Blog posts

Talking to an STM32

JeeLabs - Wed, 11/11/2015 - 00:01

When dealing with ARM µCs and boards based on them, there’s always one big elephant in the room: how to upload software to them, and how to talk to them via serial or USB.

The available options, choices, trade-offs, and even just their properties can be staggering. This week’s article series is about what the problem is, an overview of the many different ways to address them, and how to get started with the minimal fuss and/or minimal cost.

On the menu for this week are four dishes, served on a daily basis:

Fortunately, we’ll need very little to get going. We can pull ourselves up by our bootstraps!

(For comments, visit the forum area)

Categories: Community Blog posts

RFM69 to MQTT gateway using ESP8266

mharizanov - Sat, 07/11/2015 - 20:51

I’ve mentioned my plans for this project during the IoT hangout session few months ago, it has finally materialized as working prototype. The blocker so far was the lack of ESP8266 RFM69 driver and free time on my end, so I’ve teamed up with Andrey Balarev to solve this. Andrey is an IoT enthusiast + embedded systems developer and has done excellent job in porting LowPowerLab’s RFM69 library for the ESP8266. He spent few weekends staring at the oscilloscope, re-writing SPI library code and managed to solve a number of challenges to get this library going. I’ve bundled his driver code with MQTT to get a beautifully working prototype that forwards RFM69 traffic to MQTT and vice versa. Few screenshots of the setup:

Some folks probably ask why the RFM69 and not RFM12B and why LowPoweLab’s library and not Jeelib, I’ve outlined my view on that before here. Basically with Jeelib we are forcing the RFM69 in artificial compatible mode and not taking fill advantage of the chip.

What I plan to add as functionality is payload serialization configuration, payload field name configuration and RPN based signal processing configuration so that JSON could be constructed/deconstructed from payloads in both directions.

It will be a replacement for the RFM2Pi project, a much more advanced standalone M2M gateway for the IoT.

I’ll build few PCBs and put some for sale in my shop as well. RFM69 library code will be shared at that point.



Page views: 2255

Categories: Community Blog posts

The world of STM32

JeeLabs - Wed, 04/11/2015 - 00:01

As announced last week, I’ll be switching (pouring?) my efforts into a new series of µC’s for a while, so there’s quite a bit of work ahead to get going, and I really don’t want to dwell too much on the basics. The whole point is to get further, not redo everything and get nowhere!

So for this week, there will be a whole slew of posts. As usual, each next post will be ready on successive days, as I figure it all out and try to stay ahead of the game :)

Here is a sneak preview of the main character in this exciting new adventure:

(For comments, visit the forum area)

Categories: Community Blog posts

How Hair Dryers Work to Fix Your Hair Problems

FairTradeElectronics - Tue, 03/11/2015 - 17:16

Not many people will take some time to learn how some the things that they use everyday work. For example, only few women would actually devote even just a little of their precious time to know how a hair dryer works in order for them to deal with some problems concerning their hair. This might be the right opportunity to provide some helpful knowledge about how this simple machine works.

The Difference between Past Hair Dryers and their Upgrades

The very idea of the way a hair dryer works is that hot air comes out from it. But that was for modern hair dryers today. Before, dryers actually work by sucking air right inside on its body, with the hope of eventually drying wet hairs.

How A Hair Dryer Works and the Science Behind It

Upon application of power to the hair dryer, the fan installed inside it will spin enabling the dryer to have a supply of air which will pass through wire coils that will heat the air. The result is a hotter air that can be directed to the hair from a safe distance. The hot air speeds up the process of water evaporation, thus ridding your hair of moisture and making it dry faster. The process seems pretty much simple, but it takes a lot more of science to ensure that this process is carried our properly every time a hair dryer is used.

Comparing It to Traditional Methods of Hair Drying

Modern hair dryers have repeatedly gained advantage every time comparison between them and traditional methods of hair drying are drawn. Visiting sites such as definitely helps a lot of women get the dryers that they want. Perhaps, this is because a lot of people appreciate its fast and more efficient nature, as compared when you repeatedly comb your hair or leave your towel in it for a long period of time just to get rid of its moisture.


Categories: Community Blog posts

Making a sharp turn

JeeLabs - Wed, 28/10/2015 - 00:01

During my tinkering over the past two weeks, I hit a snag while trying to hook up the LPC824 µC to the Arduino IDE. Nothing spectacular or insurmountable, but still…

This week, I have two articles for you, explaining what this is all about:

Warning: there are going to be some changes w.r.t. where I’ll be going next…

(For comments, visit the forum area)

Categories: Community Blog posts

3D Printed Cases For TinyTX and Tiny328

Nathan - Sun, 25/10/2015 - 21:35
3D printed case ith TinyTX3 and Tadiran 3.6V AA battery.

Another post I’ve been meaning to write for a long time. I finally got my Rigidbot 3D printer in August 2014 some 9 months later than the estimate but I was one of the lucky ones, many had to wait a lot longer and some have even had to pay extra for delivery, having already paid it once as the company completely ran out of funds. I am very happy with the printer though, I’ve printed all kinds of things since I’ve had it and it has produced some great results.

One of the main things I had in mind for it was printing customised enclosures for my electronics projects. I’ve used a variety of off the shelf cases for my indoor TinyTX and Tiny328 sensors, my favourite being the Evatron EN30W sensor case but I really wanted to design something of my own.

Case being printed

After a few aborted attempts using other 3D CAD packages I discovered the joys of OpenSCAD an open source 3D CAD package that allows you to write code to construct the 3D model instead of the more traditional graphical model. When I had first seen this tool I thought it seemed wrong, to approach what I saw as a graphical problem in a programmatic way but in retrospect it makes total sense as we are dealing with precise numbers here and being able to code parts in modules allows you to easily turn various parts of the design on and off easily and scale the whole design just by changing a few defines as well as easily reuse modules in other designs. Once you get in to the right mindset it really is good.

OpenSCAD showing the code window on the left and a render of the two parts of the case on the right.

At the top of the code window you can see there are some defines to select whether it should render just the top or bottom of the case or the full thing, whether there should be vents in the top and how long they should be, if a square or round cut out is required for a cable or sensor to stick out of and if mounting holes are required in the back half of the case.

The next section sets the width and length of the PCB section and the battery holder section so I can set which board I am using and whether it is a single or double battery holder.  Then it goes on to configure how long the vents on the top should be and the dimensions and positions of the cut outs if required.

Once happy with that it’s just a case of exporting it as an STL file which I then process with Slic3r and send onto Octoprint running on a Raspberry Pi connected to the printer ready to be printed.

This prints really well on my printer, there are no clips to hold it together as such, the extended pieces in the corners are just made to a tight enough tolerance that they grip the top of the case as it is pushed on. I’ll probably tweak this a bit more over time but it does the job as it stands, the dimensions can be adjusted but as noted in the code comments there are some issues with the PCB supports not scaling properly once the PCB length gets over 46mm.

I’ve put the code on my Github here if anyone fancies giving it a try.

Finished case closed With TinyTX3 and single 3.6V Tadiran battery For 2 x AA batteries Tiny328 version Stevenson Screen After 12 months exposed to the weather.

One of the early prints I did was this Stevenson screen which is an enclosure for outdoor sensors, the principle is to shield the sensors from direct heat radiation from outside sources while still allowing air to circulate freely. I used the STL files from Thingiverse here, if I recall correctly it took over 20 hours to print all the parts (over several days). It consists of four identical middle sections (more or less if you want it bigger or smaller), a top section and the base section. It’s a well designed object, each piece clips together very well and I was lucky enough to have a piece of plastic pipe that it fitted to perfectly (thanks to the random fly tipper that threw it over my back fence!).

I printed it using PLA which being biodegradable isn’t ideal but it was all I had. I wasn’t sure how well it would stand up to the weather but after 12 months it doesn’t look any different than it did when I first put it out there. I did think of treating it with something to protect it but decided to leave it as an experiment to see how it fares over time.

Inside the box mounted below it is one of my Tiny328 boards and four AA batteries connected to the regulated input, this is connected to a DHT22 temperature and humidity sensor which is suspended from the top of the stevenson screen so that it is positioned roughly in the middle.

Below are some pictures of it coming together and there is also a timelapse video here of one of the sections being printed.

One middle section being printed Three middle sections clipped together The finished stevenson screen, September 2014


PIR housing PIR Housing

One other related item that I’ve printed is this nice compact housing for the cheap BIS0001 based PIR motion sensors. I got this one from Thingiverse here and there are two versions available, one with square edges and one more rounded, I’ve used the rounded one.

Categories: Community Blog posts

Lenny, The bot that fools telesales callers

Nathan - Sat, 24/10/2015 - 18:34

I mentioned in the last post that I send all but a select few callers on my landline straight to voicemail but that’s actually no longer true. Thanks to a casual comment by @ichilton on Twitter I’ve recently switched to diverting calls from unknown numbers to Lenny.

Lenny who? Lenny is an Asterisk dial plan which together with a set of very convincing recordings works as a bot to fool telesales callers into thinking they are talking to a real person. Lenny will answer then wait for the caller to speak and when they stop he moves on to the next recording, it really is very convincing and there are some great recordings of people having lengthy conversations with him on this YouTube channel.

Lenny is very simple to set up, you can find the voice files attached to this forum post and full instructions for setting it up here but briefly you just need to add the following dialplan into your /etc/asterisk/extensions_custom.conf

[from-internal-custom] ;# // BEGIN Lenny Remake ; version 0.3.2 copyright: none claimed. Enjoy! exten => 53669,1,Answer exten => 53669,n,Set(TIMEOUT(absolute)=600) exten => 53669,n,Set(MACHINE=0) exten => 53669,n,Set(OPTION=5) exten => 53669,n,Set(TALK_DETECTED=0) exten => 53669,n,Set(RECORDING=${UNIQUEID}) exten => 53669,n,MixMonitor(/tmp/Lenny/${RECORDING}.wav) exten => 53669,n,NoOp(Recording will be available: /tmp/Lenny/${RECORDING}.wav) ;exten => 53669,n,Playback(en/this-call-may-be-monitored-or-recorded) exten => 53669,n,Gosub(playit(Lenny1)) exten => 53669,n,Gosub(playit(Lenny2)) exten => 53669,n,Gosub(playitonce(Lenny3)) exten => 53669,n,Gosub(playitonce(Lenny4)) exten => 53669,n,Gosub(playitonce(Lenny5)) exten => 53669,n,Gosub(playitonce(Lenny6)) exten => 53669,n,Gosub(playitonce(Lenny7)) exten => 53669,n,Gosub(playitonce(Lenny8)) exten => 53669,n,Gosub(playitonce(Lenny9)) exten => 53669,n,Gosub(playitonce(Lenny10)) exten => 53669,n,Gosub(playitonce(Lenny11)) exten => 53669,n,Gosub(playitonce(Lenny12)) exten => 53669,n,Gosub(playitonce(Lenny13)) exten => 53669,n,Gosub(playitonce(Lenny14)) exten => 53669,n,Gosub(playitonce(Lenny15)) exten => 53669,n,Gosub(playitonce(Lenny16)) exten => 53669,n,Gosub(playitonce(Lenny2)) exten => 53669,n,Gosub(playitonce(Lenny3)) exten => 53669,n,Gosub(playitonce(Lenny6)) exten => 53669,n,Gosub(playitonce(Lenny8)) exten => 53669,n,Gosub(playitonce(Lenny9)) exten => 53669,n,Gosub(playitonce(Lenny10)) exten => 53669,n,Gosub(playitonce(Lenny14)) exten => 53669,n,Playback(en/tt-monkeys) exten => 53669,n,Hangup exten => 53669,n(playit),NoOp(Lenny speaks and repeats until reponse) exten => 53669,n,Set(LOCAL(lennyclip)=${ARG1}) exten => 53669,n(oncemo),Set(TALK_DETECTED=0) exten => 53669,n,Background(lenny/${lennyclip}) exten => 53669,n,AMD(2500,1500,800,5000,100,50,3,256) exten => 53669,n,NoOp(${AMDCAUSE}) exten => 53669,n,GotoIf($["${AMDCAUSE:0:17}"="INITIALSILENCE-25"]?reststop) exten => 53669,n(mach),WaitForSilence(700,3) exten => 53669,n,Goto(humn) exten => 53669,n(reststop),WaitForSilence(800,2) exten => 53669,n,Goto(oncemo) exten => 53669,n(humn),Return exten => 53669,n(playitonce),NoOp(Lenny speaks once) exten => 53669,n,Set(LOCAL(lennyclip)=${ARG1}) exten => 53669,n(noresponse),Background(lenny/${lennyclip}) exten => 53669,n,AMD(2500,1500,800,5000,100,50,3,256) exten => 53669,n,NoOp(${AMDCAUSE}) ;exten => 53669,n,GotoIf($["${AMDCAUSE}"="INITIALSILENCE-2500-2500"]?noresponse) ;exten => 53669,n,GotoIf($[${AMDSTATUS}=HUMAN]?humn2:mach2) exten => 53669,n(mach2),WaitForSilence(2000,1) exten => 53669,n(humn2),Return exten => 536691,1,NoOp(Rerouting inbound call...) ;exten => 536691,n,Flite("After the beep, enter extension or press pound for Lenny.") ;exten => 536691,n,Read(SENDTO,beep,7) ;exten => 536691,n,GotoIf($["foo${SENDTO}" = "foo"]?5:6) exten => 536691,n,Set(SENDTO=53669) exten => 536691,n,System(echo "Channel: local/${SENDTO}@from-internal" > /tmp/ exten => 536691,n,System(echo "MaxRetries: 0" >> /tmp/ exten => 536691,n,System(echo "RetryTime: 3" >> /tmp/ exten => 536691,n,System(echo "WaitTime: 30" >> /tmp/ exten => 536691,n,System(echo "Context: bridgit" >> /tmp/ exten => 536691,n,System(echo "Extension: 4" >> /tmp/ exten => 536691,n,System(echo "Priority: 1" >> /tmp/ exten => 536691,n,System(mv /tmp/ /var/spool/asterisk/outgoing) ;# // END Lenny Remake

Copy the audio files to /var/lib/asterisk/sounds/lenny and make sure the directory and contents are owned by the asterisk user & group.

Reload the Asterisk dialplan with: asterisk -rx “dialplan reload”

and then you can check it is working by dialling extension 53669.

You can then divert any unwanted calls to this extension to have some fun. I did this by creating a custom extension in FreePBX with a destination of local/53669@from-internal and making this the default route for unknown numbers coming in via the PSTN trunk.

To get call recordings emailed to yourself you can use the following shell script called from cron, you’ll want to make sure you have lame and the mime-construct packages installed.

email="" subj="Lenny Recording $(date)" cd /tmp/Lenny for i in *.wav; do if [ -e "$i" ]; then file=`basename "$i" .wav` lame -h -b 64 "$i" "$file.mp3" rm "$file.wav" /usr/bin/mime-construct --file-auto "$file.mp3" --to $email --subject "$subj" rm "$file.mp3" fi done

So far I haven’t recorded anything of interest, it seems most the telesales calls I have been getting are pre-recorded messages but as soon as I get something good I’ll upload it here.


Categories: Community Blog posts

Sending incoming call info to MQTT

Nathan - Sat, 24/10/2015 - 18:13

I’ve used Asterisk at home since around 2004, originally using a clone of a Digium FXO card and later a Sipura SPA-3000 (later owned and branded by Linksys) to interface to my landline. When that server decommissioned itself (with a bang and bad smell) a year or so ago I switched over to the Asterisk based FreePBX on a Raspberry Pi (using the RasPBX distro) but still using the old but perfectly serviceable SPA-3000. It’s rare that anyone I want to speak to calls me on the landline these days (hi Mum!) but I need to keep it active for my BT Infinity fibre broadband so I may as well have something connected to it. Most of the calls I do get on it are junk so I have Asterisk set up to only ring the phones for a specific set of callers and anyone else just gets dumped straight to voicemail or rejected.

On the old server I had set up various extensions that I could dial to perform tasks or drop me into a home automation menu if I called home from my mobile but it never really got any use so I haven’t bothered reimplementing that but one thing I did want to do was as feed incoming call info (caller number and time and date) into MQTT so I could log it and create notifications or events based on a particular callers numbers using Node-RED.

AGI the “Asterisk Gateway Interface” was obviously the way to do this and it turned out that someone has made this very easy by creating an agi-mqtt bridge.

Setting this up was a doddle:

  1. Clone the agi-mqtt Github into a suitable location on the Asterisk box, I put it in /opt/agi-mqtt/
  2. Copy mqtt.cfg.sample to mqtt.cfg and edit it to set the details for your MQTT server.
  3. Make sure the mqtt python script is executable
  4. Edit /etc/asterisk/extensions_custom.conf and add:[from-pstn-custom]
    exten => _X.,1,AGI(/opt/agi-mqtt/mqtt,/opt/agi-mqtt/mqtt.cfg,calls/pstn-in)

Obviously changing /opt/agi-mqtt/ for the location you used to install agi-mqtt and calls/pstn-in is the topic you want to send the call info to.

Then in Node-Red you can parse the number from the call data passed into the payload, this could just be a simple function to output the caller number such as:

var calldata = JSON.parse(msg.payload);
msg.payload = calldata.callerid;

I do a bit of translation of numbers to names for the select group that might ever call me on my landline so that voice and display notifications use their name instead of the number. I also log all calls to a text file, mainly so I can look at it once in a while and be amazed at all the phone spam I (didn’t) get.

Landlines; The sooner I don’t need one for my internet connection, the better.

Categories: Community Blog posts

Switching Voice Notifications To Ivona

Nathan - Sat, 24/10/2015 - 17:23

I had long used the unofficial Google speech API for voice notifications (TTS) as it has a very good, clear voice, much better than Festival which I had used previously. However late one night a couple of months ago this stopped working as Google started to redirect it to a captcha if you tried access it directly. That’s fair enough I suppose, it’s their service to do with what they like and it was never even advertised as a publicly available API for this purpose so all of us who were using it were on a free ride. I’m sure there will be ways around this but it got me looking at alternatives again.

This lead me to Ivona which is a speech synthesis system originally developed by a Polish company but is now owned by Amazon. Using their beta Speech Cloud service you can get a free account for “development purposes” which allows you to make 50,000 requests per month. I don’t know about you but that is more than enough for me.

My speech notifications originate from several sources but primarily they come from Node-RED which runs on my Debian server and this does not have an audio output connected into my whole house audio system. To get around this I run a small Python script on my always on Xubuntu desktop PC that performs a few functions by subscribing to various MQTT topics, one of which is generating speech. This script also links MQTT to an LED matrix display connected via serial and provides a system for playing sounds, eg. send a payload of redalert.mp3 to the topic notify/sound to get a Star Trek TNG red alert sound. It also allows me to control the master volume via MQTT and operate some basic media player controls.

Integrating Ivona speech into this was easy thanks to the Pyvona Python wrapper for Ivona.

Installing Pyvona is easy:

  1. Make sure you have the requests and pygame packages installed
  2. Clone the Pyvona Github
  3. Run python install

To use it at its simplest you just need to do:

import pyvona
v = pyvona.create_voice(‘access_key’, ‘secret_key’)
v.speak(‘Hello world’)

Changing the access_key and secret_key for the ones you will get from the Credentials section of your free Ivona account.

You can also specify which Amazon data centre to use, setting it to the nearest one for the lowest latency:

v.region = ‘eu-west’

You can also select which of the many Ivona voices to use:

v.voice_name = ‘Salli’

I’ve uploaded my script to Github here, it’s pretty specific to my requirements but may be of use as a starting point for others.


Categories: Community Blog posts

Letterbox Notifications

Nathan - Sat, 24/10/2015 - 17:22
You’ve got mail!

This was a quick project to add notifications for when I get real physical mail. This is something I’ve had on my mind since I made my first SMS doorbell notification system back in 2004 and I finally got around to it last month.

First of all I picked up a cheap internal letterbox flap and fixed that over the internal side of the letterbox opening. Then I took a microswitch that I had salvaged out of an old dot matrix printer some time ago and made a little right angle bracket from some perforated metal strip I had lying around. A few little adjustments to the microswitch actuation lever and I had it operating the switch as soon as the flap was moved even only slightly. It also operates it as it closes but that is easily taken care of in code to prevent duplicate notifcations and can also be used to detect if something is stuck part way through the letterbox instead of being pushed all the way through.

I connected the switch to a TinyTX3 running the same code as I use for reed switches and my doorbell which uses a pin change interrupt to sends a notification via the RFM12B wireless network which is then picked up by the Tiny328 connected to my server. From there Node-RED alerts me via speech and my LED matrix display if I am in or if I am out it sends me a notification via Whatsapp.

For now this is connected to its own dedicated TinyTX but I’ve somehow ended up with no less than 4 TinyTX nodes in close proximity around the door (doorbell, letterbox, outside temperature and hall temperature/air pressure) so I am working on a new node to combine these into one unit as well as adding some more features for controlling LED porch lights and so on. At the moment it is looking like this will be an ESP8266 node so watch this space.

Categories: Community Blog posts

Wireless Sensor Battery Life 3+ Years On

Nathan - Sat, 24/10/2015 - 17:20

I last blogged about this in December 2013 when the second version of my ATmega328 & DS18B20 based temperature sensor, installed on 29 December 2011, had just reached the 2 year mark on the original set of batteries. That’s pretty good going and I’d have been happy with that but how long would it last until those Energizer batteries needed replacing? Well I found out in March of this year when it finally started to report erroneous readings, yes that is over 3 years on one set of AA batteries. To be honest, I did have a false alarm a few weeks prior when it started to transmit very irregularly but it recovered from that, presumably due to the increase in temperature affecting the battery capacity.

Like I said in the last post on this, this particular sensor was positioned where it didn’t have the best signal so it often had to retransmit and being the oldest running one it had started off with some pretty poorly optimised code and was off to a bad start to begin with. Needless to say I am more than happy with this result and I only wish I had logged the battery voltage over time of some of my other sensors but as it is they only report the current level so that Node-RED can alert me if one gets low.

@RossDargan Finally replaced them last month.

— Nathan Chantrell (@nathanchantrell) April 7, 2015

Categories: Community Blog posts

IDE w/ LPC824, part 2

JeeLabs - Tue, 20/10/2015 - 23:01

Let’s get that upload going. Remember, this is about adding a “hardware platform” to the Arduino IDE so it can compile and upload files to a Tinker Pico, based on the LPC824 µC.

There are two parts to this: 1) getting all the IDE setup files right so that it knows how to compile & upload, and 2) implementing pinMode(), digitalWrite(), etc. so they can be used with LPC824 microcontrollers in the same way as with ATmega’s and other µC’s.

So let’s tackle these issues one by one, shall we?

Here’s my very first compile and upload to a Tinker Pico:

(For comments, visit the forum area)

Categories: Community Blog posts

Local hostname for connected devices

mharizanov - Tue, 20/10/2015 - 16:30

Now that we have connected our project to the local network, we are immediately faced with another challenge: how can we reach it? Using WPS/SmartConfig means we force the unit into DHCP settings mode, IP address is auto assigned by the router in that case. You may not have access to the router’s settings to force static IP leases. Finding your connected project’s IP address isn’t exactly trivial and certainly not something we expect from the end-users to be capable of doing themselves. What we need is to simply type the product hostname and it should show up, something like typing “fridge.local” or “garage-door.local” to your phone’s browser should bring you to the device control UI.

It seems that there is no solution that “just works”, it pretty much depends on the setup that you have. iOS supports mDNS/DNS-Sd/ZeroConf out of the box, Windows uses NetBIOS and more recently (from Vista onwards) LLMNR and with Linux  you have to take care to install the respective protocol yourself. I’m not sure about local hostname resolution on Android, I wasn’t able to get it running on my Android devices. Setting DHCP hostname option doesn’t seem to be universal solution either and only works in some cases, if the router supports it.

I’ve included mDNS, NetBIOS and DHCP hostname support in my latest ESP8266 projects, but am still looking for universal solution.




Page views: 502

Categories: Community Blog posts

Arduino IDE w/ LPC824

JeeLabs - Tue, 13/10/2015 - 23:01

What will it take to support the LPC824 µC, i.e. the Tinker Pico, from the Arduino IDE?

As the Arduino IDE has been evolving and growing over the years, more and more µC platforms have been added – both officially and unofficially – after the initial ATmega µC’s. One of the earlier ones was Energia, which was created as a fork to support TI’s MSP430 chips, but as the IDE matured, it has become easier to support several other architectures in the mainstream build as a simple add-on, such as ESP8266 and STM32.

Sooo… let’s try and find out how hard it would be to include our LPC824 µC into the mix:

Update: the following two articles are postponed to next week. Sorry for the bad planning:

  • A quick hack to make it compile – Fri
  • Uploading via the IDE – Sat

So far, this is merely an exploration, as I said. A complete port will take considerably more effort. I’m also considering moving a bit beyond the digitalRead/Write conventions…

(For comments, visit the forum area)

Categories: Community Blog posts

The initial setup problem

mharizanov - Tue, 13/10/2015 - 17:00

The typical end-user of your IoT products wants them up and running fast, with minimum hassle once they bring them home. They don’t want to be presented with initial configuration mechanisms/options they don’t understand, and their enthusiasm quickly diminishes if you make them struggle to get the product going.

A colleague once said “If you can’t explain how it works to your grandma in five minutes, you don’t understand it well enough”, I’d re-phrase that to “If the end user can’t get your product all configured and running in five minutes, you haven’t done good enough work on designing it”. That, of course, raises the bar for the developer. Ease of use comes at the cost of increased analysis/development/testing time, but all that pays off with improvement in customer experience.

When designing IoT hardware you are often balancing product cost vs ease of use. One of the old-school approaches to hardware configuration was to have DIP switches on your PCB, which of course only allows for limited configuration options (not to speak about the complexity for the end-user). Basic LCD graphical UIs with keys ease up this task, but add to the product cost. Configuration over serial connection or re-flashing the product with correct parameters is out of question for a product that claims to be user-friendly.

With the appearance of cheap, Wi-Fi enabled SoCs like the ESP8266 things rapidly changed. It is now possible to send Wi-Fi connection credentials to a non-connected ESP8266 through Espressif’s version of TI’s Smart Config, or use Wi-Fi Protected Setup (WPS) to configure your product’s connection with the simple push of a button. Alternatively one can simply have the ESP8266 start up a Wi-Fi access point with DNS captive portal configuration UI. This means you have a configured, Internet connected product within a minute of plugging it in.

Using a dedicated cloud M2M server you can even eliminate the need to configure the local firewall, avoid software environment setups, and have full control of the connected device in no time. Naturally, security is essential and running things over TLS channel is a must. Firmware over the air updates capability ensure the hardware runs latest bug-free code and gives you peace of mind.

I’m working on a line of next generation connected projects that utilize these (and many more) techniques and putting the the accumulated experience to work.


Page views: 735

Categories: Community Blog posts

Meet the Tinker Pico (again)

JeeLabs - Tue, 06/10/2015 - 23:01

It’s time to get some new hardware out the door, which I’ve been doodling with here at JeeLabs for quite some time, and which some of you might like to tinker with as well.

The first new board is the Tinker Pico, which was already pre-announced a while ago. Here’s the final PCB, which is being sent off to production now, soon to appear in the shop:

As before, each week consists of one announcement like this, and one or more articles with further details, ready for release on successive days of the week – three in this case:

This is merely a first step, running pretty basic demo code. Stay tuned for more options…

(For comments, visit the forum area)

Categories: Community Blog posts
Syndicate content