Logic Machine Forum
BLE profiles - Printable Version

+- Logic Machine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Gateway (https://forum.logicmachine.net/forumdisplay.php?fid=10)
+--- Thread: BLE profiles (/showthread.php?tid=1199)



BLE profiles - morak - 29.01.2018

Hi

I thought that I will share with you all the BLE profiles I collected up to know. If you have some other feel free to add them here. 
Have fun Smile


RE: BLE profiles - 1114752670@qq.com - 13.03.2019

why these are not LUA


RE: BLE profiles - Daniel - 13.03.2019

(13.03.2019, 07:53)1114752670@qq.com Wrote: why these are not LUA

yes, they are


RE: BLE profiles - gjniewenhuijse - 13.03.2019

Is there also a profile for: MIPOW Playbulb
https://www.mipow.com/collections/playbulb/products/playbulb-solar

Or how to make a profile?


RE: BLE profiles - admin - 13.03.2019

Creating profiles can range from very easy to virtually impossible Smile

BLE does not specify data exchange formats so each manufacturer can do whatever they like including custom authentication/encryption. There are mobile apps that can connect to BLE devices and show available services. Best case scenario that you can find color/brightness control service number and there's no special pairing procedure required. Have a look at awox-aromalightcolor.lua which is an RGB LED lamp with BLE.


RE: BLE profiles - benanderson_475 - 13.01.2020

Im working on a BLE profile for the xiaome Mi Flora Flower care sensor, this is as far as i have got, i can read the data but not sure how to extract the data i want from the bytes, 
there is available,  light level, soil moisture level and temperature, the location of the data is as per the link below. 
https://www.open-homeautomation.com/2016/08/23/reverse-engineering-the-mi-plant-sensor/


require('ble')
ble.up()
sock = ble.sock()
ble.settimeout(sock, 30)
res = ble.connect(sock, "80:EA:CA:88:E5:63")
log(res)

if res then

  cmd = 0xA0, 0x1F
  --0x03 -- name
  re, er =  ble.sockwritecmd(sock, 0x33, cmd) -- send the magic to allow us to read the data
  log(re, er)
 
  os.sleep(0.1)
 
  x = ble.sockreadhnd(sock,0x35) or '' 
a = x:byte(1)
b = x:byte(2)
c = x:byte(3)
d = x:byte(4)
e = x:byte(5)
f = x:byte(6)
g = x:byte(7)
h = x:byte(8)
 
log(x,a,b,c,d,e,f,g,h)
  
end


RE: BLE profiles - admin - 14.01.2020

Try this:
Code:
fertility = x:byte(9) * 0x100 + x:byte(10)
sunlight = x:byte(4) * 0x100 + x:byte(5)
temperature = (x:byte(1) * 0x100 + x:byte(2)) / 10

log(fertility, sunlight, temperature)



RE: BLE profiles - benanderson_475 - 21.04.2020

(14.01.2020, 07:44)admin Wrote: Try this:
Code:
fertility = x:byte(9) * 0x100 + x:byte(10)
sunlight = x:byte(4) * 0x100 + x:byte(5)
temperature = (x:byte(1) * 0x100 + x:byte(2)) / 10

log(fertility, sunlight, temperature)
I am having trouble receiving the correct data from lua code, when i use gatttool all works as below although i need to be fast to send the --char-read request before i get disconnected otherwise response is AA BB CC DD EE FF 99 88 77 66 00 00 00 00 00 00

gatttool --device=80:EA:CA:89:1D:78 --char-write-req -a 0x33 -n A01F
gatttool --device=80:EA:CA:89:1D:78 --char-read -a 0x35 

response is 03 01 00 4a 03 00 00 00 00 00 02 3c 00 fb 34 9b this is example of expected response 

from my lua script, result in rx is always AA BB CC DD EE FF 99 88 77 66 00 00 00 00 00 00
i think im not sending the ble.sockreadhnd(sock, 0x35) command fast enough? or sending it before the ble.sockwritereq(sock, 0x33, cmd) has returned or maybe there is something else wrong?

The result from log(x, err) is   *arg 1 number: 4 * arg: 2* number: 114 is there any documentation for these codes? or for the ble.sockwritereq() commands?
Many Thanks
Code:
require('ble')
sock = ble.sock()
ble.settimeout(sock, 10)
res = ble.connect(sock, "80:EA:CA:89:1D:78")
if res then
  cmd = 0xA0, 0x1F
 
  x, err =  ble.sockwritereq(sock, 0x33, cmd)
log(x, err)

if x then
rx = ble.sockreadhnd(sock, 0x35)
rx = string.gsub(rx, ".", function(value) return  string.format('%02X', string.byte(value))end)
log(rx)
end



RE: BLE profiles - admin - 21.04.2020

This line is incorrect (only 0xA0 is assigned to cmd):
Code:
cmd = 0xA0, 0x1F

It should be:
Code:
cmd1, cmd2 = 0xA0, 0x1F
x, err =  ble.sockwritereq(sock, 0x33, cmd1, cmd2)

You might need to swap cmd1 and cmd2 if it still does not work. You can also use loghex() instead of log() to convert binary data to hex.


RE: BLE profiles - benanderson_475 - 22.04.2020

(21.04.2020, 06:23)admin Wrote: This line is incorrect (only 0xA0 is assigned to cmd):
Code:
cmd = 0xA0, 0x1F

Thanks, i have it working correctly now (in resident script with 0 delay) and returning the correct values as below, 
but if i put a longer delay than 0 on the resident script the correct values are not returned,

what could be the reason for this?
how should this code run, in a ble profile? or it is ok in resident script?
also i want to only ask this device what its values are every 15 min or so, as it is a battery operated device... 
should i do a scheduled script every x minutes?

Code:
require('ble')
sock = ble.sock()
ble.settimeout(sock, 10)
res = ble.connect(sock, "80:EA:CA:89:1D:78")
if res then
  cmd1, cmd2 = 0xA0, 0x1F
  x, err =  ble.sockwritereq(sock, 0x33, cmd1, cmd2)
log(x, err)

rx = ble.sockreadhnd(sock, 0x35)
loghex(rx)
temperature = (rx:byte(2) + rx:byte(1)) / 10
log(temperature)
end



RE: BLE profiles - admin - 22.04.2020

You can use a scheduled script or create a profile. See raiing-temperature.lua for a similar device.

I'm not sure that this conversion is correct:
Code:
temperature = (rx:byte(2) + rx:byte(1)) / 10

The temperature value is probably two bytes, so you need to shift one byte with multiply by 256. Try both ways as byte order is not known.
Code:
temperature = (rx:byte(2) * 256 + rx:byte(1)) / 10
temperature = (rx:byte(2) + rx:byte(1) * 256) / 10

All write functions like ble.sockwritereq return two values:
1. number of bytes written, -1 = error
2. last error number (errno), applicable only when first value is -1, see this for errno number description: https://www.thegeekstuff.com/2010/10/linux-error-codes/


RE: BLE profiles - benanderson_475 - 12.03.2022

(22.04.2020, 10:53)admin Wrote: You can use a scheduled script or create a profile. See raiing-temperature.lua for a similar device.
Hi admin,

working on this some more after long testing time...

I am wondering if you can help me with the BLE code below (running in scheduled script every 10min), some times i get fail to read the data from the sensor, are you able to tell me if there is some obvious error in my lua code or is it more likely hardware related i have 2x flora plant sensor BLE, but if i am successful with no errors i might add 5 or 6 more of these sensors.


Many Thanks,
Code:
local devices = {"80:EA:CA:88:xx:xx", "80:EA:CA:89:xx:xx"}

require('ble')
for i = 1, #devices do

sock = ble.sock()
ble.settimeout(sock, 10)
  res = ble.connect(sock, devices[i])   --"80:EA:CA:88:xx:xx"  "80:EA:CA:89:xx:xx"
--log(res)
 
  if res == nil then -- device not found
    log(devices[i]..' Read Failed')
    log(devices[i] ..' Retry connecting')
   
    os.sleep(3)
   
   res = ble.connect(sock, devices[i])
   
    if res == nil then
     log(devices[i]..' Not Found')
    end
   
  end
 
if res then
  cmd1, cmd2 = 0xA0, 0x1F
  x, err =  ble.sockwritereq(sock, 0x33, cmd1, cmd2)
--log(x, err)

  os.sleep(1)

rx = ble.sockreadhnd(sock, 0x35) --it usually misses the first one
rx1 = ble.sockreadhnd(sock, 0x35)
   
batt = ble.sockreadhnd(sock, 0x38) --it usually misses the first one
batt1 = ble.sockreadhnd(sock, 0x38)     

if rx1 then
  temperature = (rx1:byte(2) * 0x100 + rx1:byte(1)) / 10
  fertility = rx1:byte(10) * 0x100 + rx1:byte(9) -- conductivity in µS/cm
  moisture = rx1:byte(8) -- moisture in %
  sunlight = rx1:byte(5) * 0x100 + rx1:byte(4) -- Lux
end
   
if batt1 then
battery =  batt1:byte(1)
end
 
log('mac ='.. devices[i]..' '.. 'temp '.. temperature, fertility, sunlight, battery, moisture)

os.sleep(2)
   
end
end