Snapcast Binding

Unfortunally the binding is not working for me. I added the Snapserver as a thing and I also see that it is working somehow, but I do not see any Snapclients in the Inbox, also I see the Snapserver thing as OFFLINE - HANDLER_REGISTERING_ERROR.

2018-01-24 16:01:47.752 [INFO ] [.JsonRpcEventClient$ConnectionThread] - Connecting to control server 192.168.0.3:1705...
2018-01-24 16:01:47.754 [INFO ] [.JsonRpcEventClient$ConnectionThread] - Connected to control server 192.168.0.3:1705

Is the binding working at all or are there just some problems? At least I did not find this problem in the thread, so I am posting it anyway. :wink:

Good morning,

I’m interested in a snapcast binding and also in development for openhab in general. So I decide to try writing an binding.

The result can be found here: https://github.com/StbX/openhab2-addons/releases/tag/snapcast-20181031
More infos are available in the README

I’ve mostly ignored the snapcast groups. If I want to change the stream of an client, which is in a group with other clients, the other clients are removed from the group. So I have only a server and a client thing.

Special thanks to @ssoerensen for the inspiration :slight_smile:

@StbX That is awesome, however i tried it out and got the following warning in the logs:

2019-02-09 14:12:04.780 [WARN ] [re.thing.internal.ThingFactoryHelper] - Could not create channel 'volume' for thing type 'snapcast:client:Snapcast:1e1fdb08-6f00-4663-a78c-2498f26693ff', because channel type 'system:volume' could not be fo
und.
2019-02-09 14:12:04.789 [WARN ] [re.thing.internal.ThingFactoryHelper] - Could not create channel 'mute' for thing type 'snapcast:client:Snapcast:1e1fdb08-6f00-4663-a78c-2498f26693ff', because channel type 'system:mute' could not be found. 

Is it a old version of Openhab or is there something that i’m missing?

Are you already using OpenHAB 2.4?
afaik the system channel types for volume and mute are new in this Version.

yeah, but clearing cache and manually configuring the things solved the problem. it all works as described :slight_smile:

Hi all,

i’ve updated the binding for the new release 2.5.0.

The result is available at: https://openhab.jfrog.io/openhab/libs-pullrequest-local/org/openhab/binding/org.openhab.binding.snapcast/2.5.0-SNAPSHOT/

And there is also a pull-request: https://github.com/openhab/openhab2-addons/pull/4189

Hi! Sorry to resurrect a dead thread. Is this binding still being maintained? I have multiple instances of Snapclient running on machine and it seems to break this binding. I am able to find the SnapServer and Clients, but they are always Offline - Communication_Error.

Looking at the console, I see this error:

16:54:37.711 [ERROR] [internal.DiscoveryServiceRegistryImpl] - Cannot trigger scan for thing types '[snapcast:client]' on 'ClientDiscoveryService'!

java.lang.IllegalArgumentException: ID segment 'b827eb86c43c#2' contains invalid characters. Each segment of the ID must match the pattern [A-Za-z0-9_-]*.

at org.eclipse.smarthome.core.common.AbstractUID.validateSegment(AbstractUID.java:97) ~[133:org.openhab.core:2.5.0.M4]

at org.eclipse.smarthome.core.common.AbstractUID.<init>(AbstractUID.java:75) ~[133:org.openhab.core:2.5.0.M4]

at org.eclipse.smarthome.core.common.AbstractUID.<init>(AbstractUID.java:58) ~[133:org.openhab.core:2.5.0.M4]

at org.eclipse.smarthome.core.thing.UID.<init>(UID.java:57) ~[185:org.openhab.core.thing:2.5.0.M4]

at org.eclipse.smarthome.core.thing.ThingUID.<init>(ThingUID.java:54) ~[185:org.openhab.core.thing:2.5.0.M4]

