vekfra
Posts: 4
Joined: Sat Mar 12, 2016 3:57 pm

Read actual vales from the BeeWi BBW200 - Smart Clim

Sat Mar 12, 2016 5:55 pm

I recently purchased some BeeWi equipment from ibood (one time offer) and wanted to handle it in OpenHab.
. 2 Smart Tracker BBD100-A10
. 2 Smart Temperature & Humidity Sensor BBW200-A1
. 1 Smart LED Color Bulb BBL227-A1

As there is no binding for BeeWi I started with the beewibulb script from Stephanie Maks viewtopic.php?f=37&t=117729 with the update from Gerrit Hannaert and got that running.
Next I wanted to get the information from the BeeWi 'BBW200 - Smart Temperature & Humidity Sensor'

This script reads the actual temperature, humidity, battery status and the device information. The historical data is not handled yet.
Future step would be to create a rule in OpenHab using the knowledge gathered.

Some output of the script:

Code: Select all

pi@raspberrypi:~ $ sudo ./beewiclim.py         
Correct usage is "[sudo] beewiclim.py <device address> <command> [hci device]"
       <device address> in the format XX:XX:XX:XX:XX:XX
       Commands:  stat          - Get status
       Commands:  val           - Get values (temperature, humidity, battery)
       Commands:  raw           - Get values (temperature, humidity, battery)
       [hci device] i.e. hci1 in case of multiple devices

Code: Select all

pi@raspberrypi:~ $ sudo ./beewiclim.py 5C:31:3E:XX:XX:XX' stat
-------------------------------------
Device name       = BeeWi SmartClim 1
Model number      = BeeWi BBW200
Serial number     = 
Firmware revision = V1.5 R140514
Hardware revision = 1.0
Software revision = 
Manufacturer       = Voxland
-------------------------------------
Temperature       = 19.5℃
Humidity          = 25%
Battery           = 97%
-------------------------------------

Code: Select all

pi@raspberrypi:~ $ sudo ./beewiclim.py 5C:31:3E:XX:XX:XX' val
-------------------------------------
Temperature       = 19.5℃
Humidity          = 25%
Battery           = 97%
-------------------------------------

Code: Select all

pi@raspberrypi:~ $ sudo ./beewiclim.py 5C:31:3E:XX:XX:XX' raw
19.5 25 97
The full Python script:

Code: Select all

#!/usr/bin/env python2.7

#   A python script to read actual vales from the BeeWi 'BBW200 - Smart Temperature & Humidity Sensor'
#   BeeWi website: http://www.bee-wi.com/en.cfm
#
#   Missing: Read the historical temperature & humidity data (0x0039)
#
#   Tested on elelentary OS elementary OS 0.3.2 Freya >> BLE hardware: Broadcom Corp. BCM2045B (BDC-2.1) USB dongle
#   Tested on Raspberry 3
#
#   Don't kill me for the source, it's the first time I did something in Python.
#
#
#   Script based on the beewibulb.py script by Stephanie Maks >> Controlling a BeeWi SmartLite
#     https://www.raspberrypi.org/forums/viewtopic.php?f=37&t=117729
#     Used the modicications of Gerrit Hannaert
#
#   Some fiddling with the bluetooth packet capture on Android, Wireshark, hcitool, hciconfig, GATTTool, apktool and testing, testing, testing.....
#  
#   Many thanks to Stephanie Maks & Gerrit Hannaert
#   
#   Stephanie Maks figured out with help from -- and thanks to -- the following sources:
#      http://stackoverflow.com/questions/24853597/ble-gatttool-cannot-connect-even-though-device-is-discoverable-with-hcitool-lesc
#      http://mike.saunby.net/2013/04/raspberry-pi-and-ti-cc2541-sensortag.html
#      https://github.com/sandeepmistry/node-yeelight-blue
#      https://www.nowsecure.com/blog/2014/02/07/bluetooth-packet-capture-on-android-4-4/
#
#   note: this needs to be called with 'sudo' or by root in order to work with some of the hci commands

import os
import sys
from subprocess import call, check_output
import time

