Soma blind control via MQTT

Is it possible to run Somactrl as a daemon? I have been trying but without success. But then I’m a total newbie to daemon/service… I wrote a shell script which calls Somactrl with the right args., as I don’t know how to pass on the arguments otherwise. But the system complains about the shebang #!usr/bin/env node in Somactrl, “no such file or directory”. When i run Somactrl from the command line it works fine though.

And another question. Sometimes my RISE-unit disconnect without reason (as I can understand it). When that happens, I would like Somactrl to make a new scan, once or twice maybe, to see if the unit is still there. Is that possible? Do I have to restart Somactrl to do that? Can I control that from homeassistant as an automation or should I do that in the service somehow?

I managed to run Somactrl as a daemon/service. There was a link between node and nodejs that had to be installed first. Happy! Tell me if you want to know more about how.

Next thing to try to master is the rescanning.

Sorry for the delayed response, been on some travel for work.
As you’ve discovered it is possible to have upstart/init.d start it, I should really put a quick script in the readme or github repo for others.

I’ve lately taken to using a custom version of soma-ctrl which has an extra web API endpoint that kills the process, so it then gets restarted by upstart and re-connects to all the devices.
This is hooked up to a REST command in home-assistant so I can just hit a button in lovelace to trigger it when a device is no longer responding.
Not sure whether to add this in to a release though, in reality there is something about the re-connect/error handling logic that needs improving. Most of the time when I need to use my reset button the device claims to be connected still, which it really shouldn’t – is that usually the case for everyone?

I did it with systemd, not init.d, which is more modern as I understand it. I am new to both of them, so I didn’t really look into init.d. Went for the newer one - systemd.

For me, Somactrl gets restarted at reboot, not restart of HA. Maybe I will change that. I am now working on a script for restarting somactrl . (not using lovelace yet, I want to finish this project before I migrate) .

The connection problem for me is that somactrl is running but the device turns unavailable. When I restart somactrl, the device gets connected/available again. Later on, it turns unavailable again. When I started working with somactrl some while ago, I got a long list of messages in the putty-window saying ‘somactrl RISE114 connected +225s’ etc. Nowadays I only get this message once. Is that indicating something?

Ah yeah, systemd was what I used too, I just couldn’t recall the name.
Just put together some quick steps for that on the wiki https://github.com/andersonshatch/soma-ctrl/wiki/Starting-automatically-with-systemd

I also put together a branch that will try re-connecting every 10 seconds when disconnected, perhaps you can try it out and let me know if this improves things?
The branch is named reconnect-interval, and instructions for using it are here.
If it’s still being problematic it’ll probably be best to move this to a GitHub issue instead.

Starting automatically: great! I had to run sudo apt-get install nodejs npm to get the service to work, though, to get the misnaming or whatever the problem is for node and nodejs to get solved.

Reconnecting: I’ll try out the branch. But not sure about the last point, Run node index.js with your normal set of options. I don’t run node specifically when using soma-ctrl. I just run somactrl. So I don’t know what my normal set of opions is…
So I don’t run node index.js, I run somactrl with my normal set of options. Correct me if I am doing wrong.

image

Got this error when running somactrl and then trying to maneuver the cover from HA.

There was enough time for the rescanning to occur (some minutes before I tried to maneuver from HA), but I didn’t get any messages that somactrl was scanning again.

That error should be solved in version 1.3.0 and above I think; are you on an older version?
Regarding your usual options, I just mean anything you would normally put after somactrl, I.e. your mqtt URL.
So to try out the specific branch, you’d just run the same command and instead of somactrl ..mqtturl etc... you’d run node index.js ..mqtturl etc...

I’m running version 1.3.0.

Next time I ran somactrl -normal options I didn’t get the same error.

Thanks for clearifying node/somactrl. Now I am running node index.js -normal options, has been up running for 30 min approx. The device is still connected, I can maneuver it from HA. But I cannot see any more scans of somactrl than the initial one.

image

Now, contact with the device is lost. It shows unavailable in HA, and has been unavailable since 03 last night.

The branch of somactrl is still running, at least it looks like it in the Putty-window (which hasn’t changed at all since I posted last time). When I check with top -u pi, I cannot see it though. But I am not sure it should turn up there and I didn’t check top when I just started the program.

