Lightpack 2 - BLE control using exec binding

Hi all.
I’m one of the lucky ones to have received this long-awaited Kickstarter product finally after years of waiting.

I’ve been experimenting with BLE control and thought I’d write up a tutorial for anyone else who receives theirs and wants to control via OH.

Requirements:
Lightpack 2 from Woodenshark
BLE capacity from OH host or from a Raspberry pi - I’m using a Pi Zero W as I have OH on a Synology NAS
SSH access to host (and Rpi if using)

Notes:
I found the BLE on the Lightpack pretty short-range. I had to install a Rpi basically right next to it to get consistent access.

1. If using a Rpi for BLE, you need to get ssh access from your OH installation to the Pi. Best to do so with a key installation on the Pi. This tutorial is pretty good if you don’t already have this setup.

2. Create a bash file on the Pi.
I called mine lightpack.sh.

#!/bin/sh
sudo hciconfig hci0 down
sudo hciconfig hci0 up

if [ $1 = 1 ]
then
gatttool -b MAC-Lightpack --char-write-req --handle=0x001c --value=30
elif [ $1 = 2 ]
then
gatttool -b MAC-Lightpack --char-write-req --handle=0x001c --value=31
elif [ $1 = 3 ]
then
gatttool -b MAC-Lightpack --char-write-req --handle=0x001c --value=32
fi

Switch out MAC-Lightpack for the MAC address of the lightpack, obviously.

You can create elif rules for any combination of the Lightpack settings below. I’ve set a sitemap switch to send numbers to the shell script for each mood setting, for example.

3. Create your thing, items and sitemap entries.

thing:

Thing exec:command:Lightpack "Lightpack" [ command="ssh user@ip-oh bash lightpack.sh %2$s", interval=0, autorun=true ]

Switch out user@ip-oh for the username@ip-address of your RPi.

item:

String Lightpack_Command "Lightpack" { channel="exec:command:Lightpack:input", autoupdate="false" }

sitemap:

Switch item=Lightpack_Command label="Lightpack" mappings=[1="Power", 2="Media", 3="Mood"]

and/or

Switch item=Lightpack_Command_Moods label="Lightpack Moods" mappings=[11="Birch", 12="Fireplace", 13="Starry", 14="Cafe", 15="Aurora", 16="White"]

Of course, you might want to change brightness, input or mood settings. The BLE characteristics are as listed below:

Power Off:

--handle=0x001c --value=30

Media mode:

--handle=0x001c --value=31

Mood mode:

--handle=0x001c --value=32

Inputs:
Input 1:

--handle=0x0018 --value=31

Input 2:

--handle=0x0018 --value=32

Input 3:

--handle=0x0018 --value=33

Input 4:

--handle=0x0018 --value=34

Brightness:
0%

--handle=0x0010 --value=2D32

25%

--handle=0x0010 --value=2D31

50%

--handle=0x0010 --value=30

75%

--handle=0x0010 --value=31

100%

--handle=0x0010 --value=32

Mood lighting:
Birch Grove:

--handle=0x000c --value=62697263685F67726F7665

Fireplace:

--handle=0x000c --value=66697265706C616365

Starry Night:

--handle=0x000c --value=7374617272795F6E69676874

Cafe:

--handle=0x000c --value=63616665

Aurora Borealis:

--handle=0x000c --value=6175726F72615F626F7265616C6973

Still Light White:

--handle=0x000c --value=7374696C6C5F6C696768745F7768697465

More info at this gist. I hope this will be useful to someone else!

1 Like

This is great thank you for pulling this together. I also recieved my lightpack and have been disappointed with the app and remotes response time. Hopefully this will help to get things more seamless. can you advise if you need an additional blue tooth USB adapter for pi to do this?

Hi George.
You don’t need an adapter if its the Zero W as this has built in bluetooth/BLE. It just depends on which RPi you want to use.

I think the responsiveness issue with the app and remote is partly related to pairing - my app and remote are almost useless to me as well.

I don’t envisage using OH is going to make it instantaneous - it certainly hasn’t for me - but it does allow scene creation etc. If you’re setting up for a movie it doesn’t matter if it takes a second or so to turn on media mode. (IMHO)

My RPi is almost next to the Lightpack as the one I tried from another room seemed to timeout. Having it next to the Lightpack has meant I rarely get a missed command. You could experiment with sending the command twice from the bash script if you’re getting misfires.

Let me know how you go!

Thanks for the quick response, I am running Openhab on a RPI3 so I should be ok then with the BLE Connections. Can you saved the bash file on the PI? did you save it to the scripts folder? I am going to try this out tonight. Thanks

No worries.