def cycleHCI(s_hci) :
   # maybe a useless time waster but it makes sure our hci is starting fresh and clean
   # nope in fact we need to call this before each time we do hci or gatt stuff or it doesn't work
   call(['hciconfig', 's_hci', 'down'])
   time.sleep(0.1)
   call(['hciconfig', 's_hci', 'up'])
   time.sleep(0.1)

def getResultStringForDeviceMacHandle(s_hci, s_mac, s_handle) :
   # Read the string from handle
   raw_input = check_output(['gatttool', '-i', s_hci, '-b', s_mac, '--char-read', '--handle='+s_handle]);
   result_string = ''
   if ':' in raw_input:
      raw_list=raw_input.split(':')
      raw_data=raw_list[1]
      raw_data=raw_data.strip()
      octet_list=raw_data.split(' ')
      for octet in octet_list :
         j = int(octet, 16)
         if j > 31 and j < 127 : result_string += str(unichr(j))
   return result_string

def getActualValues(s_hci, s_mac) :
   # read the value characteristic (read handle is 0x003f)
   # handle returns 10 byte hex block containing temperature, humidity and batery level
   # the temperature consists of 3 bytes
   # Posivive value: byte 1 & 2 present the tenfold of the temperature
   # Negative value: byte 2 - byte 3 present the tenfold of the temperature 
   raw_input = check_output(['gatttool', '-i', s_hci, '-b', s_mac, '--char-read', '--handle=0x003f']);
   if ':' in raw_input:
      raw_list    = raw_input.split(':')
      raw_data    = raw_list[1]
      raw_data    = raw_data.strip()
      octet_list  = raw_data.split(' ')
      t0 = int(octet_list[0], 16)
      t1 = int(octet_list[1], 16)
      t2 = int(octet_list[2], 16)
      if t2 == 255:
         temperature = (t1-t2)/10.0
      else:
         temperature = ((t0*255)+t1)/10.0
      humidity    = int(octet_list[4], 16)
      battery     = int(octet_list[9], 16)
   return (temperature, humidity, battery)

def getDeviceInfo(s_hci, s_mac) :
   # BeeWi Smart Climate handles
   # 0x0003 :    SmartClim name : 'Smart Clim'
   # 0x001b :      model number : 'BeeWi BBW200\00'
   # 0x001d :     serial number : '\00'
   # 0x001f : firmware revision : 'V1.5 R140514\00'
   # 0x0021 : hardware revision : '1.0\00'
   # 0x0023 : software revision : '\00'
   # 0x0025 :      manufacturer : 'Voxland\00'

   Name             = getResultStringForDeviceMacHandle(s_hci, s_mac, '0x0003')
   ModelNumber      = getResultStringForDeviceMacHandle(s_hci, s_mac, '0x001b')
   SerialNumber     = getResultStringForDeviceMacHandle(s_hci, s_mac, '0x001d')
   FirmwareRevision = getResultStringForDeviceMacHandle(s_hci, s_mac, '0x001f')
   HardwareRevision = getResultStringForDeviceMacHandle(s_hci, s_mac, '0x0021')
   SoftwareRevision = getResultStringForDeviceMacHandle(s_hci, s_mac, '0x0023')
   Manufacturer     = getResultStringForDeviceMacHandle(s_hci, s_mac, '0x0025')
   return (Name, ModelNumber, SerialNumber, FirmwareRevision, HardwareRevision, SoftwareRevision, Manufacturer)

def printHelp() :
   print 'Correct usage is "[sudo] beewiclim.py <device address> <command> [argument]"'
   print '       <device address> in the format XX:XX:XX:XX:XX:XX'
   print '       Commands:  stat          - Get status'
   print '       Commands:  val           - Get values (temperature, humidity, battery)'
   print '       Commands:  raw           - Get values (temperature, humidity, battery)'
   print '       [hci device] i.e. hci1 in case of multiple devices'
   print ''