Edit: It shows up when I run top -u pi. I just didn’t look for node, just for somactrl… My fault.

Edit2: In the system log I found this:
Feb 9 03:04:17 hassbian kernel: [488476.267714] Bluetooth: hci0 command 0x200d tx timeout

Hmm, I think I messed up with what I pushed to that branch, I went to check and didn’t see anything different from the main branch, in fact it was a little outdated.
I think the jet lag is at fault; Sorry about that!
I’ve now pushed the changes to that branch for sure so it should repeatedly try reconnecting when disconnected (no re-scan), can you do another git pull and npm install and try it now?

I’ll try again, no worries!

It’s running now. Could control the device from HA without error. So far so good.

Should I expect to see some output on in the command terminal, like “RISE114 connected”? Or is it fine with the 3-line output I posted before (soma* scanning, soma* connected RISE114, soma* stopping scan)

Would reconnecting solve the problem with the hci0 timeout? I’ve tried to find information on this timeout problem but no luck yet. I don’t understand what it means, really.

The program ran for approximately 2h, then there was a timeout for hci0 and the device was disconnected (not sure what happened first).

syslog:

Feb 9 22:19:24 hassbian kernel: [557782.738374] Bluetooth: hci0 command 0x200d tx timeout

According to top, Node is still running.

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
29243 pi 20 0 8136 3304 2760 R 1.3 0.3 0:02.84 top
3211 pi 20 0 14988 7660 3476 S 0.0 0.8 0:05.14 sshd
3223 pi 20 0 16440 9160 3412 S 0.0 1.0 0:05.15 sshd
14481 pi 20 0 11576 4180 3416 S 0.0 0.4 0:01.93 sshd
15167 pi 20 0 95688 35492 21176 S 0.0 3.7 0:12.96 node

According to bluetoothctl, the BT-dongle (I use an RPi2 with a separate BT usb dongle) seems to be missing:

[bluetooth]# devices
No default controller available
[bluetooth]# list
[bluetooth]# paired-devices
No default controller available

My conclusions are:

  1. The source of the problem is the timeout of the dongle. I don’t think it is within somactrl. If anybody has any ideas were to start looking for the solution, plz tell me :slight_smile:
  2. To make somactrl more robust, it should handle such timeouts. I tried these things, in order:
    2.1 Restarting the bluetooth.service. Didn’t help.
    2.2 After that, stopping and restarting somactrl (branch). Didn’t help.
    2.3 After that, restarting homeassistent. Didn’t help.
    2.4 After that, restarting somactrl (branch) again. Worked! Device is back in HA.
    I think the two first steps are unneccessary. Next time the device disconnect, I will try only steps 2.3 and 2.4. I have created an automation that is triggered by the device disconnecting. Eventually, I will set the action to “restart homeassistant”, and then create another automation triggered by “start of homeassistant” to “start somactrl”. Or something similar. But it would be nicer if it was handled within somactrl…

Over

Hmm, that actually has me thinking about my systemd script, it makes sense for the status of somactrl to be linked to the bluetooth service.
I’ve altered my script so that it comes up and goes down with the bluetooth service; furthermore, if you start somactrl when bluetooth is not running, it’ll start bluetooth for you.
Presumably there’s some way to have the bluetooth service restarted when your adapter re-appears.

Hey there,

As a total noob linux user
I am having a hard time getting through the first part. Those are my steps that i did (on top of my head)
Im running a raspberry pi - raspbian stretch lite / fresh install

I did in the following order

sudo apt-get upgrate
sudo apt-get install bluetooth bluez libbluetooth-dev libudev-dev
sudo ln -s /usr/bin/nodejs /usr/bin/node

curl -sL https://deb.nodesource.com/setup_8.x | bash -
sudo apt-get install -y nodejs

npm install -g soma-ctrl

Heres the log

/usr/bin/somactrl -> /usr/lib/node_modules/soma-ctrl/index.js

[email protected] install /usr/lib/node_modules/soma-ctrl/node_modules/usb
node-pre-gyp install --fallback-to-build