The bash file goes on your pi. Doesn’t matter where, but you will need to get the right address in the exec command.

If it’s the same pi you have OH on you won’t need the SSH part of the command either, just the “bash lightpack.sh %2$s” part.

How much distance is there between your pi and the lightpack? This was a real issue for me…

Let me know how you go!

Hello,

I set up the Bash File added my Lightpack MAC address to the appropriate MAC-Lightpack line. Saved it as Lightpack.sh directly in my Openhab Scripts folder. I changed the Thing.file be bash and the command as you reccomended.

Thing exec:command:Lightpack "Lightpack" [ command="bash lightpack.sh %2$s", interval=0, autorun=true ]

Then I followed your steps for Items and Sitemap files but it wont execute anything on the lightpack. Any idea what i could be doing wrong?

First step is to make sure the gatttools command is working…

Just open a shell on the pi and enter the command directly, ie.

gatttool -b MAC-Lightpack --char-write-req --handle=0x001c --value=31

If that doesn’t work you have an issue with your BLE connection. Either move the pi and lightpack closer together or use another pi.

If you’re not sure if BLE is working on your pi, check with a hcitool lescan:

sudo hcitool lescan

Check that it finds your Lightpack and the MAC is correct.

If it’s not a BLE problem need to check the Exec command is working. Do you have the exec binding installed? If you do and it’s not working, check through this thread.

Let me know how you go :slight_smile:

PS- is there anything in your logs? (openhab.log)

Thank you so much i figured it out! I got it all working I had a few issues . I original got the MAC address from FING but it was incorrect. After the PI BLE scan it gave me the correct address. Then i had to update my THING File to include the path of the script. i.e.

Thing exec:command:Lightpack "Lightpack" [ command="bash /etc/openhab2/scripts/lightpack.sh %2$s", interval=0, autorun=true ]

After that it is all working in my sitemap. I would like to add Power On and Media Mode On added to the following rule. Do you know how to go about that? Thank you!

//Alexa Movie Mode ON
rule "Movie Mode On"
when
        Item movie_lights changed to ON
then
    Echo_Living_Room_StartRoutine.sendCommand('turn on movie mode')
end

Awesome!
How are you finding the latency cf the remote/app?

I haven’t set up my rules just yet.
It should be something like:

Lightpack_Command.sendCommand('1')

ie. just change the number in the command for what you want it to do…

Amazing! I got it all working properly! Now the Lightpack turns on when the Movie Lights are set! Thank you for your help. Latency is ok now that I rebooted the PI i was pressing the buttons too much and it started to lag I think. I will let you know how it goes as I continue to use it.

Did you end up adding all of you mood light modes to your script? If so I would love to add them too. Thanks for developing this!

1 Like

That’s great!

Can you post your rule so that anyone else who needs it can see it?

I have all the moods in my bash script. It’s easy to modify my script above if you want to try, or I can post my full bash script later tonight (AEDT).

Cheers!

Sure thing my working Rule is:

//ALexa Movie Mode ON
rule "Movie Mode On"
when
        Item movie_lights changed to ON
then
        Echo_Living_Room_StartRoutine.sendCommand('turn on movie mode')
        Lightpack_Command.sendCommand('2')
end


//ALexa Movie Mode OFF
rule "Movie Mode Off"
when
        Item movie_lights changed to OFF
then
    Echo_Living_Room_StartRoutine.sendCommand('turn off movie mode')
    Lightpack_Command.sendCommand('3')
end

The above rule works with the Alexa Control Binding. I made a routine in Alexa for Movie Mode which switches off all the lights, Closes the Roll shutters, Turns on some of the Colored Hue lights and the TV/Kodi. Now it also Triggers Light pack to turn on as well!

I also set up a few Switch Rules so I could use them VIA OPENHAB.

//Lightpack Power ON
rule "Lightpack rules"
when
        Item Lightpack_Power changed to ON
then
        Lightpack_Command.sendCommand('1')
end

//Lightpack Power OFF
rule "Lightpack OFF"
when
        Item Lightpack_Power changed to OFF
then
        Lightpack_Command.sendCommand('1')
end

//Lightpack Media ON
rule "Lightpack Media ON"
when
        Item Lightpack_Media changed to ON
then
        Lightpack_Command.sendCommand('2')
end

//Lightpack Media OFF
rule "Lightpack Media OFF"
when
        Item Lightpack_Media changed to OFF
then
        Lightpack_Command.sendCommand('2')
end

//Lightpack Moods ON
rule "Lightpack Moods ON"
when
        Item Lightpack_Moods changed to ON
then
        Lightpack_Command.sendCommand('3')
end

