IpCamera: New IP Camera Binding

See this… https://github.com/Skinah/IpCamera/issues/22

I use cameras made by both companies and will continue to use them as they have great value for money. Every non camera device I own is calling home regardless of where it was made, that does not mean the traffic is bad. today devices have to check for security patches and also poke holes in your firewall to make apps work seamlessly for normal everyday users.

I have just installed the binding, and set it up with a Hikvision camera, API and ONVIF has been enabled in the cam.

I am NOT using the image stream from the binding, but referencing the imageurl and showing that.

Every few seconds I get the following error, does anyone know how to get rid of that?

2018-12-04 11:19:10.757 [WARN ] [netty.channel.DefaultChannelPipeline] - An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
io.netty.util.concurrent.BlockingOperationException: DefaultChannelPromise@1ea4e5f(incomplete)
	at io.netty.util.concurrent.DefaultPromise.checkDeadLock(DefaultPromise.java:395) ~[190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.DefaultChannelPromise.checkDeadLock(DefaultChannelPromise.java:159) ~[190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.util.concurrent.DefaultPromise.awaitUninterruptibly(DefaultPromise.java:246) ~[190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.DefaultChannelPromise.awaitUninterruptibly(DefaultChannelPromise.java:137) ~[190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.DefaultChannelPromise.awaitUninterruptibly(DefaultChannelPromise.java:30) ~[190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at org.openhab.binding.ipcamera.handler.IpCameraHandler.sendHttpRequest(IpCameraHandler.java:398) ~[190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at org.openhab.binding.ipcamera.handler.IpCameraHandler.sendHttpGET(IpCameraHandler.java:275) ~[190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at org.openhab.binding.ipcamera.handler.IpCameraHandler.motionDetected(IpCameraHandler.java:1193) ~[190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at org.openhab.binding.ipcamera.handler.IpCameraHandler.access$40(IpCameraHandler.java:1187) ~[190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at org.openhab.binding.ipcamera.handler.IpCameraHandler$HikvisionHandler.channelRead(IpCameraHandler.java:909) ~[190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at org.openhab.binding.ipcamera.handler.IpCameraHandler$CommonCameraHandler.channelRead(IpCameraHandler.java:579) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at org.openhab.binding.ipcamera.internal.MyNettyAuthHandler.channelRead(MyNettyAuthHandler.java:225) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:438) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:284) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:646) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:581) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:498) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:460) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [190:org.openhab.binding.ipcamera:2.4.0.201811270958]
	at java.lang.Thread.run(Thread.java:748) [?:?]

Hey @matt1,

I have updated the binding to use the fielddetection alarm. The CHANNEL_ENABLE_FIELD_DETECTION_ALARM is working to turn the detection on and off. The CHANNEL_FIELD_DETECTION_ALARM turns on when there is intrussion detected, but it does not turn off.
Is it possible the the alarm doesn’t pick up when there is no intrussion?
Cheers and thanks for implementing this.
BTW: I am using the binding with Hikvision DS-2CD2142FWD-IWS and DS-2CD2042WD-I
Jef

Do other alarms types function correctly?
Watch what happens in any browser with this address open adjusted for your IP of course:

http://192.167.3.1/ISAPI/Event/notification/alertStream

What happens when no alarms are going off?
Check for a newer firmware for the camera. I’ll take a look after I hear about the above…

@petero

The warning is sometimes not helpful as knowing what the binding was doing just before the first error occurred. Enable trace logging and watch the log after a server restart. It could be from the camera locking you out from using the wrong password too many times?

Thank you for this great binding. I am using it with two Instar cameras (9008 and 8015). After installing the second camera I started to run into the issue that the update of the regular snapshots stop working sometimes. The camera is still available (live stream works and I can call the snapshot URL of the camera) but the snapshot is not updated anymore. Do you have any idea how to fix that issue or analyze it further?

You need to work out if it is my binding or the openhab framework/app at fault. Look at the event.log and you should see the binding updating the image, if this is happening yet it stops displaying then it wont be my binding but possibly a bug in the app or framework. I find the IOS app does not work at all, but the Andriod app does work as does using basic UI in a browser when using my iphone.

Thanks for your hints. I use the Android app and myopenhab.org to access my smart home. I switched off all regular events (running on Raspberry Pi) to reduce data writes to the SD card. I re-activated the event log. Now I am waiting for the snapshot update to fail again. Since yesterday it is working reliably.

Hi, With my cam (IPC-HDBW4431R-AS) , Every 20s, I have this warning :slight_smile:
Event detection works fine anyway …
[WARN ] [ding.ipcamera.handler.IpCameraHandler] - The alarm checking stream was not running. Cleaning channels and then going to re-start it now.

I was able to reproduce the error with my Instar IP camera regarding the snapshot updates. I assume that my camera didn’t have a WiFi connection for several minutes resulting in the behavior the I described. In my openhab.log I can find the following lines:
2018-12-10 12:26:43.630 [ERROR] [ing.ipcamera.handler.IpCameraHandler] - Can not connect with HTTP to the camera at 192.168.178.13:80 check your network for issues.

These messages appear for about 5 minutes. Thereafter OpenHAB doesn’t try to update the snapshot anymore. The last photo is from 12:25:33.

Is there a maximum retry counter or something similar that I can configure?

Has anyone had any success with the Xiaomi Yi Ants cameras - they’re currently on offer at Amazon down from £50 to £17.99!

Either with native firmware or the “Yi-hack” (https://github.com/fritz-smh/yi-hack)?

No there is no maximum, it should try and reconnect forever and until it successfully re-connects the snapshot will not update. When I have some time in a weeks time I will run some tests as I have not checked this function in a while. In the mean time perhaps check if the camera has a lock out if the password is entered whilst it is still booting up. Also try cleaning out the tmp and cache folders of openhab and reboot the server.

Yes that is currently normal and nothing wrong, I’ll take a look at changing this next time I have the IDE open. I may just move it to DEBUG output.

New Build 15-12-2018 new changes are:

  • Less logs for Dahua due to event stream needing to be restarted. @furax54
  • TP-Link NC250 fix to allow images to work for cameras that declare jpg instead of jpeg in http headers. Possible other cameras do this as well.

@rsterz Quick tests showed my cameras could have the cat5 cable pulled and reinserted and the camera goes offline and online correctly. If you still have issues you will need to provide some trace level log output by raising an issue at the github project.

Thanks matt1. I got it working with the Amcrest IP3M-943B model. I can see the snapshot image and the motion event work.

Has anyone try to retrieve the snapshot image and send it out using the Mail add-on? What is the best way to do this without exposing the plaintext password?

Thanks,

I just managed to send a snapshot by saving the raw image to a file and email that file using the Mail plugin.

@rule("Send snapshot")
@when("Item CamMotionAlarm changed to ON")
def sendSnapshot(event):
    logger.info('*** url: {}'.format(items['CamImageUrl'].toString()))
    image = items['CamImage'].getBytes()
    file = io.open("/tmp/amcrest.jpg", 'wb')
    file.write(image)
    file.close()
    Mail.sendMail(emailAddress, 'Cam image', '', ["file:///tmp/amcrest.jpg"])           

I think one problem with this approach is that if the Image item is not refreshed frequently, the image will be stale.

1 Like

The binding allows you to do a REFRESH command on the image channel and it will fetch a new image even if you have disabled image updates from happening automatically. In any rule you can send this command sleep for x time and then do what you have already worked out. If you can share your solution when working that would be great. Use code fences to preserve the formatting.

Oop I didn’t notice that my previous code snippet didn’t like the Linux line ending. I will try the refresh later. However, I just notice something strange today. After sometimes, the binding cannot connect to the camera for some reason, and it doens’t seem to try again. I just got home, and I notice the the timestamp on the still image is almost from 2 hours ago. And the log file has these entries:

2018-12-16 13:21:31.729 [ERROR] [org.openhab.io.net.http.HttpUtil    ] - Fatal transport error: java.net.SocketTimeoutException: Read timed out
2018-12-16 13:23:02.145 [WARN ] [ing.ipcamera.handler.IpCameraHandler] - Cleaning the channels has just force closed a connection.
2018-12-16 13:23:07.184 [WARN ] [ing.ipcamera.handler.IpCameraHandler] - Can't find ch when removing handler          URL:null
2018-12-16 13:23:07.192 [ERROR] [ing.ipcamera.handler.IpCameraHandler] - Can not connect with HTTP to the camera at 192.168.0.46:80 check your network for issues.
2018-12-16 13:24:01.198 [INFO ] [ing.ipcamera.handler.IpCameraHandler] - About to connect to the IP Camera using the ONVIF PORT at IP:192.168.0.46:80
2018-12-16 13:24:33.169 [INFO ] [ing.ipcamera.handler.IpCameraHandler] - Camera is reporting that it does NOT support Absolute PTZ controls via ONVIF
2018-12-16 13:24:33.172 [INFO ] [ing.ipcamera.handler.IpCameraHandler] - Finished with PTZ with no errors, now fetching the Video URL for RTSP from the camera.

The still image’s time stamp is 13:22:59. So it looks like the connection was lost, the binding reconnects, but somehow the image source wasn’t updated. Just now, 2 hours later, I open Amcrest View on my android and I can view the stream just fine. But the binding is still in a bad state.

Have you seen this issue before? I also notice this at least twice yesterday night.

I also see a number of exceptions like this:

2018-12-16 15:19:38.604 [ERROR] [ersey.server.ServerRuntime$Responder] - An I/O error has occurred while writing a resp
onse message entity to the container output stream.                                                                    
org.glassfish.jersey.server.internal.process.MappableException: java.io.IOException: java.util.concurrent.TimeoutExcept
ion: Idle timeout expired: 30000/30000 ms                                                                              
        at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrap
perInterceptor.java:92) ~[?:?]                                                                                         
        at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162) 
~[170:org.glassfish.jersey.core.jersey-common:2.22.2]                                                                  
        at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1130) ~[170:org.gla
ssfish.jersey.core.jersey-common:2.22.2]                                                                               
        at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:711) [171:org.glassfish
.jersey.core.jersey-server:2.22.2]                                                                                     
        at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:444) [171:org.glassfi
sh.jersey.core.jersey-server:2.22.2]                                                                                   
        at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:434) [171:org.glassfish.jerse
y.core.jersey-server:2.22.2]                                                                                           
        at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:329) [171:org.glassfish.jersey.core.jerse
y-server:2.22.2]                                                                                                       
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) [170:org.glassfish.jersey.core.jersey-common:2.
22.2]                                                                                                                  
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) [170:org.glassfish.jersey.core.jersey-common:2.
22.2]                                                                                                                  
        at org.glassfish.jersey.internal.Errors.process(Errors.java:315) [170:org.glassfish.jersey.core.jersey-common:2
.22.2]                                                                                                                 
        at org.glassfish.jersey.internal.Errors.process(Errors.java:297) [170:org.glassfish.jersey.core.jersey-common:2
.22.2]                                                                                                                 
        at org.glassfish.jersey.internal.Errors.process(Errors.java:267) [170:org.glassfish.jersey.core.jersey-common:2
.22.2]                                                                                                                 
        at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) [170:org.glassfish.jers
ey.core.jersey-common:2.22.2]
...
Caused by: java.io.IOException: java.util.concurrent.TimeoutException: Idle timeout expired: 30000/30000 ms                    
at org.eclipse.jetty.util.SharedBlockingCallback$Blocker.block(SharedBlockingCallback.java:235) ~[87:org.eclipse.jetty.util:9.4.11.v20180605]                                                                                                 
at org.eclipse.jetty.server.HttpOutput.write(HttpOutput.java:217) ~[84:org.eclipse.jetty.server:9.4.11.v20180605]                                                                                                                             
at org.eclipse.jetty.server.HttpOutput.write(HttpOutput.java:536) ~[84:org.eclipse.jetty.server:9.4.11.v20180605]                                                                                                                             
at java.io.OutputStream.write(OutputStream.java:75) ~[?:?]                                                             
at org.glassfish.jersey.servlet.internal.ResponseWriter$NonCloseableOutputStreamWrapper.write(ResponseWriter.java:320) ~[?:?]                                                                                                                 
at org.glassfish.jersey.message.internal.CommittingOutputStream.write(CommittingOutputStream.java:218) ~[?:?]          at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$UnCloseableOutputStream.write(WriterInterceptorExecutor.java:294) ~[?:?]                                                                                                  
at org.eclipse.smarthome.io.rest.core.internal.GsonProvider.writeTo(GsonProvider.java:71) ~[?:?]                       
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:265) ~[?:?]                                                                                         
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:250) ~[?:?]                                                                                         
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162) ~[?:?]                                                                                                                         
at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:106) ~[?:?]                                                                                                                  
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162) ~[?:?]                                                                                                                         
at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:86) ~[?:?]                                                                                                 ... 53 more         
Caused by: java.util.concurrent.TimeoutException: Idle timeout expired: 30000/30000 ms                                         
at org.eclipse.jetty.io.IdleTimeout.checkIdleTimeout(IdleTimeout.java:166) ~[75:org.eclipse.jetty.io:9.4.11.v20180605]
at org.eclipse.jetty.io.IdleTimeout$1.run(IdleTimeout.java:50) ~[75:org.eclipse.jetty.io:9.4.11.v20180605]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[?:?]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:?]                                                     
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[?:?]                                                                                                               
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) ~[?:?]                                                                                                                      
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[?:?]                              at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[?:?]                              
... 1 more                                                                       

I am not sure if that part is related to the binding. I am running OH 2.4 M5.

It is working fine here on Openhab 2.3 stable and I have not made any recent changes in the code that could cause that. You are using an unstable build of openhab so please do not report bugs without testing if it occurs on 2.3 stable. Btw there is at least a milestone 8 build so your using an old milestone.

EDIT:
@rsterz and @yfaway, you both seem to have the same issue. If it occurs in the latest milestone build then you should report this to the developers of the Milestone builds so it can be looked at before the milestones become the new stable build which is set to occur in the next few weeks.

Sadly the URL with the compiled .jar is not working:( Any ideas from where to download this Binding?

I was able to go to the URL and click on IP Cameras, then click on the latest zip file
it will download