Wednesday, March 18, 2015

PI with Java embedded Jetty for serving JSP or plain html and exposing Jersey REST services

Why? because I like embedding everything in one app in a more lightweight fashion.

First, make sure you have the Oracle 1.7 JDK instead of the delivered one with Debian, plenty of articles out there to hold your hand on that one.

Install Eclipse, it really helps to debug, and is quick enough to develop on.

Install Maven in Eclipse, I tried without and ended up in jar hell, so take the easier route.

POM dependencies :-
    <dependencies>
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-server</artifactId>
            <version>${jersey-version}</version>
        </dependency>
        <dependency>
   <groupId>org.glassfish.jersey.core</groupId>
   <artifactId>jersey-client</artifactId>
   <version>${jersey-version}</version>
</dependency>
<dependency>
   <groupId>org.glassfish.jersey.connectors</groupId>
   <artifactId>jersey-jetty-connector</artifactId>
   <version>${jersey-version}</version>
</dependency>
<dependency>
 <groupId>com.fasterxml.jackson.jaxrs</groupId>
 <artifactId>jackson-jaxrs-json-provider</artifactId>
 <version>2.3.0</version>
</dependency>
        <dependency>
   <groupId>org.glassfish.jersey.containers</groupId>
   <artifactId>jersey-container-servlet</artifactId>
   <version>${jersey-version}</version>
</dependency>
        <dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-http-spi</artifactId>
<version>${jettyVersion}</version>
</dependency>
        <dependency>
      <groupId>org.eclipse.jetty</groupId>
      <artifactId>jetty-server</artifactId>
      <version>${jettyVersion}</version>
   </dependency>
        <dependency>
      <groupId>org.eclipse.jetty</groupId>
      <artifactId>jetty-webapp</artifactId>
      <version>${jettyVersion}</version>
   </dependency>
        <dependency>
      <groupId>org.eclipse.jetty</groupId>
      <artifactId>jetty-security</artifactId>
      <version>${jettyVersion}</version>
   </dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-annotations</artifactId>
<version>${jettyVersion}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${jettyVersion}</version>
</dependency>
<dependency>
  <groupId>org.eclipse.jetty</groupId>
 <artifactId>apache-jsp</artifactId>
<version>${jettyVersion}</version>
</dependency>
    </dependencies>
    <properties>
        <jersey-version>2.7</jersey-version>
        <jettyVersion>9.3.0.M2</jettyVersion>
    </properties>

Make sure the jetty version is above 9.2 as the JSP compiler changed from glassfish to apache.

Do your standard jetty server object create on the desired port, the only thing you need to do to get JSP files served now is :-
              // Create WebAppContext for JSP files.
              WebAppContext webAppContext = new WebAppContext();
              webAppContext.setContextPath("/jsp");
              webAppContext.setResourceBase("/home/pi/Jetty/");
              webAppContext.setAttribute(InstanceManager.class.getName(), new SimpleInstanceManager());

//Now for the JAX-WS-RS (RESTful) resources
ServletContextHandler contextRS = new           ServletContextHandler(ServletContextHandler.SESSIONS);
contextRS.setContextPath("/RS");
  ServletHolder h =new ServletHolder(new ServletContainer());
       ServletHolder jerseyServlet = contextRS.addServlet(
               org.glassfish.jersey.servlet.ServletContainer.class, "/*");
          jerseyServlet.setInitOrder(1);      jerseyServlet.setInitParameter("jersey.config.server.provider.classnames",RESTService.class.getCanonicalName());
//RESTService is just a Jersey annotated class, standard stuff.

Add the handlers to the handler collection. Job done!.

It took me quite a while to get this, as there is a myriad of older deprecated garbage to sift through.
The key ingredient to JSP was the InstanceManager. I have other simple handlers, lifted straight from the online examples to return on the fly html content using other context's that just work out of the box.

Wednesday, March 4, 2015

Why do you need a taxi?

