Wednesday, June 3, 2015

.NET Rounding Error

A recent project of mine was creating a custom reporting engine in .NET since all of the commercial ones were either too expensive or not flexible enough for the projects requirements.  After creating the engine the natural next step was writing reports to run on it; it was during this process that I found a very interesting error in .net 4.

.NET apparently handles calculations differently depending on whether or not they are implicit or explicit.  For example if you were to run this statement:

If( 3 < (0.6F / 0.2F ))

you would expect .net to do the float calculation, then either cast the integer to a float, or round the float to an integer and perform the calculation.  Apparently it does not as the statement above always evaluates to true, when in reality it is false since the integer 3 is the same value as the float 3.0.  My guess is when performing the division there is some sort of math error in the .net engine which results in something like 3.0000000000000000000001 for 0.6F / 0.2F

The solution to this issue is to explicitly force trimming like this:

Int f = (int)(0.6F / 0.2F)
If( 3 < f )

The above statement casts the float calculation to an integer effectively truncating the extra floating data and allowing a correct comparison.  A better solution would probably be to use Math.Round just in case .net decides to evaluate the calculation to just under 3 rather than just over it.

Friday, March 6, 2015

ELEC new wireless talk camera

ELEC has recently come out with a new wireless camera that allows you to talk out of it.  Considering it is only $40 it is far cheaper than any other competition with that feature so I thought I would try it out.  Unfortunately I was in for a big disappointment.

I was initially pretty disappointed that it lacks an RJ45 port to configure it with, i'm guessing it uses bluetooth or it's own wifi hotspot for initial configuration, either way it requires you to download their app onto your phone for initial configuration.  This is the first camera I have seen that does not have an ethernet port, a big shortcoming in many ways in my opinion.

The web interface for it is viewing only, no configuration changes, which means I need to use my phone for any administrative changes which I do not like.

Their software has a spot for a static IP address, but when I tried to put one in it would not save.  After contacting their support I was told it only supports DHCP.  Another huge shortcoming.  Granted you could put a static reservation in your router for it, so I could live with this if I had to.

Support for elec on the web does not exist yet, so if you get one you will be relying on blog posts like this one, your own whit, or on their support which sometimes responds and sometimes does not.  If they do respond you have to ask only one simple little question at a time, they don't seem to be able to actually read emails.

I had a momentary spark of hope when I attempted adding it to my XProtect system as a generic OnVif device and it was actually recognised.  Unfortunately, XProtect completely loses connection with it if the microphone is enabled (I have covered that issue in my post about dlink products), and still loses connection for a couple of seconds every 30 seconds or so even with the microphone disabled.  I'm not sure who's fault that is just yet. (see below for fix)

Unless I get some more of these issues figured out I will not be buying another Model: EL -Wini001 720P wifi security camera.

Edit: Using wireshark I was able to get the url for the video feed as rtsp://

Using that I setup a Universal driver in XProtect with:
Codec: H264
Streaming Mode: RTP (UDP)
Keep alive: Default
Connection URI: live0.264
RTSP port: 554

So far I have not lost connection to the camera, as long as the microphone is disabled in XProtect.  Wireshark indicates that the audio is G.711 PCMU, however I have not gotten that to work yet.  At least this camera is not a total loss anymore, if I could get the audio to work I think I would even call it a decent camera.  At 1280 x 720 the video quality is definitely far superior to what the dlinks offer.

The connection URI seems to be live0.264 or live1.264 depending on which of the two feeds the camera offers you want to tap into.

It looks like I was able to get the OnVif to work for this camera.  For some reason changing some things in the config resets the cameras protocol from RTP/UDP to RTP/RTSP/HTTP/TCP.  Simply changing that setting back again to RTP/UDP fixes the issue and the camera works great.

Tuesday, February 24, 2015

Overlapping Columns in Microsoft ASP.NET Chart controls

I was recently tasked with creating a reporting solution that generated column style graphs.  However, there was a twist, the various series in the graphs had to be partially overlapping.

There are lots of solutions available for fully overlapping, stacked, or side-by-side.  But partially overlapping seemed to be missing from all of the posts I found.  Very few people were even asking the question of how to do it, although I did find one post that never got answered.

After much searching, and hours of trying different solutions, I finally found a post that gave me some added information regarding Chart Areas that I was missing.  However, this post cautioned that if one chart area had tick marks and labels while another did not then there was no way to get the axis lines to match up.  Considering I ended up being successful in my endeavours I am not entirely sure what that comment was referring to.