node-pre-gyp WARN Using needle for node-pre-gyp https download
node-pre-gyp WARN Pre-built binaries not installable for [email protected] and [email protected] (node-v57 ABI, glibc) (falling back to source compile with node-gyp)
node-pre-gyp WARN Hit error EACCES: permission denied, mkdir '/usr/lib/node_modules/soma-ctrl/node_modules/usb/src/binding'
gyp WARN EACCES user "root" does not have permission to access the dev dir "/root/.node-gyp/8.15.1"
gyp WARN EACCES attempting to reinstall using temporary dev dir "/usr/lib/node_modules/soma-ctrl/node_modules/usb/.node-gyp"
gyp WARN install got an error, rolling back install
gyp WARN install got an error, rolling back install
gyp ERR! configure error
gyp ERR! stack Error: EACCES: permission denied, mkdir '/usr/lib/node_modules/soma-ctrl/node_modules/usb/.node-gyp'
gyp ERR! System Linux 4.14.79-v7+
gyp ERR! command "/usr/bin/node" "/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "configure" "--fallback-to-build" "--module=/usr/lib/node_modules/soma-ctrl/node_modules/usb/src/binding/usb_bindings.node" "--module_name=usb_bindings" "--module_path=/usr/lib/node_modules/soma-ctrl/node_modules/usb/src/binding" "--napi_version=3" "--node_abi_napi=napi" "--napi_build_version=0" "--node_napi_label=node-v57"
gyp ERR! cwd /usr/lib/node_modules/soma-ctrl/node_modules/usb
gyp ERR! node -v v8.15.1
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok
node-pre-gyp ERR! build error
node-pre-gyp ERR! stack Error: Failed to execute '/usr/bin/node /usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js configure --fallback-to-build --module=/usr/lib/node_modules/soma-ctrl/node_modules/usb/src/binding/usb_bindings.node --module_name=usb_bindings --module_path=/usr/lib/node_modules/soma-ctrl/node_modules/usb/src/binding --napi_version=3 --node_abi_napi=napi --napi_build_version=0 --node_napi_label=node-v57' (1)
node-pre-gyp ERR! stack     at ChildProcess.<anonymous> (/usr/lib/node_modules/soma-ctrl/node_modules/node-pre-gyp/lib/util/compile.js:83:29)
node-pre-gyp ERR! stack     at emitTwo (events.js:126:13)
node-pre-gyp ERR! stack     at ChildProcess.emit (events.js:214:7)
node-pre-gyp ERR! stack     at maybeClose (internal/child_process.js:915:16)
node-pre-gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:209:5)
node-pre-gyp ERR! System Linux 4.14.79-v7+
node-pre-gyp ERR! command "/usr/bin/node" "/usr/lib/node_modules/soma-ctrl/node_modules/.bin/node-pre-gyp" "install" "--fallback-to-build"
node-pre-gyp ERR! cwd /usr/lib/node_modules/soma-ctrl/node_modules/usb
node-pre-gyp ERR! node -v v8.15.1
node-pre-gyp ERR! node-pre-gyp -v v0.11.0
node-pre-gyp ERR! not ok
Failed to execute '/usr/bin/node /usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js configure --fallback-to-build --module=/usr/lib/node_modules/soma-ctrl/node_modules/usb/src/binding/usb_bindings.node --module_name=usb_bindings --module_path=/usr/lib/node_modules/soma-ctrl/node_modules/usb/src/binding --napi_version=3 --node_abi_napi=napi --napi_build_version=0 --node_napi_label=node-v57' (1)

> [email protected] install /usr/lib/node_modules/soma-ctrl/node_modules/bluetooth-hci-socket
> node-gyp rebuild