Is it just me, or does anyone else wonder why there are always a queue of taxi's waiting to service that long line of people in the 'Taxi Queue' at most airports?
I travel a fair bit to customer sites, mainly in Europe but also occasionally America's and Asia. I have rarely, with the odd exception, taken a taxi from or to the airport. An airport is always one of the most highly public serviced locations, providing plenty of bus, coach, train or tram links at frequent intervals.
Mostly a public service will be far quicker than taking a taxi, as you avoid the traffic jams that are always present on the airport ring roads, and mostly you are going to be travelling to the nearest city center for a travel connection or ultimate destination, which is normally also full of traffic jams.
It is also cheaper by a magnitude of 10 or 20, and the freedom of choice you have with where to step on or off or rejoin is far superior to a taxi service.
I also travel for business, so can reclaim the expense my travel, but even so, I still prefer public services.
So who are all of these people taking taxi's?  Anthropophobic? Agoraphobic? lazy? ignorant? I struggle to generalise, but with the amount of taxi's servicing those queues I see, I can only wonder.

Coincidental case in point, two guys just wandered in to the airport lounge, one complaining the taxi driver took all back streets to get here, the other complaining of being stuck in traffic, I took the metro and bus 119, 30 minutes relaxed from Prague central to terminal 2.

Here are some off the top of my head airports with great public service connections:


  • JFK
  • San Francisco
  • Vancouver
  • Heathrow, all terminals
  • Bristol, UK
  • Luton, UK
  • Gatwick, UK
  • Prague, Czech Republic
  • Schiphol, Netherlands
  • Charles de Gaulle, France
  • Toulouse, France

I will update the list again when I am next waiting in an airport lounge...boarding now

Monday, March 2, 2015

DSMR4 P1 reader with PL2303 from Windows PC and c# WinForm

For those out there who are NOT connecting with a Raspberry Pi and bought the 'cheap' PL2303 cable before they realised they were in trouble with the inverted signal on the DSMR4 smart meters, here is my experience from what I learned getting this to work, which is slightly different than has been posted already :-
http://www.domoticz.com/forum/viewtopic.php?f=14&t=4970
http://www.iproto.nl/post/37?title=P1+poort+%5C%26quot%3Bslimme%5C%26quot%3B+meter+uitlezen
http://www.maartendamen.com/2012/04/new-smart-meter-installed-iskra-me382-and-landis-gyr-gasmeter-e06140/
https://www.sossolutions.nl/gpio-accessoires/9324365-usb-naar-ttl-serieel-kabel.html

So many thanks to the above sources, they pretty much had everything I needed among them.

My first thoughts in this process was to buy a cable from http://www.smartmeterdashboard.nl/,
but instead I thought it might be fun to try and do this myself as a mini project. So before I did the proper research I ordered a PL2303 chipset USB to ttl serial, as it was going to keep me under the 22.50 budget level of smartmeterdashboard.

Next day delivery, I had my cable ready to hook up to the rj11 4 wire cable i had already prepared and plugged in to the meter 5 meters away through the floor of my office.

+5V connected, from Red wire on PL2303 USB to RJ11 BLACK (it seems they mix the red black to confuse us electrical numbties).
Black of USB to Red of RJ11 (the P1 port of the meter).
White Rx to Yellow of RJ11 (the P1 port of the meter).
Green, for now, not required, as we are not going to be sending anything to the meter, just reading.

At this stage I knocked up a quick visual studio WinForms project in C#, dropped a serial control to the form, set it to 115200/8N1, text box output on the data received event (.Read(byte[] buffer,0,length) then AppendText(System.Text.Encoding.Default.GetString(buffer)).

