esp8266 Witty ( kind of ) intro

A couple of months ago a new development board based on the popular esp8266 was created.

It seems like a compact version of the popular nodemcu board that includes an RGB led and an LDR. It is called esp8266 witty ( you’ll find them for just a couple of dollars on ebay or aliexpress) and the idea was to split the UART interface into a dedicated board that can be attached to the esp8266 whenever you need to program it or access the serial interface to read data (clever design guys).

The board comes with a custom firmware flashed which I honestly didn’t try to explore because I’m used to nodemcu firmware. Connection was established using the ESPlorer at 115200bps. After connecting this is what we can see:

Welcome screen ESPlorer esp8266 witty version

Flashing the nodemcu firmware is straightforward just like any with any nodemcu dev board… keep the flash button pressed while pressing reset and use the esp tool to flash the firmware:

esptool flashing esp8266

And there you go, nodemcu firmware is now running:

nodemcu firmware flashed by esptool.py

On a side note, the baud rate changed from 115200 to 74880. This is an unusual value for it, but if it doesn’t work for you, just play with the values until you find what works for you.

I couldn’t find a lot of documentation regarding this module and how to access the LDR and the RGB led. Fortunately it was very easy to find out.

The esp8266 modules have a single pin with analog reading capabilities ( pin 0 ) and that was it. For the digital pins controlling the led channels all I had to do was a simple for loop to iterate over all the digital pins and find out which ones were triggering the blue, read and green channels. It ended up being pin 6, 7 and 8.

The following lua snippet will output green under good light conditions and red under low light:

-- Output pins:
-- 6: Green
-- 7: Blue
-- 8: Red
 
-- Input pins:
-- 0: LDR
 
 
function clearOutput()
  for i=6,8 do
    gpio.mode(i, gpio.OUTPUT)
    gpio.write(i, gpio.LOW)
  end
end
 
 
tmr.alarm(1, 1000, 1, function()
  -- Output LOW on all channels
  ldr_value = adc.read(0)
  print(string.format("Current LDR value: %d", ldr_value))
 
   clearOutput()
   if ldr_value > 600 then
     gpio.write(6, gpio.HIGH)
     gpio.write(8, gpio.LOW)
   else
     gpio.write(6, gpio.LOW)
     gpio.write(8, gpio.HIGH)
   end
 
end )

Have fun! :)

Useful links:
esptool.py – https://github.com/themadinventor/esptool
nodemcu firmware binaries – https://github.com/nodemcu/nodemcu-firmware/releases
ESPlorer – http://esp8266.ru/esplorer/

NodeMCU based Greenhouse Controller

Winter is coming!

A few days ago I started a new project to help me take care of my peppers. Winter is coming ( pun intended ) and unfortunately it’s a bit harsh here in Portugal for people who likes to grow peppers, specially tropical strains that are used to good weather.

For that reason, it all started as simple thermostat that could tell me the temperature over the internet but soon lots of other ideas started to pop up in my mind. So I started developing a tiny appliance that could allow me to control a few things and that’s how this project started.

I don’t plan on creating something super fancy and for that reason these are the initial hardware requirements:

  • NodeMCU
  • DHT11 – Temperature and Humidity sensor
  • Digital light sensor
  • 3v Relay module with four relays
  • 16×02 LCD module with an I2C adapter

The idea is very simple: The NodeMCU will create a tiny web api that can be used to retrieve data about the sensors and trigger the relays. That information can also be seen on the LCD so that you can check the sensors when you enter the greenhouse.

The webapp will output the information in json format so that you can easily integrate it with another application.

NodeMCU Greenhouse Controller

I’ll post the rest of the howto in the next days but feel free to check the repository containing the code. If you can contribute with ideas or some code, feel free to! :)

https://github.com/zatarra/nodemcu-greenhouse-controller

Unlocking Netflix contents on OSX – The easy way

Netflix was launched here in Portugal one day ago. I was really excited because I was finally going to be able to get an account and start enjoying all the contents that they have to offer.

That was until I checked the catalog…

Currently the catalog has 354 movies or tv shows which is a very poor selection. I didn’t want to turn to VPNs or DNS services that could route traffic through their services but unfortunately I had no choice. Since I work in security, I know how these things can turn south like people found out recently.