//Lightpack Moods OFF
rule "Lightpack Moods OFF"
when
        Item Lightpack_Moods changed to OFF
then
        Lightpack_Command.sendCommand('3')
end

If you could post your full Bash Script which includes all of the moods that would be great so I can get a better understanding on how to add them. Thank you for your help on this!

1 Like

I’ll do so tonight :slight_smile:

#!/bin/sh
sudo hciconfig hci0 down
sudo hciconfig hci0 up

if [ $1 = 1 ]
then
gatttool -b MAC --char-write-req --handle=0x001c --value=30
elif [ $1 = 2 ]
then
gatttool -b MAC --char-write-req --handle=0x001c --value=31
elif [ $1 = 3 ]
then
gatttool -b MAC --char-write-req --handle=0x001c --value=32
elif [ $1 = 11 ]
then
gatttool -b MAC --char-write-req --handle=0x000c --value=62697263685F67726F7665
elif [ $1 = 12 ]
then
gatttool -b MAC --char-write-req --handle=0x000c --value=66697265706C616365
elif [ $1 = 13 ]
then
gatttool -b MAC --char-write-req --handle=0x000c --value=7374617272795F6E69676874
elif [ $1 = 14 ]
then
gatttool -b MAC --char-write-req --handle=0x000c --value=63616665
elif [ $1 = 15 ]
then
gatttool -b MAC --char-write-req --handle=0x000c --value=6175726F72615F626F7265616C6973
elif [ $1 = 16 ]
then
gatttool -b MAC --char-write-req --handle=0x000c --value=7374696C6C5F6C696768745F7768697465
fi

sitemap for moods:

Switch item=Lightpack_Command_Moods label="Lightpack Moods" mappings=[11="Birch", 12="Fireplace", 13="Starry", 14="Cafe", 15="Aurora", 16="White"]

item:

String Lightpack_Command_Moods "Lightpack Moods" { channel="exec:command:Lightpack:input", autoupdate="false" }

Note that it’s sending a command to the same exec thing.

Great thank you! I got everything working!

Awesome.

If you want to add input or brightness switching just expand the bash script and create a new openhab item and sitemap switch. Just make sure you use different numbers for each command option. Like I used the 1-3 for modes and 11-16 for moods.

Cheers!

I ended up setting up all of my Lightpack items to be used within Habpanel. I use the Matrix theme so if anyone else is interested I am posting them here.

Items:

/Lightpack Items
String Lightpack_Command                   "Lightpack" { channel="exec:command:Lightpack:input", autoupdate="false" }
String Lightpack_Command_Moods             "Lightpack Moods" { channel="exec:command:Lightpack:input", autoupdate="false" }
Switch Lightpack_Power_Switch              "Lightpack Power"            <switch>    (gLightpack) 
Switch Lightpack_Media_Switch              "Lightpack Media Switch"     <switch>    (gLightpack) 
Switch Lightpack_Mood_Switch               "Lightpack Mood Switch"      <switch>    (gLightpack) 
Switch Lightpack_Birchgrove_Switch         "Birch Grove"                <switch>    (gLightpack) 
Switch Lightpack_Fireplace_Switch          "Fireplace"                  <switch>    (gLightpack) 
Switch Lightpack_StarryNight_Switch        "Starry Night"               <switch>    (gLightpack) 
Switch Lightpack_AuroraBorealis_Switch     "Aurora Borealis"            <switch>    (gLightpack) 
Switch Lightpack_Input1_Switch             "Input 1"                    <switch>    (gLightpack) 
Switch Lightpack_Input2_Switch             "Input 2"                    <switch>    (gLightpack) 
Switch Lightpack_Input3_Switch             "Input 3"                    <switch>    (gLightpack) 
Switch Lightpack_Input4_Switch             "Input 4"                    <switch>    (gLightpack) 
Switch Lightpack_0_Brightness_Switch       "0% Brightness"              <switch>    (gLightpack) 
Switch Lightpack_25_Brightness_Switch      "25% Brightness"             <switch>    (gLightpack) 
Switch Lightpack_50_Brightness_Switch      "50% Brightness"             <switch>    (gLightpack) 
Switch Lightpack_75_Brightness_Switch      "75% Brightness"             <switch>    (gLightpack) 
Switch Lightpack_100_Brightness_Switch     "100% Brightness"            <switch>    (gLightpack) 

Rules:

//Lightpack Power ON
rule "Lightpack rules"
when
        Item Lightpack_Power_Switch changed to ON
then
        Lightpack_Command.sendCommand('1')
end

//Lightpack Power OFF
rule "Lightpack OFF"
when
        Item Lightpack_Power_Switch changed to OFF