High expectations turned to disappointment, with no readings coming through, nothing at all. So back to researching, and came across the above sites detailing the differences with the DSMR4 meters, oops.
At first I thought I could get away with the 'pull up' resistor bridged from the +Ve and software manipulate the inversion. The following is my received buffer printed out by byte bit pattern separated by : the ascii char code, inverted code (unmasked at this stage to remove bit 8)
01000000:64:-65
00000000:0:-1
00111000:56:-57
00000000:0:-1
01000110:70:-71
01100000:96:-97
01110010:114:-115
01110010:114:-115
01100010:98:-99
01100010:98:-99
01110010:114:-115
00010010:18:-19
00011110:30:-31
00011110:30:-31
00011110:30:-31
00011110:30:-31
00000110:6:-7
00000110:6:-7
00010010:18:-19
00010010:18:-19
11000000:192:-193
11000010:194:-195
11000000:192:-193
11000010:194:-195
00000000:0:-1
01000110:70:-71
01000000:64:-65
01000100:68:-69
00100000:32:-33
00100100:36:-37

OK, so reverse engineering the UART protocol start & stop bits was not the fun I had intended, so more researching.
A transistor to hardware invert the signal is stretching my electronics capability, and I didn't want to order a single BS170, and I didn't have these Arduino boards, or any other type, to connect it to.
http://www.kabeldirect.nl/aten-uc-232a-usb-rs232-seriele-verloopkabel.html, would of made it easier for myself in the first place I guess.
Maybe time to buy that cable from smartmeterdashboard?
Overnight thoughts led me to cannibalise  an old pentium that had been gathering dust in the attic that the previous owner left up there. Searching for possible transistors on the circuit boards.
Googling a 2n3904 part number of similar looking items on an audio io board led me to other articles that electronic savvy people were posting about in relation to PL2303 and signal inversion for TTL.

So hooking up the left leg of this item to the +ve after the resistor, middle leg to the RJ11 inbound data (I moved the data (yellow RJ11 from P1 port) from being connected to the +ve)  and the right leg to the ground wires.
Nothing...again.
After a bit of head scratching and poking my wiring to make sure everything was connected correctly and soldered still I had a minor 'accident' of touching the transmit Green wire of the USB adapter to the middle leg of the transistor where the Data stream was attached while everything was connected up. All of a sudden my text box starts to fill with data, in a nice looking structured format!
What I realised later was that I had taken the 'pull up' power away from the data leg, and the USB green wire was carrying 3.3v from the spec sheet, which replaced the required power that I was missing. My lack of electronics knowledge would not of made this jump of revelation without the 'accident' as I had already connected one leg to the +ve and the other to ground, so 'completing' the circuit for my view.
Here is my reading!

/XMX5LGBBFFB200004422

1-3:0.2.8(40)
0-0:1.0.0(150302104808W)
0-0:96.1.1(4530303035303031343933343131333133)
1-0:1.8.1(001119.327*kWh)
1-0:2.8.1(000000.000*kWh)
1-0:1.8.2(001577.942*kWh)
1-0:2.8.2(000000.000*kWh)
0-0:96.14.0(0002)
1-0:1.7.0(00.144*kW)
1-0:2.7.0(00.000*kW)
0-0:17.0.0(999.9*kW)
0-0:96.3.10(1)
0-0:96.7.21(00002)
0-0:96.7.9(00000)
1-0:99.97.0(0)(0-0:96.7.19)
1-0:32.32.0(00000)
1-0:52.32.0(00000)
1-0:72.32.0(00000)
1-0:32.36.0(00000)
1-0:52.36.0(00000)
1-0:72.36.0(00000)
0-0:96.13.1()
0-0:96.13.0()
1-0:31.7.0(001*A)
1-0:51.7.0(000*A)
1-0:71.7.0(000*A)
1-0:21.7.0(00.082*kW)
1-0:41.7.0(00.046*kW)
1-0:61.7.0(00.015*kW)
1-0:22.7.0(00.000*kW)
1-0:42.7.0(00.000*kW)
1-0:62.7.0(00.000*kW)
0-1:24.1.0(003)
0-1:96.1.0(4730303137353931323038323037313134)
0-1:24.2.1(150302100000W)(01045.614*m3)
0-1:24.4.0(1)
!A395 

and my out of focus wiring :-)

Now to the fun part of parsing the data and making some graphics in my own particular way :-)

