My first attempt at writing and submitting an entry in the BASIC 10Liner game contest and I placed 18/19. Not bad for my first try!
Building ARM Docker images on the Raspberry Pi
Install Docker for ARM using the install script:
curl -sSL https://get.docker.com | sh
From: https://www.raspberrypi.org/blog/docker-comes-to-raspberry-pi/
Set to startup as a service:
sudo systemctl enable docker
Start the service manually now (or reboot to start automatically):
sudo systemctl start docker
Add user to docker group (to run docker cli without sudo):
sudo usermod -aG docker pi
To create a new image from a Raspbian base for ARM, use the Raspbian images from resin (in your Dockerfile):
FROM resin/rpi-raspbian:latest
From: http://blog.alexellis.io/getting-started-with-docker-on-raspberry-pi/
Edit your Dockerfile to include and configure whatever you need, and build an image as normal on the Pi using:
docker build -t tagname .
… and off you go.
Building an Amateur Radio Packet to Twitter bridge: Part 3 – preventing duplicate tweets
In my last post (part 2, also see part 1 here), I talked about Twitter’s API rate limits. Since many Packet Radio transmissions are duplicates by their nature, for example, beacon packets and ID packets, it’s important to have some kind of mechanism to prevent sending these through to Twitter.
The approach I used was to insert each received packet into a MongoDB database, storing the received packet data, who the packet was from and who to, and additional metadata about the packet, for example, when last sent, and when it was last received.
Here’s an example of what each document stored looks like:
{ "_id" : ObjectId("5909828e5a2f130fc8039882"), "firstHeard" : ISODate("2017-05-03T07:11:10.051Z"), "from" : "AE6OR ", "heardTimes" : 1, "infoString" : "¤¤@à¤@@त@ல@`¨@`¨@a\u0003ðHello from 5W Garage packet node AUBURN 73's Steli !\r", "lastHeard" : ISODate("2017-05-03T07:11:10.051Z"), "lastTweet" : ISODate("2017-05-03T07:11:10.051Z"), "to" : "BEACON", "tweet" : "Received station: AE6OR sending to: BEACON : ¤¤@à¤@@त@ல@`¨@`¨@a\u0003ðHello from 5W Garage packet node AUBURN 73's Steli !\r" }
My current logic to check for duplicates and record when a tweet is last sent is:
-
- search for a matching document (tweet details) with a $lt condition that lastTweet is before ‘now – 12 hours’:
document.lastTweet = {'$lt' : moment().utc().subtract(12, 'hours').toDate() };
- This is executed as a findOne() query:
db.collection('tweets').findOne(document).then(function (olderResult) { ... }
- If an existing document older than 12 hours is found, then update properties to record that this same packet was seen now, and the time is was resent was also now (we’ll resend it to the Twitter api after the db updates):
if (olderResult != null) { sendTweet = true; updateProperties = { lastHeard: now, lastTweet: now }; } else { updateProperties = { lastHeard: now }; }
If not older than 12 hours, set properties to be updated to indicate just the lastHeard property
- To either update the existing document or insert a new document if this was the first time this packet was heard, do an ‘upsert’:
db.collection('tweets').update( document, { $set: updateProperties, $inc: {heardTimes: 1}, $setOnInsert: { firstHeard: now, lastTweet: now } }, {upsert: true} ).then(function (response) { ... }
- Depending on the result indicating if we inserted or updated, set a property so on return we know whether to send a new Tweet or not:
if(response.upserted != null || sendTweet) { response.sendTweet = true; } else{ response.sendTweet = false; }
- search for a matching document (tweet details) with a $lt condition that lastTweet is before ‘now – 12 hours’:
The approach is not yet completely foolproof, but it is stopping the majority of duplicate Tweets sent to Twitter so far.
For the full source check the project on github here: https://github.com/kevinhooke/PacketRadioToTwitter .
Building an Amateur Radio packet to Twitter bridge: Part 2 – Understanding Twitter’s API rate limits
Quick update on my project to build an Amateur Radio Packet to Twitter bridge (see here for the first post).
I’ve moved the node.js code to a Raspberry Pi 3. So far I have up and running:
- OAUTH authentication with Twitter (covered in my first post)
- Installed node.js on the Raspberry Pi
- Parsing ax25 Packets read from the TNC-Pi using node.js ax25 library
- MongoDB running on the Raspberry Pi
- Partially implemented duplicate post detection / rate limiting
Twitter provides an incredibly useful REST based API to integrate with their service, but understandably your usage is ‘rate limited’ so you’re not retrieving vast amounts of data or flooding the service with spam Tweets.
To understand their rate limit approach, see this article: https://dev.twitter.com/rest/public/rate-limiting
For limits on POSTs, for example for creating new Tweets: https://support.twitter.com/articles/15364
Per above article, POSTs are limited 2,400 per day, or 100/hour. This means if you’re app could potentially use the POST apis more than 100 per hour, you need to build in some limiting logic in your app so you don’t exceed this threshold.
The rate limits for the /GET REST apis are here, although for my application I’m not relying heavily on GETs, the majority of the calls are POSTS:
https://dev.twitter.com/rest/public/rate-limits
Twitter’s api prevents you from posting duplicate Tweets (see here), although they don’t publish how much time needs to elapse before an identical post is no longer consider a duplicate (see here). This wasn’t something I was planning on handling, but given the repetitive nature of some packet transmissions, for example BEACON packets, and packets sent for ID, this has to be a necessary feature of my app, otherwise in the worst case it would be attempting to tweet a stations BEACON packet every minute continuously.
To handle this I’m storing each Tweet sent, with additional tracking stats, like time last Tweet sent. Using this time stamp I can then calculate the elapsed time between now and the time last sent to make sure enough time has elapsed before I attempt to Tweet the packet again.
This is still a work in progress and there’s still some tweeking to do on the duplicate post detection and rate limiting, but while testing you can see the Tweets sent from my Twitter account @KK6DCT_Packet.
Here’s an example of the packets currently being Tweeted:
Received station: N6YUV sending to: BEACON : N6YUV in Woodland, MBX is N6YUV-1
— KK6DCT-PacketTweets (@KK6DCT_Packet) May 4, 2017