Thank You so much! I updated to 2.5.5 and it’s working.
Do you have Paypal? This binding is really worth a coffee!
That’s great. Glad that resolved it. Thanks for the offer, but no need.
Thanks so much for this binding! Zoneminder finally works with OH (at least for me)!
I am wondering if it’s possible to have a element type “SELECTION” in a sitemap giving the option to choose for a live stream of one specific cam out of multiple cams. The live stream should be then e.g. shown below the selection based on the string given with “videoUrl” channel.
Anybody realized something like this already?
Nice to hear!
Interesting idea. I suppose you could do it was a rule, but it would be a little bit clumsy because you’d have to construct the video stream URL manually.
Alternatively, I think it would be possible to accomplish what you want by adding a couple channels to the server thing.
- 
monitorId - the binding would populate state options on this channel for all the monitor ids on the Zoneminder server. Sending a command to an item linked to this channel (or selecting a state option using a
Selectionwidget) would cause the binding to update another channel to contain the video streaming URL for that monitor id - 
videoUrl - This channel would contain the video streaming URL associated with the selected monitor id above, or UNDEF if nothing is selected.
 
WDYT?
I also was thinking about another channel on the server thing. This channel would be of type Image, and would cycle through all monitor images at a rate defined by a config parameter on the server thing. Thoughts?
@Falk I implemented the above-mentioned channels - videoStreamMonitorId and videoStreamUrl. If you would like to try it out, I posted the new version at the link in the first post. To use, you need to delete and readd just the server thing to pick up the new channels. Then you can put something like this in your sitemap.
                Selection item=ZmServer_VideoStreamMonitorId
                Video item=ZmServer_VideoStreamUrl url="" encoding="mjpeg"