if __name__=='__main__' :
   if os.geteuid() != 0 :
      print 'WARNING: This script may not work correctly without sudo / root. Sorry.'
   if len(sys.argv) < 3 :
      printHelp()
   else :
      hci_device = 'hci0' # default
      device_address = sys.argv[1]
      command = sys.argv[2]
      command = command.lower()
      error = ''
      if len(sys.argv) == 4 : hci_device = sys.argv[3]
      hci_device = hci_device.lower()

      # address shortcuts
      if device_address == 'sc1' : device_address = '5C:31:3E:XX:XX:XX'
      if device_address == 'sc2' : device_address = 'D0:5F:B8:XX:XX:XX'

      if len(device_address) != 17 :
         print 'ERROR: device address must be in the format NN:NN:NN:NN:NN:NN'
         exit()
      if 'stat' in command :
         name, model, serial, frevision, hrevision, srevision, manufacturer = getDeviceInfo(hci_device, device_address)
         temperature, humidity, battery = getActualValues(hci_device, device_address)
         print '-------------------------------------'
         print 'Device name       = ' + name
         print 'Model number      = ' + model
         print 'Serial number     = ' + serial
         print 'Firmware revision = ' + frevision
         print 'Hardware revision = ' + hrevision
         print 'Software revision = ' + srevision
         print 'Manufaturer       = ' + manufacturer
         print '-------------------------------------'
         print 'Temperature       = ' + str(temperature) + u'\u2103'.encode("utf8") # encode("utf8") needed on raspberry
         print 'Humidity          = ' + str(humidity) + '%'
         print 'Battery           = ' + str(battery) + '%'
         print '-------------------------------------'
      if 'val' in command :
         temperature, humidity, battery = getActualValues(hci_device, device_address)
         print '-------------------------------------'
         print 'Temperature       = ' + str(temperature) + u'\u2103'
         print 'Humidity          = ' + str(humidity) + '%'
         print 'Battery           = ' + str(battery) + '%'
         print '-------------------------------------'
      if 'raw' in command :
         temperature, humidity, battery = getActualValues(hci_device, device_address)
         print str(temperature),str(humidity),str(battery)
      if error != '' :
         if error == 'off' : error = 'ERROR: SmartClim ' + device_address
         print error
   exit()
2016-03-16
Update for negative temperatures and positive values over 25.5 degrees Celcius
Busy on pulling the historical data (temperature & humidity), having some troebles translating the data into values.

And sorry for the language mistakes, English is not my native language
Cheers!

Dragafe
Posts: 2
Joined: Sun Mar 20, 2016 7:33 pm

Re: Read actual vales from the BeeWi BBW200 - Smart Clim

Sun Mar 20, 2016 7:55 pm

Hi Vekfra, I see your post abd I want to ask you a question about Beewi's script. I have a bulb like Stephanie Marks and I want to use her script but it doesn't work. I can use "status" but it's the only code which I can use... You study her script and I want to know why It can't work ... Thanks.

PS : English isn't my native language.

deese
Posts: 1
Joined: Sun May 08, 2016 11:25 pm

Re: Read actual vales from the BeeWi BBW200 - Smart Clim

Sun May 08, 2016 11:31 pm

Hi,

The script is quite good, but the temperature readings are not represented correctly.

I haven't checked with negative temperatures but with this patch I'm seeing the correct temperature.
Thanks for sharing the code!

Code: Select all

--- beewiclim-orig.py   2016-05-08 23:26:48.120024401 +0000
+++ beewiclim.py    2016-05-08 23:28:20.679648390 +0000
@@ -70,9 +70,10 @@
       t1 = int(octet_list[1], 16)
       t2 = int(octet_list[2], 16)
       if t2 == 255:
-         temperature = (t1-t2)/10.0
+         temperature = (t1+(t2<<8))/10.0
       else:
-         temperature = ((t0*255)+t1)/10.0
+         #temperature = ((t0*255)+t1)/10.0
+    temperature = (t1 + (t2<<8))/10.0
       humidity    = int(octet_list[4], 16)
       battery     = int(octet_list[9], 16)
    return (temperature, humidity, battery)
@@ -145,7 +146,7 @@
       if 'val' in command :
          temperature, humidity, battery = getActualValues(hci_device, device_address)
          print '-------------------------------------'