Using this code:
    Chart chrt = new Chart();
    chrt.ChartAreas["ChartAreaRed"].BackColor = System.Drawing.Color.Transparent;
    chrt.ChartAreas["ChartAreaRed"].Position.Height = 100;
    chrt.ChartAreas["ChartAreaRed"].Position.Width = 100;
    chrt.ChartAreas["ChartAreaRed"].InnerPlotPosition.Height = 90;
    chrt.ChartAreas["ChartAreaRed"].InnerPlotPosition.Width = 80;
    chrt.ChartAreas["ChartAreaRed"].InnerPlotPosition.X = 10;
    chrt.ChartAreas["ChartAreaRed"].AxisY.Maximum = 6;
    chrt.ChartAreas["ChartAreaRed"].AxisX.Maximum = 5;
    chrt.ChartAreas["ChartAreaRed"].AxisX.Interval = 1;
    chrt.ChartAreas["ChartAreaRed"].Position.X = 0;
    chrt.ChartAreas["ChartAreaGreen"].BackColor = System.Drawing.Color.Transparent;
    chrt.ChartAreas["ChartAreaGreen"].Position.Height = 100;
    chrt.ChartAreas["ChartAreaGreen"].Position.Width = 100;
    chrt.ChartAreas["ChartAreaGreen"].InnerPlotPosition.Height = 90;
    chrt.ChartAreas["ChartAreaGreen"].InnerPlotPosition.Width = 80;
    chrt.ChartAreas["ChartAreaGreen"].InnerPlotPosition.X = 10;
    chrt.ChartAreas["ChartAreaGreen"].AxisY.Maximum = 6;
    chrt.ChartAreas["ChartAreaGreen"].AxisX.Maximum = 5;
    chrt.ChartAreas["ChartAreaGreen"].AxisX.Interval = 1;
    chrt.ChartAreas["ChartAreaGreen"].Position.X = 0;
    chrt.ChartAreas["ChartAreaGreen"].Axes[0].Enabled = AxisEnabled.False;
    chrt.ChartAreas["ChartAreaGreen"].Axes[1].Enabled = AxisEnabled.False;
    chrt.ChartAreas["ChartAreaBlue"].BackColor = System.Drawing.Color.Transparent;
    chrt.ChartAreas["ChartAreaBlue"].Position.Height = 100;
    chrt.ChartAreas["ChartAreaBlue"].Position.Width = 100;
    chrt.ChartAreas["ChartAreaBlue"].InnerPlotPosition.Height = 90;
    chrt.ChartAreas["ChartAreaBlue"].InnerPlotPosition.Width = 80;
    chrt.ChartAreas["ChartAreaBlue"].InnerPlotPosition.X = 15;
    chrt.ChartAreas["ChartAreaBlue"].AxisY.Maximum = 6;
    chrt.ChartAreas["ChartAreaBlue"].AxisX.Maximum = 5;
    chrt.ChartAreas["ChartAreaBlue"].AxisX.Interval = 1;
    chrt.ChartAreas["ChartAreaBlue"].Axes[0].Enabled = AxisEnabled.False;
    chrt.ChartAreas["ChartAreaBlue"].Axes[1].Enabled = AxisEnabled.False;

    chrt.ChartAreas["ChartAreaBlue"].AxisX.MajorGrid.Enabled = false;

    Series chrtS_Red = new Series();
    chrtS_Red.Points.Add(new DataPoint(2, 1));
    chrtS_Red.Points.Add(new DataPoint(3, 0));
    chrtS_Red.Points.Add(new DataPoint(4, 2));
    chrtS_Red.ChartType = SeriesChartType.Column;
    chrtS_Red.Color = System.Drawing.ColorTranslator.FromHtml("#aa220d"); // massini red
    chrtS_Red.IsValueShownAsLabel = true;
    chrtS_Red.EmptyPointStyle.IsValueShownAsLabel = false;
    chrtS_Red["PointWidth"] = ".5";
    chrtS_Red["LabelStyle"] = "TopLeft"; // Auto, Top, Bottom, Right, Left, TopLeft, TopRight, BottomLeft, BottomRight, Center
    chrtS_Red.ChartArea = "ChartAreaRed";

    Series chrtS_Green = new Series();
    chrtS_Green.Points.Add(new DataPoint(2, 0));
    chrtS_Green.Points[0].IsEmpty = true;
    chrtS_Green.Points.Add(new DataPoint(3, 5));
    chrtS_Green.Points.Add(new DataPoint(4, 0));
    chrtS_Green.Points[2].IsEmpty = true;
    chrtS_Green.ChartType = SeriesChartType.Column;
    chrtS_Green.Color = System.Drawing.ColorTranslator.FromHtml("#94952d"); // massini green
    chrtS_Green.IsValueShownAsLabel = true;
    chrtS_Green.EmptyPointStyle.IsValueShownAsLabel = false;
    chrtS_Green["LabelStyle"] = "TopLeft"; // Auto, Top, Bottom, Right, Left, TopLeft, TopRight, BottomLeft, BottomRight, Center
    chrtS_Green["PointWidth"] = ".5";
    chrtS_Green.ChartArea = "ChartAreaGreen";