at org.openhab.binding.snapcast.internal.discovery.ClientDiscoveryService.getThingUID(ClientDiscoveryService.java:79) ~[?:?]

at org.openhab.binding.snapcast.internal.discovery.ClientDiscoveryService.discover(ClientDiscoveryService.java:66) ~[?:?]

at org.openhab.binding.snapcast.internal.discovery.ClientDiscoveryService.startScan(ClientDiscoveryService.java:51) ~[?:?]

at org.eclipse.smarthome.config.discovery.AbstractDiscoveryService.startScan(AbstractDiscoveryService.java:209) ~[139:org.openhab.core.config.discovery:2.5.0.M4]

at org.eclipse.smarthome.config.discovery.internal.DiscoveryServiceRegistryImpl.startScan(DiscoveryServiceRegistryImpl.java:382) [139:org.openhab.core.config.discovery:2.5.0.M4]

at org.eclipse.smarthome.config.discovery.internal.DiscoveryServiceRegistryImpl.startScans(DiscoveryServiceRegistryImpl.java:358) [139:org.openhab.core.config.discovery:2.5.0.M4]

at org.eclipse.smarthome.config.discovery.internal.DiscoveryServiceRegistryImpl.startScan(DiscoveryServiceRegistryImpl.java:216) [139:org.openhab.core.config.discovery:2.5.0.M4]

at org.eclipse.smarthome.io.rest.core.internal.discovery.DiscoveryResource.scan(DiscoveryResource.java:97) [153:org.openhab.core.io.rest.core:2.5.0.M4]

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]

at java.lang.reflect.Method.invoke(Method.java:498) ~[?:?]

at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81) [125:org.glassfish.jersey.core.jersey-server:2.22.2]

at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144) [125:org.glassfish.jersey.core.jersey-server:2.22.2]

at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161) [125:org.glassfish.jersey.core.jersey-server:2.22.2]

at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160) [125:org.glassfish.jersey.core.jersey-server:2.22.2]

at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99) [125:org.glassfish.jersey.core.jersey-server:2.22.2]

at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389) [125:org.glassfish.jersey.core.jersey-server:2.22.2]

at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347) [125:org.glassfish.jersey.core.jersey-server:2.22.2]

at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102) [125:org.glassfish.jersey.core.jersey-server:2.22.2]

at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326) [125:org.glassfish.jersey.core.jersey-server:2.22.2]

at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) [124:org.glassfish.jersey.core.jersey-common:2.22.2]

at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) [124:org.glassfish.jersey.core.jersey-common:2.22.2]

at org.glassfish.jersey.internal.Errors.process(Errors.java:315) [124:org.glassfish.jersey.core.jersey-common:2.22.2]

at org.glassfish.jersey.internal.Errors.process(Errors.java:297) [124:org.glassfish.jersey.core.jersey-common:2.22.2]

at org.glassfish.jersey.internal.Errors.process(Errors.java:267) [124:org.glassfish.jersey.core.jersey-common:2.22.2]

at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) [124:org.glassfish.jersey.core.jersey-common:2.22.2]

at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305) [125:org.glassfish.jersey.core.jersey-server:2.22.2]

at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154) [125:org.glassfish.jersey.core.jersey-server:2.22.2]

at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473) [122:org.glassfish.jersey.containers.jersey-container-servlet-core:2.22.2]

at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427) [122:org.glassfish.jersey.containers.jersey-container-servlet-core:2.22.2]

at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388) [122:org.glassfish.jersey.containers.jersey-container-servlet-core:2.22.2]

at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341) [122:org.glassfish.jersey.containers.jersey-container-servlet-core:2.22.2]

at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228) [122:org.glassfish.jersey.containers.jersey-container-servlet-core:2.22.2]

at com.eclipsesource.jaxrs.publisher.internal.ServletContainerBridge.service(ServletContainerBridge.java:76) [20:com.eclipsesource.jaxrs.publisher:5.3.1.201602281253]