But the truth is that I need to trust in a foreign node at some point because without a US IP address netflix wouldn’t show me the full catalog. Searching for netflix and DNS the first link that popped up seemed exactly what I was looking for except that I didn’t want to use their DNS servers for all the requests ( again, security ringing a bell ) a vector for Pharming attacks.

So the idea was to use one of those DNS providers that route traffic through their servers whenever we wanted to access netflix, but only for netflix related requests. Sure I could just setup a DNS server and create a custom zone for netflix but that seemed an overkill. That is how I discovered that OSX supports a feature which allows you to do exactly that: the “/etc/resolver/” folder.

The idea is simple, you just create a folder ( if it doesn’t exist already ) and create a file inside it using the name of the domain that you want to use custom DNS servers. Inside that file you just put the address of the custom DNS servers for that domain and you’re all set!

laptop:resolver xxxXXXxxx$ pwd
/etc/resolver
laptop:resolver xxxXXXxxx$ ls -altr
total 8
drwxr-xr-x  95 root  wheel  3230 Oct 22 09:31 ..
-rw-r--r--   1 root  wheel    51 Oct 22 09:32 netflix.com
drwxr-xr-x   3 root  wheel   102 Oct 22 10:14 .
laptop:resolver xxxXXXxxx$ cat netflix.com
nameserver 46.101.36.120 
nameserver 46.101.149.135
laptop:resolver xxxXXXxxx$

In this case I used the IP addresses of tvunblock but you can try other ones.

Bear in mind that if you use tvunblock, you need to open their website from time to time to keep active your IP address.

Enjoy your improved list of contents :)

How to use Sublime to develop and run code without launching duplicate processes

I’ve been learning a lot about pyQT and definitely started using Sublime as my IDE. There was just one thing that was annoying me, which was the pile of windows that were being left behind each time I called the Build Action in Sublime (I easily forget about closing them).

Fortunately Sublime is so easy and powerful, that changing this behavior was very easy.

First I changed a small file that contains the settings for the Build action for Python (This is the path for OSX, for Windows/Linux it will be different, just google for it):

~/Library/Application Support/Sublime Text 2/Packages/Python/Python.sublime-build

Instead of calling the Python interpreter directly, I’ve piped this to a simple bash script which will handle that. The json file mentioned above contains one child attribute named “cmd”. Change that to a bash script of yours. Don’t forget to keep passing the filename as argument. This is how mine looks like:

“cmd”: [“/usr/local/bin/python-sublime-build”, “$file”]

And this is the content of my python-sublime-build file:

#!/bin/bash
ps -A| grep $1 | grep -v $0 | grep -v grep | cut -d' ' -f1 | xargs kill -9
/usr/local/bin/python -u $1

Aaaaand that’s it. :)

There’re lots of different ways of doing it, but this one works for me. I could probably do everything in Sublime without using an external bash script but I’m feeling lazy today ūüėÄ

PS: Same principle can be applied to any other language. Just make sure that you edit the sublime build file accordingly (each language has one I think) and have a bash script for it.

Read the UID from a HID iClass smartcard ( Px G8L )

A couple of guys asked me to create a simple python script to allow the iClass cards to be read and extract their UID to control a few other devices. I thought of sharing with you since there are a few other people asking for the same on the Internet.

from smartcard.CardType import AnyCardType
from smartcard.CardRequest import CardRequest
from smartcard.util import toHexString, toBytes
from smartcard.CardMonitoring import CardMonitor, CardObserver
from smartcard.util import *
import urllib2
import time
 
class printobserver( CardObserver ):
    """A simple card observer that is notified
    when cards are inserted/removed from the system and
    prints its uids. The code is not pretty but it works!
    """
 
    def update( self, observable, (addedcards, removedcards) ):
        apdu = [0xff, 0xca, 0, 0, 0]
        for card in addedcards:
          try:
            cardtype = AnyCardType()
            cardrequest = CardRequest( timeout=1, cardType=cardtype )
            cardservice = cardrequest.waitforcard()
            cardservice.connection.connect()
            response, sw1, sw2 = cardservice.connection.transmit(apdu)
            tagid = toHexString(response).replace(' ','')
            print tagid
            #urllib2.urlopen("http://your_web_servers_waiting_for_card_data/?uid=%s" % tagid, None, 3)
          except Exception as e:
            print "Exception detected: %s" % e
 
print "Card Monitor started..."
cardmonitor = CardMonitor()
cardobserver = printobserver()
cardmonitor.addObserver( cardobserver )
while True:
  time.sleep(3600)