I was able to produce this graph:

Overlap with Chart Areas

While it is definitely complex and difficult to understand, once you do understand it it allows for a great deal of control. The key is setting all the Chart Areas width and heights to the same values, then doing the same with the InnerPlotPosition attributes.

The InnerPlotPosition allows you to control the area inside the plot area that is dedicated to plotting the values rather than having the grid lines and values included in the width and height calculations.

You have to set a value for both the width and the height for InnerPlotPosition or else a default of 0 will be used and you will see nothing.

Also, if you intend to have grid lines or X and Y axis values then you will need the width and height values for InnerPlotPosition to be less than 100 to allow for room inside the Chart Area for those items, or else they will be hidden.

Finally, when using layers, make sure you set all the backgrounds to transparent or you will only see the last layer added. If you want a background then apply it to the first layer.

Tuesday, January 6, 2015

Add DLink DCS-932L cameras to Milestone's XProtect Go software


I've been trying to get some of my low end DLink cameras to work with XProtect Go. I have been successful getting their feeds in iSpy, BlueIris, VLC, and the D-ViewCam. However, for some reason I could not get them to work with XProtect.

After trying many different settings, and searching the web for hours, I finally decided to try Wireshark. I am no expert with wireshark by any means, but it seemed to me that XProtect was failing to add the correct port to the request URL even though I had specified a port when setting up the camera. So I tried setting the port back to port 80 on the camera itself, but it seemed to have no effect.

In XProtect I have tried many combinations, and during the wireshark test was trying (turns out it does work):

Code: JPEG
Streaming Mode: HTTP
Delivery Mode: Multipart stream
Retrieval mode: Snapshot
Connection URI: mjpeg.cgi

I realise these are two different IPs, I was capturing data using two different cameras to make it easier to filter through the results in Wireshark. However, all the cameras work with BlueIris. (Yes I changed IPs and passwords for this post)