then
        Lightpack_Command.sendCommand('1')
end

//Lightpack Media ON
rule "Lightpack Media ON"
when
        Item Lightpack_Media_Switch changed to ON
then
        Lightpack_Command.sendCommand('2')
end

//Lightpack Media OFF
rule "Lightpack Media OFF"
when
        Item Lightpack_Media_Switch changed to OFF
then
        Lightpack_Command.sendCommand('2')
end

//Lightpack Moods ON
rule "Lightpack Moods ON"
when
        Item Lightpack_Mood_Switch changed to ON
then
        Lightpack_Command.sendCommand('3')
end

//Lightpack Moods OFF
rule "Lightpack Moods OFF"
when
        Item Lightpack_Mood_Switch changed to OFF
then
        Lightpack_Command.sendCommand('3')
end

//Lightpack Birch Grove ON
rule "Lightpack Birch Grove ON"
when
        Item Lightpack_Birchgrove_Switch changed to ON
then
        Lightpack_Command.sendCommand('11')
end

//Lightpack Birch Grove OFF
rule "Lightpack Birch Grove OFF"
when
        Item Lightpack_Birchgrove_Switch changed to OFF
then
        Lightpack_Command.sendCommand('11')
end

//Lightpack Fireplace ON
rule "Lightpack Fireplace ON"
when
        Item Lightpack_Fireplace_Switch changed to ON
then
        Lightpack_Command.sendCommand('12')
end

//Lightpack Fireplace OFF
rule "Lightpack Fireplace OFF"
when
        Item Lightpack_Fireplace_Switch changed to OFF
then
        Lightpack_Command.sendCommand('12')
end

//Lightpack Starry Night ON
rule "Lightpack Starry Night ON"
when
        Item Lightpack_StarryNight_Switch changed to ON
then
        Lightpack_Command.sendCommand('13')
end

//Lightpack Starry Night OFF
rule "Lightpack Starry Night OFF"
when
        Item Lightpack_StarryNight_Switch changed to OFF
then
        Lightpack_Command.sendCommand('13')
end

//Lightpack Aurora Borealis ON
rule "Lightpack Aurora Borealis ON"
when
        Item Lightpack_AuroraBorealis_Switch changed to ON
then
        Lightpack_Command.sendCommand('15')
end

//Lightpack Aurora Borealis OFF
rule "Lightpack Aurora Borealis OFF"
when
        Item Lightpack_AuroraBorealis_Switch changed to OFF
then
        Lightpack_Command.sendCommand('15')
end

//Lightpack Input 1 ON
rule "Lightpack Input 1 ON"
when
        Item Lightpack_Input1_Switch changed to ON
then
        Lightpack_Command.sendCommand('17')
end

//Lightpack Input 1 OFF
rule "Lightpack Input 1 OFF"
when
        Item Lightpack_Input1_Switch changed to OFF
then
        Lightpack_Command.sendCommand('17')
end

//Lightpack Input 2 ON
rule "Lightpack Input 2 ON"
when
        Item Lightpack_Input2_Switch changed to ON
then
        Lightpack_Command.sendCommand('18')
end

//Lightpack Input 2 OFF
rule "Lightpack Input 2 OFF"
when
        Item Lightpack_Input2_Switch changed to OFF
then
        Lightpack_Command.sendCommand('18')
end

//Lightpack Input 3 ON
rule "Lightpack Input 3 ON"
when
        Item Lightpack_Input3_Switch changed to ON
then
        Lightpack_Command.sendCommand('19')
end

//Lightpack Input 3 OFF
rule "Lightpack Input 3 OFF"
when
        Item Lightpack_Input3_Switch changed to OFF
then
        Lightpack_Command.sendCommand('19')
end

//Lightpack Input 4 ON
rule "Lightpack Input 4 ON"
when
        Item Lightpack_Input4_Switch changed to ON
then
        Lightpack_Command.sendCommand('20')
end

//Lightpack Input 4 OFF
rule "Lightpack Input 4 OFF"
when
        Item Lightpack_Input4_Switch changed to OFF
then
        Lightpack_Command.sendCommand('20')
end

//Lightpack 0% Brightness ON
rule "Lightpack 0% Brightness ON"
when
        Item Lightpack_0_Brightness_Switch changed to ON
then
        Lightpack_Command.sendCommand('21')
end

//Lightpack 0% Brightness OFF
rule "Lightpack 0% Brightness OFF"
when
        Item Lightpack_0_Brightness_Switch changed to OFF
then
        Lightpack_Command.sendCommand('21')
end