It was tested using an Omnikey 5321 v2 USB reader and it was working perfectly. I know that I’m doing two calls to the device (the first one detects it and the second one requests the UID) and this could probably be done in a single pass. If you know how to do it, please step forward :)

PS: It was also shared on github: https://gist.github.com/zatarra/75df47c8bd5a8d913cb4

Converting the Mindflex into an open source wireless EEG tool

During the last days, I’ve been reading a lot about Lucid Dreaming and the¬†several alternatives¬†of accomplishing it. If you google the subject you’l find dozens of tiny gadgets promising the do it, but very few will really help in that because one of the key actions consists in detecting REM (Rapid Eye Movement) which only seem to be possible either by using some EEG equipment to monitor your brain or by analyzing the eye movement during sleep. The second option seems to be too complex for me because I couldn’t find any similar gadget that could be hacked.

And that’s where the Mindflex comes into play. The Mindflex is a toy developed by Mattel which uses a headband to read brainwaves and control games. It uses a processor from Neurosky very similar to the one on their official Development Kit.

Searching for the available options I’ve stumbled upon an awesome post ( http://frontiernerds.com/brain-hack ) describing in detail this little gadget and how to hook it to an arduino. This was almost perfect except that I wanted that this could remain portable and could be connected to any bluetooth enabled device directly.

 

Tools Required:

HC-06 Bluetooth module ( http://www.ebay.com/sch/i.html?_trksid=p2050601.m570.l1313.TR0.TRC0.H0.Xhc-06+module&_nkw=hc-06+module&_sacat=0&_from=R40 )

hc06

HC-06 Bluetooth mobule

Mindflex headband

500x_mindflex_headset

Bluetooth enabled device.

 

The hardware hack is fairly simple. Just connect the Pin1 of the BT dongle to the T pin on the headband, Pin2 to the R pin, Pin3 to GND and Pin4 to VCC. Just two quick side notes:

* I was lazy enough to solder the BT dongle directly to the battery header. To do a perfect job you should remove the pcb and solder the BT dongle to the power switch (so that it can be turned on/off  without removing the batteries).

* Connecting the Pin2 to the R pin is not necessary because we’re just listening ¬†but it doesn’t hurt doing so. We never know when someone might be able to find a new feature that could require it. :)

 

To parse the data I had to come up with a python script to do it since I couldn’t find anything ready for use other than the arduino lib:

#!/usr/bin/python
import serial
import sys
 
latestByte  = ('c')
lastByte    = ('c')
inPacket    = False
myPacket    = []
PLENGTH     = 0
 
EEGVALUES    = []
EEGRAWVALUES = []
 
def parsePacket():
  if checksum():
    i=1
    while i < len(myPacket) - 1:
      if ord(myPacket[i]) == 0x02:
        POOR_SIGNAL = ord(myPacket[i+1])
        i += 2
      elif ord(myPacket[i]) == 0x04:
        ATTENTION = ord(myPacket[i+1])
        i += 2
      elif ord(myPacket[i]) == 0x05:
        MEDITATION = ord(myPacket[i+1])
        i += 2
      elif ord(myPacket[i]) == 0x16:
        BLINK_STRENGTH = ord(myPacket[i+1])
        i += 2
      elif ord(myPacket[i]) == 0x83:
        for c in xrange(i+1, i+25, 3):
          EEGVALUES.append(ord(myPacket[c]) << 16 | ord(myPacket[c+1]) << 8 | ord(myPacket[c+2]))
        i += 26
      elif ord(myPacket[i]) == 0x80:
        EEGRAWVALUES = ord(myPacket[i+1]) << 8 | ord(myPacket[i+2])         i += 4     print "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d" % (POOR_SIGNAL,ATTENTION,MEDITATION,EEGVALUES[0],EEGVALUES[1],EEGVALUES[2],EEGVALUES[3],EEGVALUES[4],EEGVALUES[5],EEGVALUES[6],EEGVALUES[7])   else:     print "Invalid Checksum!" def checksum():   x = 0   for i in range(1, len(myPacket) -1):     x += ord(myPacket[i])   return ~(x&255) & 0b11111111 == ord(myPacket[len(myPacket)-1]) def readCSV():   global myPacket, lastByte, LatestByte, inPacket, PLENGTH   ser = serial.Serial(       port=sys.argv[1],       baudrate=9600,       parity=serial.PARITY_NONE,       stopbits=serial.STOPBITS_ONE,       bytesize=serial.SEVENBITS   )   ser.isOpen()   try:     while 1 :       while ser.inWaiting() > 0:
        latestByte = ser.read(1)
 
        if ord(lastByte) == 170 and ord(latestByte) == 170 and inPacket == False:
          inPacket   = True
 
        elif len(myPacket) == 1:
          myPacket.append(latestByte)
          PLENGTH = ord(myPacket[0])
 
        elif inPacket == True:
          myPacket.append(latestByte)
          if len(myPacket) > 169:
            print "Error: Data Error too long!"
            del myPacket[:]
            inPacket = False
            del EEGVALUES[:]
          elif len(myPacket) == PLENGTH + 2:
            parsePacket()
            del myPacket[:]
            inPacket = False
            del EEGVALUES[:]
 
 
        lastByte = latestByte
 
  except KeyboardInterrupt:
    print('Exiting...')
    if ser.isOpen():
      ser.close();
    sys.exit(0)
 
if len(sys.argv) < 2:
  print "Mindflex datalogger by David gouveia <david.gouveia[at]gmail[dot]com>"
  print "Usage: %s " % sys.argv[0]
  sys.exit(1)
 
readCSV()

This will be the result (tested on OSX):

brain.py output

PS: I know that this script probably looks like crap. Feel free to improve it or check github for an updated version :)
https://gist.github.com/zatarra/6d2be801010c7eb844f0