XPROTECT (Doesn't Work):
GET /mjpeg.cgi HTTP/1.1\r\n
User-Agent: HTTP Image Reader\r\n
Connection: Keep-Alive\r\n
User-Agent: HTTP Image Reader\r\n
Authorization: Basic YWRtaW46==\r\n
Credentials: admin:password
Full request URI:

GET /mjpeg.cgi HTTP/1.1\r\n
User-Agent: BlueIris\r\n
Connection: Keep-Alive\r\n
Authorization: Basic YWRtaW=\r\n
Credentials: admin:password
Full request URI:


After doing more research on the web and pouring over other people's posts with the same problem I finally found the solution.

It turns out there are quite a few settings that actually do work with XProtect. However, XProtect does seem to have a flaw in that it cannot correctly pass authentication to the DLink camera.

The biggest change I needed to make was turning off UAC as this post suggested. It is found on the Maintenance tab of the DCS-930L and DCS-932L cameras under Server Settings, it is called User Access Control. By disabling this feature I believe you are turning off the ability to have multiple user accounts on the camera itself, a nice feature being lost, but in my case I can live without it.

Once that change has been made on the camera, specific ports do seem to work just fine. Specific ports are nice if you want direct access to the cameras through your firewall, in my case so the DLink mobile app doesn't time out.

The Settings in XProtect that I have found to work the best are:
Codec: JPEG
Streaming mode: HTTP
Delivery mode: Non multipart stream
keep alive type: Default (greyed out)
Retrieval mode: Snapshot
Connection URI: image/jpeg.cgi

These settings seem to provide a more consistent network stream when viewed in wireshark:
Codec: JPEG
Streaming mode: HTTP
Delivery mode: Non multipart stream
keep alive type: Default (greyed out)
Retrieval mode: Streaming
Connection URI: video.cgi

Other delivery modes, retrieval modes, and URI's do work, however the ones I tried caused a great deal of jerkiness to be introduced into the stream.


Edit: I am using the Universal 1 channel driver in XProtect.  Also, DCS-932L and 930L cameras are NOT ONVIF compatible , nor do they support RTSP streams.  If you want the technical details on how to use the XProtect universal driver you can find them in their KB article 197.

Edit2: I ran into an issue where the cameras were flashing, or not connecting at all in the smart client.  I had to disable the microphone on the server side to fix this issue.  I have not configured it yet, perhaps when correctly configured it will not be an issue.

Edit3: I have noticed that when the microphone is enabled that the video stream slows up quite a bit, but if I use the jpeg snapshots refresh speed is still quite good.  The downside is that the snapshots take up easily 3 times the space and bandwidth.

Friday, December 5, 2014

.NET WSDL integration array error

I have not had a lot of need for web services over the years, but now and then they have come in handy, so I have had to learn about them; including some of the hair pulling issues that they can result in.

For this post I was trying to integrate a C#.NET solution with  A few years ago I had done the same thing using the older Web References which I was more familiar with and which were less flexible and therefore simpler to use.  However this time I had a bigger development window and decided to do things right using the newer Service Reference.

Most of the changes were not too hard, just took some digging since so much of the Sales Force documentation uses the old web references code.  Add to that the fact that Sales Force had made some decent sized changes to their WSDL over the years and it took me a full day to get the code to compile the first time.

When I ran it for the first time I received this odd error :

Error CS0030: Cannot convert type 'TRCWebApp.SalesForceEnterprise.ListViewRecordColumn[]' to 'TRCWebApp.SalesForceEnterprise.ListViewRecordColumn'

The most confusing part initially was that I didn't recognize the class from the basic login code I had written, I had never used it.  Fortunately, I was not the first person to run into this problem, and I was able to easily find the solution here.  What bothered me enough to write this post is that it was not an error in my code, or even in the Sales Force WSDL.  It was actually an error in the .net code generator that created the Reference.cs class from the WSDL.

Apparently the "code generation component cannot handle the XSD definitions that have only one element and the occurrence of the element is unbounded."

There are two solutions listed that I found:
1. "to manually modify the schema and altered the constructors for those 2 classes mentioned above by adding an extra dummy attribute".  The Sales Force specific fix is shown here, of course you would have to regenerate the code after making the change:

2. The option I chose was quite a bit simpler as long as you know where to find the generated Reference.cs file in the Service References folder of your project.  "I had to delete the extra [] from public ListViewRecordColumn[][] records in Reference.cs which is a file that is formed from the WSDL".  I opened the References.cs file in Notepad++ to follow those directions, did a search for ListViewRecordColumn[][] and renamed all two instances of it to ListViewRecordColumn[].

Problem solved, my code compiled and was able to talk to Sales Force.

Thursday, November 13, 2014

.js normal reference to embedded file authentication issue in .net

I had written a fairly complex paging object in javascript for a custom reporting system built on the .net platform.  It was all bundled up as an embedded resource for the custom system but I wanted to re-use it for another part of the site that suddenly needed to do paging.

When I first added the file reference in the head of my HTML document everything was working great.  But an hour or so later I started getting javascript reference errors saying there was a syntax issue inside the file.  I looked at what my browser was referencing as the file and discovered that it was getting an authentication denied page instead.

It turns out that .net handles embedded resources a little differently than normal files; which is to be expected since they get bundled up in the dll.  I was just expecting a second copy of my .js file to remain in its folder in addition to getting bundled, but it would seem that .net protects that file.

I was able to get my basic reference working correctly by navigating to the reporting pages which reference the embedded resource.  Once the reporting system had correctly authenticated and downloaded the embedded .js file then my other page was able to use it until that authentication ran out.  The long term fix of course it to add an embedded reference to the file on the new page as well.

Monday, September 8, 2014

Custom Security System

If you are considering setting up and installing a personal security system by yourself, the amount of setup involved can be daunting.  Even if you do have the technical know how to get the wires plugged in correctly, the base station installed, scheduled, and connected to the internet properly; you still have to deal with the headache of actually running the wires and the ability to overcome wire length limitations.

Do-It-Yourself Option
Fortunately technology has come a long ways, and it is now possible to purchase a nice do-it-yourself home system for fairly cheap.  Several companies have come out with IP based cameras which can connect to your existing computer network making setup costs much lower.  However, unless you get the cameras on sale, they will end up costing as much as a traditional system.  The brand I have gone with is D-Link.  The D-Link DCS-930L and DCS-932L cameras are great; the 932 has night vision while the 930 model does not.  When on sale you can get the DCS-930L for as low as $30 from, and the DCS-932L for as low as $40.

The two reasons I chose the method I did for a personal security system are: it is easily implemented on top of my existing IP based network, and two it is very scalable.  So I can slowly buy one camera at a time and increase my system as desired, needed, or money is available.

There are of course other security devices such as the magnetic open window detectors, but most security firms have long since stopped using those due to the inherent flaw that you can just break the window and they won't go off.  Motion detection, night vision, heat sensing, and image capture seem to be the key features common to most modern systems.

Considering the price, these cameras have a wide range of abilities.  Everything from emailing on motion detection, to built-in remote viewing over the Internet.  Of course you can also schedule the activation of night vision or motion detection as well as choose where in the viewing area motion will be checked for and at what sensitivity level.

The biggest downside to this system is the resolution, or picture quality.  While it works great in a normal house or office building, it is not good enough for facial recognition at long distances.

Convenience and Security Risks
The cameras do have an incredibly convenient wireless feature which allows you to setup the security network with almost no effort so long as you are within range of a wireless router.  Using this method does put your system at risk for an interference attack.  Even something as innocent as a microwave can take down a cameras wireless signal if it is close enough.  However, the chances of a normal residential house being broken into by someone with enough knowledge and skill to take advantage of that seems unlikely.  And for businesses who need to be more careful the camera does come with a standard ethernet jack.

These cameras do require power in order to function.  Which means that a backup generator, or battery backups would be required to overcome an attack where someone cuts the power to the location.

Most of this does require an active Internet connection to work as well, which of course is another potential security flaw should an intruder cut your Internet access.  While a redundant Internet connection would be nice, most people building their own system do not want to spring for such an expensive recurring cost.

Fortunately D-Link gives away for free a very nice software package called D-ViewCam which brings the power of a traditional base station to this custom system.  It allows for video recording on schedule, motion detection, or manually.  It provides remote access to both the cameras and archived recordings, and has extensive logs built-in so you know about any network related issues or user actions that have affected your system.
EDIT: I have since moved to Mileston's XProtect Pro system, an amazing product.

Alternate Options
D-Link is not the only option out there, it just happens to be my favorite.  Brands such as Wansview offer cheaper cameras than D-Link, but reviews indicate they may not last as long and the management software does not feel as polished as the D-Link offerings.

If you are comfortable with running wires you could go the route of an ELEC system, which are incredibly inexpensive for what you get.  Less convenience, more functionality.  The ELEC brand is currently the cheapest closed circuit I am aware of; obviously cheapness carries all the normal risks of cheap hardware and software.

So far I have had very little success combining more than one brand for the near free price I like.  None of the brands software supports other brands hardware.  However there are a few third party options that give something in this area. Blue Iris seems to be a common favorite among the industry, but the interface was not clean enough for me to be interested in the learning curve, and it is not free.  iSpy was my favorite, it has a bit more polish and supports anything and everything I could possibly want.  Unfortunately iSpy does not have a reasonable remote or mobile offering, the best I could come up with for a mobile app to supplement iSpy is called IP Cam Viewer Lite.  It was able to successfully connect to both my D-Link IP cameras, and my ELEC CCTV system; the downside was I had to give up a lot of the custom and extra functionality the brands own apps gave.  It was a great mobile viewer that rivaled and sometimes surpassed the brands personal software's viewing capabilities, but not much more.

In conclusion, if your building requires the additional security of being up through a power failure, and being less susceptible to other types of direct security system compromises, I would recommend going with the more traditional closed circuit systems.  However, if you are looking for something quick that will cover 90% of every day events with minimal hassle, setup, or costs, then the system I have built is probably exactly what you are looking for.