Hope this helps someone else out there in addition to the posts out there already.


 




Wednesday, September 26, 2012

reminder on validations in ajax mvc razor

 Order IS important and can stop the client side vlidation working if not in this order.
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery-ui-1.8.11.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>


        [Required]
        [StringLength(20, MinimumLength = 4)]
        [Display(Name = "User Name")]
        [RegularExpression(@"(\S)+", ErrorMessage = "White space is not allowed")]
        [ScaffoldColumn(false)]
        public string UserName { get; set; }

        [Required]
        [StringLength(18, MinimumLength = 0)]
        [Display(Name = "First Name")]
        public string FirstName { get; set; }
        [Required]
        [StringLength(18, MinimumLength = 0)]
        [Display(Name = "Last Name")]
        public string LastName { get; set; }

            <div class="editor-label">
                @Html.LabelFor(model => model.FirstName)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(model => model.FirstName)
                @Html.ValidationMessageFor(model => model.FirstName)
            </div>
           
            <div class="editor-label">
                @Html.LabelFor(model => model.LastName)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(model => model.LastName)
                @Html.ValidationMessageFor(model => model.LastName)
            </div>
            <div class="editor-label">
                @Html.LabelFor(model => model.UserName)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(model => model.UserName)
                @Html.ValidationMessageFor(model => model.UserName)
            </div>


All Active Directory Users 1000 user limit

Only 1000 of my AD entries were being returned by dsUsers,FindAll(), quick search after spending what seemed hours banging my head trying to debug where I could only access a small development DC with < 100 users...So deploy to prod server and output file appends with info, yeah the long way.
It was also only returning a portion of the properties within that 1000 too, 381 entries it told me didn't have an ipPhone field set, whereas Domain Users server tools told me that 99% were set...
Anyway, found that someone already had figured out to frig the Pagesize parameter, which for some reason got past the 1000 restriction.

                    // declare directory searcher
                    DirectorySearcher dsUsers = new DirectorySearcher(deRoot);

                    dsUsers.SearchScope = SearchScope.Subtree;
                    //OR the filter
                    dsUsers.Filter = "(|(objectCategory=person)(objectClass=user))";
                    dsUsers.PageSize = 1001;// ms limitation with shitty workaround

                    // define what properties you want to have loaded into your search results
                    dsUsers.PropertiesToLoad.Add("givenName");
                    dsUsers.PropertiesToLoad.Add("sn");
                    dsUsers.PropertiesToLoad.Add("samAccountName");
                    dsUsers.PropertiesToLoad.Add("ipPhone");
                    dsUsers.PropertiesToLoad.Add("telephoneNumber");
                    dsUsers.PropertiesToLoad.Add("mobile");
                    dsUsers.PropertiesToLoad.Add("department");
                    dsUsers.PropertiesToLoad.Add("l");

Tuesday, September 11, 2012

handy dynamic JQuery event handler


in View :-
grid2.Column(format: @<input type="button" onclick="mysub='@item.UserName'" value="Setup" name="Setup" id="Setup" />),

var mysub = "";

            $(function () {
                $("#Setup").live('click', function () {
                    alert(mysub);
                });
            });

Thursday, August 30, 2012

MVC razor pain with dropdowns

Took a little head banging against the wall with this one, probably my lack of exposure to the MVC @razor model.
                <div>
                Region  @Html.DropDownListFor(model => model.Region, Model.Regions)
                </div>
Simple enough...but for one reason and another I needed to change the model, and all of a sudden the currently selected 'Region' ws no longer being default selected on a repost.
                <div>
                Region  @Html.DropDownListFor(model => model.subclass1.Region, Model.Regions)
                </div>
at first it was the incorrect property declaration :-
public string Region =""; instead of public string Region { get; set; }
still not fixed...
moved a copy of Region from model.subclass1.Region back up a level to model.Region.

Working again....so I can only surmise that the @razor model isn't too keen on properties being on sublevels when used for the selected item in a dropdown list.