Futebol na TV

Last weekend I’ve decided to create a new Android application. The idea is very simple and all I wanted was something that could show me which football games were going to be aired by TV channels available in Portugal.¬† There are some websites that have this information available but I wanted something easier to use. And that’s how this tiny app was created.

Main screen from Futebol na TV

It is very simple to use. All you have to do is make sure you have Internet access and press the refresh button. That it :)

Merge Strava’s GPX exported files

Last Weekend something happened during a morning ride on my bike with some friends and my GPS device turned off for no reason. When I turned it back on I didn’t have the choice of continuing a previous ride and I had to create a new ride.

When I got home and tried to upload the information the Strava I couldn’t find any feature which could let me merge rides and fixe the issue. Instead I ended up having two different rides which really annoyed me.

I started googling around and found someone suggesting that I export the rides and merge the contents of the files. They also suggested that this could be done directly concatenating the files which isn’t true. The trick here is to extract the tracking data from the files (GPX files exported from Strava are XML based) and using the first one as the metadata template.

This was the result of a very simple GPX merger:

#!/usr/bin/env php -q
<?php
/*
* StravaMerger © David Gouveia - http://www.davidgouveia.net
* Simple script to merge tracking data from Strava's exported GPX files.
* The backtrack_limit is there because some files could not be parsed due to their size.
* Feel free to raise the limit but be carrefull not to cross the limit.
* Instead of using regex, I could have used a XML cursor to overcome the backtrack limit
* but either I would have to use the php_xml extension or build my own parser.
*/
ini_set("pcre.backtrack_limit", "10000000");
 
if ( !trim( $argv[1] ) || trim( !$argv[2] ) || sizeof($argv) < 4 )
               die("Usage:\n$argv[0] file1.gpx file2.gpx <fileN.gpx> output.gpx\n" );
 
$segments ="";
 
 
for($i = 1; $i < sizeof($argv) - 1; $i++)
{
        echo "Processing $argv[$i] ...";
        if (!is_file( $argv[$i] ) ) die( "Invalid file: $argv[$i]\n" );
 
        $gpx = file_get_contents( $argv[$i] );
        if ( $i == 1 )  preg_match( "/^(.*?)<trkseg>.*?<\/trkseg>(.*?)$/is", $gpx, $metadata );
        preg_match("/<trkseg>(.*?)<\/trkseg>/ims", $gpx, $matches);
        if( trim( $matches[1] ) )
        {
                $segments .= $matches[1];
                echo "[OK]\n";
        }
        else
                echo "[FAIL]\n";
 
}
 
$output_file = $metadata[1] . "<trkseg>" . $segments . "</trkseg>" . $metadata[2];
 
file_put_contents($argv[sizeof($argv) -1], $output_file) or die( "Unable to create destination GPX\n" );
print "File " . $argv[sizeof($argv) -1] . " successfully created.\n";