IDK why it’s necessary to provide the url="" on the Video widget - if it’s not there, it throws an error when loading the sitemap.
Fantastic idea @mhilbush! However, I don’t seem to be there yet …
I uninstalled the old binding (2.5.4 from link in 1st post), installed the latest 2.5.5 jar, configured in zoneminder.items
String      zm_Server_videoStreamMonId      "Video Stream Monitor Id"               {channel="zm:server:ZoneMinder:videoStreamMonitorId"}
String      zm_Server_videoStreamUrl        "Video Stream URL"                      {channel="zm:server:ZoneMinder:videoStreamUrl"}
zoneminder.things already has:
Bridge zm:server:ZoneMinder [ host="192.168.20.4", refreshInterval=5, defaultAlarmDuration=120, discoveryEnabled=true, useDefaultUrlPath=true ]
For the items I get the following values
openhab> smarthome:status zm_Server_videoStreamUrl
UNDEF
openhab> smarthome:status zm_Server_videoStreamMonId
UNDEF
Therefore
Selection 	item=zm_Server_videoStreamMonId
Video 		item=zm_Server_videoStreamUrl 		url="" encoding="mjpeg"				
does not show anything but empty fields.
When starting up OH, I also see another error message for each monitor which I think is new in version 2.5.5. Anything other changes compared to 2.5.4? I checked items config but can not find a problem here.
2020-04-26 23:31:26.556 [WARN ] [mon.registry.AbstractManagedProvider] - Could not update element with key zm:monitor:1 in ManagedThingProvider,
because it does not exists.
2020-04-26 23:31:26.557 [WARN ] [mon.registry.AbstractManagedProvider] - Could not update element with key zm:monitor:2 in ManagedThingProvider,
because it does not exists.
2020-04-26 23:31:26.558 [WARN ] [mon.registry.AbstractManagedProvider] - Could not update element with key zm:monitor:3 in ManagedThingProvider,
because it does not exists.
2020-04-26 23:31:26.558 [WARN ] [mon.registry.AbstractManagedProvider] - Could not update element with key zm:monitor:4 in ManagedThingProvider,
because it does not exists.
2020-04-26 23:31:26.559 [WARN ] [mon.registry.AbstractManagedProvider] - Could not update element with key zm:monitor:5 in ManagedThingProvider,
because it does not exists.
2020-04-26 23:31:26.559 [WARN ] [mon.registry.AbstractManagedProvider] - Could not update element with key zm:monitor:6 in ManagedThingProvider,
because it does not exists.
2020-04-26 23:31:26.560 [WARN ] [mon.registry.AbstractManagedProvider] - Could not update element with key zm:monitor:7 in ManagedThingProvider,
because it does not exists.
2020-04-26 23:31:26.560 [WARN ] [mon.registry.AbstractManagedProvider] - Could not update element with key zm:monitor:8 in ManagedThingProvider,
because it does not exists.
2020-04-26 23:31:26.561 [WARN ] [mon.registry.AbstractManagedProvider] - Could not update element with key zm:monitor:9 in ManagedThingProvider,
because it does not exists.
btw: I am still running OH 2.5.4. Hope this is not a problem …
EDIT: sorry for being slow … I understand now I need to set “zm_Server_videoStreamMonId” with an ID and receive a video URL with zm_Server_videoStreamUrl. Will play around with this …
Nope, this is not an issue. Anything that’s 2.5.x will work.
Are you still seeing this? It seems like an issue with how the monitor things are defined (i.e. a mismatch in how the monitor thing is referencing the server bridge. Just a guess, though. Maybe post the whole .things file, not just the bridge?
Exactly. Once you select a monitor from the selection list, the item linked to the url channel should have a valid url for the video stream for that monitor.
here is the zoneminder.things configuration:
Bridge zm:server:ZoneMinder [ host="192.168.20.4", refreshInterval=5, defaultAlarmDuration=300, discoveryEnabled=true, useDefaultUrlPath=true ]
Thing zm:monitor:1 		"ZM Garten"			(zm:server:ZoneMinder) 		[ monitorId="1", imageRefreshInterval=10, alarmDuration=300 ]
Thing zm:monitor:2 		"ZM Wintergarten"	(zm:server:ZoneMinder) 		[ monitorId="2", imageRefreshInterval=10, alarmDuration=300 ]
Thing zm:monitor:3 		"ZM Garage"			(zm:server:ZoneMinder) 		[ monitorId="3", imageRefreshInterval=10, alarmDuration=300 ]
Thing zm:monitor:4 		"ZM Dach West"		(zm:server:ZoneMinder) 		[ monitorId="4", imageRefreshInterval=10, alarmDuration=300 ]
Thing zm:monitor:5 		"ZM Dach Süd"		(zm:server:ZoneMinder) 		[ monitorId="5", imageRefreshInterval=10, alarmDuration=300 ]
Thing zm:monitor:6 		"ZM Dach Ost"		(zm:server:ZoneMinder) 		[ monitorId="6", imageRefreshInterval=10, alarmDuration=300 ]
Thing zm:monitor:7 		"ZM Dach Nord"		(zm:server:ZoneMinder) 		[ monitorId="7", imageRefreshInterval=10, alarmDuration=300 ]
Thing zm:monitor:8 		"ZM Gehweg"			(zm:server:ZoneMinder) 		[ monitorId="8", imageRefreshInterval=10, alarmDuration=300 ]
Thing zm:monitor:9 		"ZM Carport"		(zm:server:ZoneMinder) 		[ monitorId="9", imageRefreshInterval=10, alarmDuration=300 ]
            Thanks so much @mhilbush, the live video works like a charm!
Only limitation I found is that with openhab app for iOS the video item does not refresh when being on the same page as the selection. Therefore I split the two items like this (sorry for german language labels):
Frame label="Live-Stream" {
  Selection item=zm_Server_videoStreamMonId			label="Kamera wählen"			icon="camera"		mappings=[0="KEINE", 1="Garten", 2="Wintergarten", 3="Garage", 4="Dach West", 5="Dach Süd", 6="Dach Ost", 7="Dach Nord", 8="Gehweg", 9="Carport"]
  Text 												label="Live-Stream"				icon="camera" {
    Video 	item=zm_Server_videoStreamUrl 			url="" encoding="mjpeg"								visibility=[zm_Server_videoStreamMonId!=0]
    Text											label="Keine Kamera ausgewählt"	icon="error"		visibility=[zm_Server_videoStreamMonId==0]			
  }
}
Another thought is to not have excessive data transmitted once the monitor ID has been defined. Not sure when the OH app for iOS receives data … however, there may be a risk of blowing up your mobile data capacity.
I therefore came up with this rule to limit the live stream to 5min:
var int zm_LiveStream_Timeout_Seconds = 300 		//seconds to allow for livestream of a selected cam
var Timer zm_LiveStream_Timeout_Timer = null		//timer for timeout
rule "Set videostream ID to 0 to prevent from sending excessive data"
	when
		Item zm_Server_videoStreamMonId changed
	then
		if (zm_Server_videoStreamMonId.state != 0) {
            if(zm_LiveStream_Timeout_Timer === null) {
                zm_LiveStream_Timeout_Timer = createTimer(now.plusSeconds(zm_LiveStream_Timeout_Seconds)) [|
                    zm_Server_videoStreamMonId.sendCommand(0)
                    zm_LiveStream_Timeout_Timer = null
                ]
            }
            else {
                zm_LiveStream_Timeout_Timer.reschedule(now.plusSeconds(zm_LiveStream_Timeout_Seconds))
            }
        }
        else {
            if (zm_LiveStream_Timeout_Timer !== null) {zm_LiveStream_Timeout_Timer = null}
        }
end
please note: not thoroughly tested yet …
Great! I’ll push the changes to my PR after I do a little cleanup.
That’s weird, but I guess that’s an issue with how the iOS app is implemented. Maybe you could open an issue on the openhab-ios repo.
I don’t know specifically how the iOS app works, but I’d be a bit surprised if it streamed video when the page containing the video is not active.
I probably should add the ability to send an OFF command, which would set the monitor id and stream url back to UNDEF.
@Falk I’m going to add a similar feature for images. It will work just the like feature I added for selecting the video URL. For consistency, I’m going to rename the video channels. So, when you update to the latest build, I’d suggest you drop and readd the server thing.
BTW, did you ever sort out the error messages you were seeing in the logs. I looked at this a little more, and couldn’t figure out what it was complaining about (although it had to do with the monitor things). I’m hoping a restart of OH will resolve the issue.
I’ve posted the version with image and video channels on the server thing.
This now enables you to have a rule that rotates through the images every n seconds.
val int NUM_MONITORS = 6
var int monitorId = 1
rule "Rotating Image"
when
    Time cron "0/10 * * ? * * *"
then
    var String id = String::format("%d", monitorId)
    ZmServer_ImageMonitorId.sendCommand(id)
    monitorId = monitorId + 1
    if (monitorId > NUM_MONITORS) {
        monitorId = 1
    }
end
If your monitor IDs aren’t consecutive, or if you only want to rotate through a subset of monitors (e.g. outside cameras only), you can rewrite the rule to cycle through a string array of ids.
Like this…
val monitors = newArrayList("1", "3", "4", "6")
var int index = 0
rule "Rotating Image 2"
when
    Time cron "0/10 * * ? * * *"
then
    ZmServer_ImageMonitorId.sendCommand(monitors.get(index))
    index = index + 1
    if (index >= monitors.size) {
        index = 0
    }
end
            I did install the new version and haven’t seen the message since then. Probably should have cleaned cache/temp in the first place.
Thanks again! Works fantastic for me (even with refreshing the image in OH iOS app).
Thanks a lot for your efforts creating this binding !
It works on initial setup, but after a few hours my zoneminder Webserver crashes when the Binding is active
From apache logs:
[mpm_prefork:error] [pid 232] AH00161: server reached MaxRequestWorkers setting, consider raising the MaxRequestWorkers setting
Could it be that the connections stay open somehow?
Sure I could raise these (currently set to 256), but the isse does not come up without the binding
I’m on Zoneminder 1.34.12 running in an Ubuntu 20.04 LTS LXC container
That’s odd. The connections shouldn’t be left open. The binding uses the standard openHAB core http client for all transactions with the Zoneminder server.
@mawa How many Zoneminder monitors do you have, and what is the Refresh Interval in the Zoneminder bridge config?
just 2 monitors with standard config from documentation example
refreshInterval=10
I can’t imagine what would be causing the problem. I have 7 monitors with a 5 second refresh interval. Mine has been running for weeks without issue. I just upgraded from 1.34.10 to 1.34.12 just to make sure I’m on the same ZM version as you, but I doubt that will make a difference based on the commit history between .10 and .12.
Also, have you checked the Apache server status page. I would expect it would show the number of connections growing over time. It might even give a clue if there’s a single transaction type that’s causing the issue.