//Lightpack 25% Brightness ON
rule "Lightpack 25% Brightness ON"
when
        Item Lightpack_25_Brightness_Switch changed to ON
then
        Lightpack_Command.sendCommand('22')
end

//Lightpack 25% Brightness OFF
rule "Lightpack 25% Brightness OFF"
when
        Item Lightpack_25_Brightness_Switch changed to OFF
then
        Lightpack_Command.sendCommand('22')
end

//Lightpack 50% Brightness ON
rule "Lightpack 50% Brightness ON"
when
        Item Lightpack_50_Brightness_Switch changed to ON
then
        Lightpack_Command.sendCommand('23')
end

//Lightpack 50% Brightness OFF
rule "Lightpack 50% Brightness OFF"
when
        Item Lightpack_50_Brightness_Switch changed to OFF
then
        Lightpack_Command.sendCommand('23')
end

//Lightpack 75% Brightness ON
rule "Lightpack 75% Brightness ON"
when
        Item Lightpack_75_Brightness_Switch changed to ON
then
        Lightpack_Command.sendCommand('24')
end

//Lightpack 75% Brightness OFF
rule "Lightpack 75% Brightness OFF"
when
        Item Lightpack_75_Brightness_Switch changed to OFF
then
        Lightpack_Command.sendCommand('24')
end

//Lightpack 100% Brightness ON
rule "Lightpack 100% Brightness ON"
when
        Item Lightpack_100_Brightness_Switch changed to ON
then
        Lightpack_Command.sendCommand('25')
end

//Lightpack 100% Brightness OFF
rule "Lightpack 100% Brightness OFF"
when
        Item Lightpack_100_Brightness_Switch changed to OFF
then
        Lightpack_Command.sendCommand('25')
end

Widget Code for the Matrix Habpanel Theme:

	<div class="section" ng-init="hueColors = [ { hsb: '0,0,100', hex: '#fff' }, { hsb: '74,78,100', hex: '#fecc2f' }, { hsb: '46,100,100', hex: '#f9a228' }, { hsb: '26,100,100', hex: '#f6621f' }, { hsb: '0,100,100', hex: '#db3838' }, { hsb: '273,100,100', hex: '#a363d9' }, { hsb: '201,100,100', hex: '#40a4d8' }, { hsb: '177,100,100', hex: '#33beb8' }, { hsb: '140,100,100', hex: '#b2c225' } ]">
	<div class="sectionIconContainer"><div class="sectionIcon"><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/matrixicons.svg#light_bulb"></use></svg></div></div>
  <div class="title"><div class="name">LightPack Control</div><div class="summary">ON: {{ ( filtered | filter: { state: 'ON' } ).length }} of {{filtered.length}}</div></div>
  <div class="controls">

  <div ng-repeat="item in itemsInGroup('gLightpack') | filter:query as filtered"> 
    <div class="widget" ng-if="item.type=='Switch' && itemValue(item.name)=='OFF'" ng-click="sendCmd(item.name, 'ON')">
      <div class="icon off" ><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/matrixicons.svg#off"></use></svg></div>
      <div class="name">{{item.label}}</div>
    </div>

    <div class="widget" ng-if="item.type=='Switch' && itemValue(item.name)=='ON'" ng-click="sendCmd(item.name, 'OFF')">
      <div class="icon on" ><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/matrixicons.svg#on"></use></svg></div>
      <div class="name">{{item.label}}</div>
    </div>

    <div class="widget" ng-if="item.type=='Switch' && itemValue(item.name)=='NULL'" ng-click="sendCmd(item.name, 'ON')">
      <div class="icon off" ><svg viewBox="0 0 48 48"><use xlink:href="/static/matrix-theme/matrixicons.svg#none"></use></svg></div>
      <div class="name">{{item.label}}</div>
    </div>
    
  </div>

  </div>



</div>

Results look like the below and everything works great directly from Habpanel! Thank you for the help on this.

Hey George,
Sorry I’ve been offline, we had a baby so I’ve been tied up.
The only downside to creating all of those single switches is that you need some way to cancel the other ones. i.e. in mood lighting, your panel shows birch grove, starry night and fireplace as selected. Setting one should un-set the other…

Try something like this:

//Lightpack Birch Grove ON
rule "Lightpack Birch Grove ON"
when
        Item Lightpack_Birchgrove_Switch changed to ON
then
        Lightpack_Command.sendCommand('11')
Lightpack_Fireplace_Switch.sendCommand(OFF)
Lightpack_StarryNight_Switch.sendCommand(OFF)
Lightpack_AuroraBorealis_Switch.sendCommand(OFF)
end

You can modify your rules to do similar for brightness, input settings etc.

Cheers!