at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:873) [90:org.eclipse.jetty.servlet:9.4.18.v20190429]

at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:542) [90:org.eclipse.jetty.servlet:9.4.18.v20190429]

at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:71) [194:org.ops4j.pax.web.pax-web-jetty:7.2.10]

at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:146) [89:org.eclipse.jetty.server:9.4.18.v20190429]

at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) [87:org.eclipse.jetty.security:9.4.18.v20190429]

at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) [89:org.eclipse.jetty.server:9.4.18.v20190429]

at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257) [89:org.eclipse.jetty.server:9.4.18.v20190429]

at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1700) [89:org.eclipse.jetty.server:9.4.18.v20190429]

at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255) [89:org.eclipse.jetty.server:9.4.18.v20190429]

at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1345) [89:org.eclipse.jetty.server:9.4.18.v20190429]

at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:293) [194:org.ops4j.pax.web.pax-web-jetty:7.2.10]

at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203) [89:org.eclipse.jetty.server:9.4.18.v20190429]

at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:480) [90:org.eclipse.jetty.servlet:9.4.18.v20190429]

at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1667) [89:org.eclipse.jetty.server:9.4.18.v20190429]

at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201) [89:org.eclipse.jetty.server:9.4.18.v20190429]

at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1247) [89:org.eclipse.jetty.server:9.4.18.v20190429]

at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144) [89:org.eclipse.jetty.server:9.4.18.v20190429]

at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:80) [194:org.ops4j.pax.web.pax-web-jetty:7.2.10]

at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) [89:org.eclipse.jetty.server:9.4.18.v20190429]

at org.eclipse.jetty.server.Server.handle(Server.java:505) [89:org.eclipse.jetty.server:9.4.18.v20190429]

at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:370) [89:org.eclipse.jetty.server:9.4.18.v20190429]

at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:267) [89:org.eclipse.jetty.server:9.4.18.v20190429]

at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305) [80:org.eclipse.jetty.io:9.4.18.v20190429]

at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103) [80:org.eclipse.jetty.io:9.4.18.v20190429]

at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117) [80:org.eclipse.jetty.io:9.4.18.v20190429]

at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333) [92:org.eclipse.jetty.util:9.4.18.v20190429]

at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310) [92:org.eclipse.jetty.util:9.4.18.v20190429]

at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168) [92:org.eclipse.jetty.util:9.4.18.v20190429]

at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126) [92:org.eclipse.jetty.util:9.4.18.v20190429]

at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366) [92:org.eclipse.jetty.util:9.4.18.v20190429]

at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:698) [92:org.eclipse.jetty.util:9.4.18.v20190429]

at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:804) [92:org.eclipse.jetty.util:9.4.18.v20190429]

at java.lang.Thread.run(Thread.java:748) [?:?]

same here can’t connect to the snapserver…

ok I found the problem. I use two snapclients on the same device with #1 und #2 so my ID Adresse in the things file has a #1 or #2 at the end and the plugin did not like this. So I had to start one client with a preset ID with the option “–hostID” and now it works.

OH 3.0 is released and I like to ask if someone is able to port the binding to OH3.0. I heard from another binding that it is not to hard to do. So it needs not many changes but I can’t do it I have no idea how to do that.

by the way here is the log output when putting the jar file into the addon folder:

10:23:30.551 [WARN ] [org.apache.felix.fileinstall         ] - Error while starting bundle: file:/usr/share/openhab/addons/org.openhab.binding.snapcast-2.5.0-SNAPSHOT.jar
org.osgi.framework.BundleException: Could not resolve module: org.openhab.binding.snapcast [327]
  Unresolved requirement: Import-Package: org.eclipse.jdt.annotation; resolution:="optional"
  Unresolved requirement: Import-Package: org.eclipse.smarthome.config.core

        at org.eclipse.osgi.container.Module.start(Module.java:444) ~[org.eclipse.osgi-3.12.100.jar:?]
        at org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:383) ~[org.eclipse.osgi-3.12.100.jar:?]
        at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundle(DirectoryWatcher.java:1260) [bundleFile:3.6.4]
        at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundles(DirectoryWatcher.java:1233) [bundleFile:3.6.4]
        at org.apache.felix.fileinstall.internal.DirectoryWatcher.startAllBundles(DirectoryWatcher.java:1221) [bundleFile:3.6.4]
        at org.apache.felix.fileinstall.internal.DirectoryWatcher.doProcess(DirectoryWatcher.java:515) [bundleFile:3.6.4]
        at org.apache.felix.fileinstall.internal.DirectoryWatcher.process(DirectoryWatcher.java:365) [bundleFile:3.6.4]
        at org.apache.felix.fileinstall.internal.DirectoryWatcher.run(DirectoryWatcher.java:316) [bundleFile:3.6.4]
10:23:30.557 [WARN ] [org.apache.felix.fileinstall         ] - Error while starting bundle: file:/usr/share/openhab/addons/org.openhab.binding.snapcast-2.5.0-SNAPSHOT.jar
org.osgi.framework.BundleException: Could not resolve module: org.openhab.binding.snapcast [327]
  Unresolved requirement: Import-Package: org.eclipse.jdt.annotation; resolution:="optional"
  Unresolved requirement: Import-Package: org.eclipse.smarthome.config.core

        at org.eclipse.osgi.container.Module.start(Module.java:444) ~[org.eclipse.osgi-3.12.100.jar:?]
        at org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:383) ~[org.eclipse.osgi-3.12.100.jar:?]
        at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundle(DirectoryWatcher.java:1260) [bundleFile:3.6.4]
        at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundles(DirectoryWatcher.java:1233) [bundleFile:3.6.4]
        at org.apache.felix.fileinstall.internal.DirectoryWatcher.doProcess(DirectoryWatcher.java:520) [bundleFile:3.6.4]
        at org.apache.felix.fileinstall.internal.DirectoryWatcher.process(DirectoryWatcher.java:365) [bundleFile:3.6.4]
        at org.apache.felix.fileinstall.internal.DirectoryWatcher.run(DirectoryWatcher.java:316) [bundleFile:3.6.4]

Andy

I guess nobody is maintaining it so I’ve updated the plugin for 3.0:

org.openhab.binding.snapcast-3.1.0-SNAPSHOT.jar

@StbX I’ve also updated it for the new build Bnd system, and I can try to work a bit more on the code review comments, so it might be merged, as long as you don’t mind.

3 Likes

wow thx a lot! It works as expected!
How hard is it to maintain this binding, and how hard was it to update it from 2.5 to 3.0?

I’m just asking since my system relies on the snapcast binding (I use a NEEO Remote which can control all the snapcast clients). In the meantime I made a solution with EXEC and some python scripts which work but are not very neat.

2.5 to 3.0 was easy, it only needed a couple of renames. It took me a bit of time to get to know it and to convert the binding to use the new build system as it was still using the old one.

I might try to fix the code review comments that were on the old pull request and make an new one and see if I can get this plugin merged into openHab addons.

But first I have to convert the rest of my system to openHab 3.

thx for your work and yeah would be great to have it integrated into the openHab addon.

great work - thank you!

Also a big thank you from my side. Everything works great on OH3.1.

Just wondering how I can achieve to change the stream of a specific client. I have the streams channel bound to a string item. It shows me a comma separated string, but how do I change from one stream to another.

@esdeboer @StbX any chance to port this excellent addon to OH v3.2? its essential for me before upgrading…

I’m running openHAB 3.2.0 and the binding is working

I think my 3.1 version just works for 3.2. I’ll let you know once I’ve upgraded my openHab (I should have some time for that before the end of the month)

oh, I didn’t know that! So i can upgrade and just leave this addon jar as-is? great! thank you!