-         print 'Temperature       = ' + str(temperature) + u'\u2103'
+         print 'Temperature       = ' + str(temperature) #+ u'\u2103'.encode("utf8")
          print 'Humidity          = ' + str(humidity) + '%'
          print 'Battery           = ' + str(battery) + '%'
          print '-------------------------------------'

faabbiii
Posts: 1
Joined: Tue Jun 21, 2016 6:41 pm

Re: Read actual vales from the BeeWi BBW200 - Smart Clim

Tue Jun 21, 2016 6:53 pm

Hi,

i need some help :?

I got the BeeWi BBW200-A10 and can connect it to my smartphone.

If i run hcitool scan i cant finde the BeeWi, but other Devices like my Smartphone.

I also try l2ping with the MAC of the BeeWi i got from the BeeWi App, but it only returns:

Can't connect: Host is down

I hope someone can help me :)

thx & greetz
Fabi

PS : Sorry, english isnt my native language.

vekfra
Posts: 4
Joined: Sat Mar 12, 2016 3:57 pm

Re: Read actual vales from the BeeWi BBW200 - Smart Clim

Thu Jun 23, 2016 6:38 pm

faabbiii wrote:Hi,

i need some help :?

I got the BeeWi BBW200-A10 and can connect it to my smartphone.

If i run hcitool scan i cant finde the BeeWi, but other Devices like my Smartphone.

I also try l2ping with the MAC of the BeeWi i got from the BeeWi App, but it only returns:

Can't connect: Host is down

I hope someone can help me :)

thx & greetz
Fabi

PS : Sorry, english isnt my native language.
Hi faabbii,

You cant find the BeeWi BBW200 using the "hcitool scan" command, the scan command is for Bluetooth only i.e. phone, tv, etc.
To scan for a Bluetooth 4.0 device (Bluetooth Low Energy or BLE) you have to use the command "hcitool lescan" and that is a neverending scan, you have to stop it using Ctrl+C.

Example output lescan:

Code: Select all

sudo hcitool lescan
LE Scan ...
5C:31:3E:4D:C6:3F (unknown)
5C:31:3E:4D:C6:3F BeeWi SmartClim 1
D0:5F:B8:51:A0:5E (unknown)
D0:5F:B8:51:A0:5E BeeWi SmartClim 2
5C:31:3E:4D:C6:3F (unknown)
5C:31:3E:4D:C6:3F BeeWi SmartClim 1
D0:5F:B8:51:A0:5E (unknown)
D0:5F:B8:51:A0:5E BeeWi SmartClim 2
5C:31:3E:4D:C6:3F (unknown)
D0:5F:B8:51:A0:5E (unknown)
D0:5F:B8:51:A0:5E BeeWi SmartClim 2
5C:31:3E:4D:C6:3F (unknown)
5C:31:3E:4D:C6:3F BeeWi SmartClim 1
D0:5F:B8:51:A0:5E (unknown)
D0:5F:B8:51:A0:5E BeeWi SmartClim 2
5C:31:3E:4D:C6:3F (unknown)
5C:31:3E:4D:C6:3F BeeWi SmartClim 1
^C
A BeeWi SmartClim will send 2 resonses when a lescan is active, one response containing the data and a response containing the device name.

For the security minding people: Yes you can see the device id's of my devices, but there is no security in the device, I did not find it, anyone that does a lescan within 30 meters or less from the devices can see this data anyway.

Good luck with your testing.

vekfra
Posts: 4
Joined: Sat Mar 12, 2016 3:57 pm

Version 2: Read actual vales from the BeeWi BBW200 - Smart C

Thu Jun 23, 2016 6:54 pm

The first example scanning the information from the BBW200 was setup by connecting to the device and reading the data, I found that this technique uses a lot of battery power, battery dead in 3 weeks, not 3 months.

Something new:
For my home setup of OpenHab I use the lescan without hcitool by BLE scanning in node.js using the noble addon. No connection to the devices needed.

The node.js code runs once and returns a json dataset. The script is called every minute in a openhab rule and the json data is used to update the openhab items.

The node.js code: scanBeeWi.js

Code: Select all

var noble = require('noble');