gyp WARN EACCES user "root" does not have permission to access the dev dir "/root/.node-gyp/8.15.1"
gyp WARN EACCES attempting to reinstall using temporary dev dir "/usr/lib/node_modules/soma-ctrl/node_modules/bluetooth-hci-socket/.node-gyp"
gyp WARN install got an error, rolling back install
gyp WARN install got an error, rolling back install
gyp ERR! configure error
gyp ERR! stack Error: EACCES: permission denied, mkdir '/usr/lib/node_modules/soma-ctrl/node_modules/bluetooth-hci-socket/.node-gyp'
gyp ERR! System Linux 4.14.79-v7+
gyp ERR! command "/usr/bin/node" "/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /usr/lib/node_modules/soma-ctrl/node_modules/bluetooth-hci-socket
gyp ERR! node -v v8.15.1
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/soma-ctrl/node_modules/xpc-connection):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"arm"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/soma-ctrl/node_modules/usb):
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] install: `node-pre-gyp install --fallback-to-build`
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: Exit status 1
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/soma-ctrl/node_modules/bluetooth-hci-socket):
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] install: `node-gyp rebuild`
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: Exit status 1
1 Like

I think you just need to run the npm install command with sudo. Installing globally requires root permissions.

Is there a way to control the blinds with home assistant if you’ve got the soma connect hub, anybody know?

Not sure as I don’t have one, but since it supports HomeKit, maybe you could pair it to HASS with the HomeKit Controller component and then if necessary back out to HomeKit through HASS/homebridge?

Trying to get this setup, I’ve got the raspberry pi setup and connecting to my smart shades. I can also hit the api endpoints to see the device information.

What I can’t get working is the mqtt connection. No matter what I try I can’t see to connect to the hass.io addon MQTT broker.

My full command is:

somactrl --url mqtt://172.16.2.205 -l 3000 -e 2 -u soma -p XXXXXX

I’ve created a soma user in HomeAssistant. But when I check in HomeAssistant for Discovered MQTT devices I get nothing.

Is there any way to debug the connection to the MQTT broker to make sure that it’s connection properly?

EDIT: Nevermind me, I completely spaced that my HassIO instance was running in a VM on a different IP than my server. Updated the IP and now it’s working great.

Thanks for this by the way, such a better solution than what Soma is providing with their Connect. Works great in both HomeKit and Google Home.

1 Like

I’m also having issues getting this running on both debian and raspbian:

Raspbian (Tried on Node 9.11.2, 8.11.1, results the same):

pi@raspberrypi:/tmp $ sudo npm install -g soma-ctrl
/usr/bin/somactrl -> /usr/lib/node_modules/soma-ctrl/index.js
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/soma-ctrl/node_modules/xpc-connection):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"arm"})

+ [email protected]
updated 1 package in 16.629s

Which results in:

pi@raspberrypi:/tmp $ somactrl
module.js:549
    throw err;
    ^

Error: Cannot find module '../build/Release/binding.node'
    at Function.Module._resolveFilename (module.js:547:15)
    at Function.Module._load (module.js:474:25)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/usr/lib/node_modules/soma-ctrl/node_modules/bluetooth-hci-socket/lib/native.js:3:15)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)

Debian 10.0 using Node 9.11.2

root@debian:/home/priort# sudo npm install -g soma-ctrl
/usr/bin/somactrl -> /usr/lib/node_modules/soma-ctrl/index.js
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/soma-ctrl/node_modules/xpc-connection):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

+ [email protected]
updated 1 package in 4.679s
root@debian:/home/priort# somactrl
/root/node-bluetooth-hci-socket/node_modules/node-pre-gyp/lib/pre-binding.js:17
        throw new Error("package.json does not exist at " + package_json_path);
        ^

Error: package.json does not exist at /root/node-bluetooth-hci-socket/lib/package.json
    at Object.exports.find (/root/node-bluetooth-hci-socket/node_modules/node-pre-gyp/lib/pre-binding.js:17:15)
    at Object.<anonymous> (/root/node-bluetooth-hci-socket/lib/native.js:5:27)
    at Module._compile (internal/modules/cjs/loader.js:654:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
    at Module.load (internal/modules/cjs/loader.js:566:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:506:12)
    at Function.Module._load (internal/modules/cjs/loader.js:498:3)
    at Module.require (internal/modules/cjs/loader.js:598:17)
    at require (internal/modules/cjs/helpers.js:11:18)
    at Object.<anonymous> (/root/node-bluetooth-hci-socket/index.js:8:20)
root@debian:/home/priort#

Ideally I’d like to have this running on my Debian box that hosts HomeAssistant. Any pointers would be more than gratefully appreciated!