I’m going to put an online version of this script to make it easier to use. ūüėČ

Outra forma de desactivar a rede PT-WIFI

Ok, este vai ser um post simples. Existe outra forma de desactivarem o hotspot da PT-WIFI do vosso router e apenas precisam de um cliente de telnet.

1¬ļ Acedam via telnet ao endere√ßo IP do router. Utilizem o nome de utilizador sumeo e a password bfd,10ng

telnet 192.168.1.254

2¬ļ Executem os seguintes comandos:

wireless
mssid
iflist

Neste momento irá ser listada a lista de SSIDs que são propagados pelo vosso router. Em teoria deverão ser três (dois da PT-WIFI e um da vossa rede).

Para apagar basta usar o comando ifdelete usando a seguinte sintaxe:

ifdelete
ssid
radio

O √ļnico valor que muda √© o do ssid pois o radio (que identifica a placa de rede associada √© sempre o mesmo: 0). Os SSIDs come√ßam no zero o que significa que para apagar o terceiro deveriam usar o seguinte commando:

ifdelete
ssid_id = 2
radio_id = 0

Basta portanto apagarem todos e no final salvar a configuração com:

saveall

E por fim sair:

exit

Como desactivar o Hotspot da PT-WIFI nos routers Thomson

Se tens o serviço de fibra da PT (quer seja MEO ou Sapo) já deves ter reparado que a PT silenciosamente activou um Hotspot da PT-WiFi através da tua ligação um pouco ao estilo das redes ZON Free Internet.

A ideia √© boa, a forma como foi implementada √© que √© simplesmente absurda. N√£o s√≥ o fizeram de forma camuflada, acedendo e alterando a configura√ß√£o do router sem o conhecimento e consentimento do cliente, como excluiram qualquer hip√≥tese de ser desactivada, ou seja, somos todos for√ßados a ceder a nossa largura de banda e a patrocinar um servico que pode at√© beneficiar os clientes mas que foi feito com intuitos meramente comerciais. Mais ainda, os routers como qualquer outro dispositivo possuem limita√ß√Ķes, e n√£o sendo estes modelos uma gama profissional (qualquer hotspot PT-WiFi presente num Hotel ou centro comercial utiliza equipamentos Cisco ou Nortel que em NADA se assemelham a estes thomson) podem sofrer degrada√ß√£o de performance da rede wireless pois ainda que seja uma rede virtual diferente, os interfaces fisicos s√£o os mesmos.

Mais! Se a velocidade contratada forem 100Mbits e tendo em conta que esta é também a velocidade máxima do equipamento, isto significa que se alguém estiver ligado na rede irá reduzir a vossa largura de banda contratada!

Dito isto e porque sou a favor da liberdade de escolha por parte do cliente, encontrei uma forma de desactivar novamente o hotspot PT-WIFI:

1¬ļ Acedam ao interface web do router via http://192.168.1.254

2¬ļ No ecr√£ de login, activem a consola de javascript ( cada browser tem a sua pr√≥pria forma de aceder √† consola, mais informa√ß√Ķes aqui) e colem o seguinte c√≥digo:

var user = "Debug";
var hash2 = "91cd28f3d8d3a503e9839caaa2929123";
 
var HA2 = MD5("GET" + ":" + uri);
document.getElementById("user").value = user;
document.getElementById("hidepw").value = MD5(hash2 + 
                              ":" + nonce +":" + 
                              "00000001" + ":" + 
                              "xyz" + ":" + 
                               qop + ":" + HA2);
document.authform.submit();

Ap√≥s clicarem no Enter v√£o entrar no interface de gest√£o com permiss√Ķes especiais, entre elas o poder de desligar o hotspot PT-WiFi.

3- Acedam ao painel de configura√ß√£o da rede Wireless do router. No fundo da p√°gina v√£o encontrar um novo link com a designa√ß√£o “Defini√ß√Ķes Hotspot”. Cliquem nele.

4- Aqui encontram as defini√ß√Ķes do Hotspot PT-WiFi. Cliquem em desactivar et voila!

Disfrutem do vosso router livre de qualquer acesso.

Antes de terminar este post no blog, deixo-vos com mais duas perguntas retóricas:

 

PS: Obrigado √† malta da ptsec.info por ter disponibilizado os dados de acesso como root (mais informa√ß√Ķes aqui).