var SC1 = false;
var SC1T = '';
var SC1H = '';
var SC1B = '';
var SC2 = false;
var SC2T = '';
var SC2H = '';
var SC2B = '';
var TP1 = false;
var TP1S = "OFF"
var Count = 0;

function hexToInt(hex) {
    if (hex.length % 2 != 0) {
        hex = "0" + hex;
    }
    var num = parseInt(hex, 16);
    var maxVal = Math.pow(2, hex.length / 2 * 8);
    if (num > maxVal / 2 - 1) {
        num = num - maxVal
    }
    return num;
}


noble.on('stateChange', function(state) {
  if (state === 'poweredOn') {
    noble.stopScanning();
    noble.startScanning();
  } else {
    noble.stopScanning();
  }
});


noble.on('scanStop', function() {
    console.log('{"SC1Temp":"'+SC1T+'","SC1Humi":"'+SC1H+'","SC1Batt": "'+SC1B+'","SC2Temp":"'+SC2T+'","SC2Humi":"'+SC2H+'","SC2Batt": "'+SC2B+'","TPFrans":"'+TP1S+'"}');
    process.exit(0);
});


// Scan for the 3 devices (maximum 20 replies)
noble.on('discover', function(peripheral) {

    if ((peripheral.id == '5c313e4dc63f' || peripheral.id == 'd05fb851a05e')) {
        var data = peripheral.advertisement.manufacturerData.toString('hex');
        var Temp = parseFloat(hexToInt(data.substr(10, 2)+data.substr(8, 2))/10).toFixed(1);
        var Hum = Math.min(100,parseInt(data.substr(14, 2),16));
        var Bat = parseInt(data.substr(24, 2),16);

        if (!SC1 && peripheral.id == '5c313e4dc63f') {
            SC1 = true;
            SC1T = Temp;
            SC1H = Hum;
            SC1B = Bat;
        }

        if (!SC2 && peripheral.id == 'd05fb851a05e') {
            SC2 = true;
            SC2T = Temp;
            SC2H = Hum;
            SC2B = Bat;
        }
    }

    // TrackerPad
    if (peripheral.id == '5c313e4dc63f') {
        TP1 = true;
        TP1S = 'ON';
    }
    if ((Count > 20 || TP1) && (SC1 && SC2)) {
        noble.stopScanning();
    }

    Count = Count + 1;
});
OpenHab rule using scanBeeWi.js

Code: Select all

rule "Get BeeWi SmartClim data"
when
	System started or
	Time cron "0 * * * * ?"
then
	var String data

// Get BeeWi data (each item in json string)
	data = executeCommandLine("sudo /usr/local/bin/node /home/pi/scanBeeWi.js", 20000)
//	postUpdate(SC1data, data)
	postUpdate(SC1Temp,transform("JSONPATH","$.SC1Temp",data))
	postUpdate(SC1Humi,transform("JSONPATH","$.SC1Humi",data)
	postUpdate(SC1Batt,transform("JSONPATH","$.SC1Batt",data)
	postUpdate(SC2Temp,transform("JSONPATH","$.SC2Temp",data))
	postUpdate(SC2Humi,transform("JSONPATH","$.SC2Humi",data)
	postUpdate(SC2Batt,transform("JSONPATH","$.SC2Batt",data)
	postUpdate(TPFrans,transform("JSONPATH","$.TPFrans",data)
end
Yes you can see the device id's of my devices, but there is no security in the device, I did not find it, anyone that does a lescan within 30 meters or less from the devices can see this data anyway.

Happy testing :-)

enrimilan
Posts: 1
Joined: Mon Apr 24, 2017 2:47 pm
Location: Vienna, Austria

Re: Read actual vales from the BeeWi BBW200 - Smart Clim

Mon Apr 24, 2017 2:55 pm

Hey there!

First, I would like to thank you for sharing your code here, awesome!

I created a new repository for collecting different code examples in order to interact with the device:
https://github.com/enrimilan/BeeWi-BBW200-Reader

I hope this could be helpful too ^^

Regards

Return to “Automation, sensing and robotics”

Who is online

Users browsing this forum: No registered users and 18 guests