This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

Ruuvitag BLE integration
#1
Hi,
has anyone tried to integrate these BLE temperature/humidity/pressure sensors with LM5? https://ruuvi.com/
I have BLE dongle in LM5 and it seems that it found those Ruuvitags but if I try to read response from it, it just gives *nil to log or says that error in connection.

Here is specs for ruuvitag data: Ruuvitag dataformat

This is script that I used for connecting to Ruuvi:
require('ble')
ble.up()
sock = ble.sock()
res,err=ble.settimeout(sock, 15)
res,err,errno = ble.connect(sock,"f7:14:56:d0:33:d5")


if res then
rx = ble.sockreadhnd(sock, 0x0499)
log(rx)
end
log(res,err,errno)
ble.close(sock)




Script that I used for scan BLE devices:

require('ble')

-- enable ble
ble.up()

list = {}

-- mac -> group address mapping
known = {
  ['f7:14:56:d0:33:d5'] = '9/1/1',
  ['CD:F5:C0:A2:F4:4C'] = '9/1/2',
}

ctime = os.time()

function callback(addr)
  local now, delta

  now = os.time()
  delta = now - ctime

  if addr then
    if not list[ addr ] then
      log('BLE found ' .. addr)

      if known[ addr ] then
        grp.write(known[ addr ], true, dt.bool)
      end
    end

    list[ addr ] = now
  end

  -- check for missing devices each 5 seconds
  if delta < 0 or delta > 5 then
    for addr, time in pairs(list) do
      delta = now - time

      if delta < 0 or delta > 60 then
        log('BLE missing ' .. addr)
        list[ addr ] = nil

        if known[ addr ] then
          grp.write(known[ addr ], false, dt.bool)
        end
      end
    end

    ctime = now
  end
end

ble.scan(callback)
Reply
#2
The sensor uses BLE advertising packets to send data. This means that you do not need to connect to it and just parse the advertising packet data.
Run this script and post what you get in logs tab. You might need to disable it quickly if there are many packets sent.
Code:
require('ble')

-- enable ble
ble.up()

function callback(addr, name, rssi, data)
  if addr then
    log(addr)
    loghex(data)
  end
end

ble.scan(callback)
Reply
#3
Hi,
I added that script (added also to log rssi value) and it gave this:
Test_ble_adv 22.05.2020 14:28:08
* string: F7:14:56Big Grin0:33Big Grin5


Test_ble_adv 22.05.2020 14:28:08
* number: -35


Test_ble_adv 22.05.2020 14:28:08
* nil



That is right address for Ruuvitag (log showed lots of other BLE devices too) but data is  * nil
Reply
#4
Which FW version are you running?
Reply
#5
HW: LM5 Lite + Ext (i.MX6)
SW: 20180822
Reply
#6
Ok, and what is luable package version?
Reply
#7
20151208
Reply
#8
Install these packages and try the script again:
https://dl.openrb.com/lm-18-imx6/pkg/lib...1_imx6.ipk
https://dl.openrb.com/lm-18-imx6/pkg/lua...4_imx6.ipk
Reply
#9
Thanks!
Now I got this:
Test_ble_adv 22.05.2020 15:42:18
* string: F7:14:56Big Grin0:33Big Grin5


Test_ble_adv 22.05.2020 15:42:18
* number: -35


Test_ble_adv 22.05.2020 15:42:18

* hexstring [21]: 02 01 06 11 FF 99 04 03 38 15 17 C8 38 00 0B 00 02 04 10 0B A1

Next step is parse right data from there.  I think that real data what Im looking for starts after FF 99 04. From spec manual : "The data is decoded from "Manufacturer Specific Data" -field, for more details please check this article out. Manufacturer ID is 0x0499."
If I look that spec for payload then:
03 = Data format definition
38 = Humidity ( 38 hex = 56 dec -> 56/2 = 28% )
15 = temperature. 15 hex = 21 celsius
17 = decimals of temperature -> 17 hex = 23

Those all are right values and same as in app (these ruuvitags have own android app for reading values).

Do you have little example script for parsing those parts from data?
Reply
#10
Like this. Keep in mind that it does not handle negative temperature correctly.
Code:
humidity = data:byte(9) / 2
temperature = data:byte(10) + data:byte(11) / 100
Reply
#11
Thanks a lot!
I need to check that negative temperature because one ruuvitag will be outside. Another one will be in sauna. Alexa notifies me when temperature in sauna is high enough (via Node-red) Big Grin
I did this with before with node-red but it wasnt stable enough. It needed to restart flow once a week. This LM integration might be more stable solution.
Reply
#12
Use this to handle negative temperature correctly:
Code:
temperature = data:byte(10)
decimals = data:byte(11) / 100

if bit.band(temperature, 0x80) == 0x80 then
  temperature = -bit.band(temperature, 0x7F)
  temperature = temperature - decimals
else
  temperature = temperature + decimals
end
Reply


Forum Jump: