Pages

Saturday, 2 July 2016

Importing Custom Libraries in Dart

After several months of using Dart to develop virtually real solutions, I started experimenting with class object programming. I have used classes extensively in another favourite programming languages such as Free Pascal, so it was only a matter of time until I started implementing these in Dart.

In my code, I initially had the custom class definition together with the main application code. This simplified understanding and trialing the concepts involved. As the class definition increased both in size and complexity, it made perfect sense to move out the class definitions into a dedicated class file.
This was relatively easy and presented no challenges in having the resultant application code function as was required. In other words, the importing of the new class definition file into teh main code was rather straightforward.

Invariably the class definitions continue to evolve and adapt to the application development requirements of one or more projects. I had started to create two additional class, each code in its own .dart file. It should go without saying on the advantages of breaking class definitions into their own files:
  • Object oriented paradigm.
  • Inheritance
  • Interface



All went well in creating the new class definition files when I suddenly could not proceed testing teh code due an unfamiliaar error in the editor:
The imported libraries 'libAdministration.dart' and 'libAdminReports.dart' cannot both be unnamed
Well, firstly I could not make sense of the message. Secondly, I did not know how to resolve this clearly phrased message, though a mouthful in some way. Thirdly, I asked myself - should I perhaps place all the class definition back into the main doe file?

Giving up easily is not in my nature, so after searching in google for a possible solution, I was excited that the solution was rather simple: at the top of each library file to be imported, add the following:
library libraryname;
 Thereafter my custom class definition file imports work without any problems.

Monday, 4 January 2016

Raspberry PI Temperature Sensor

The Raspberry Pi (PI) is pretty nifty little device. I have done various programming projects with it over the past seven to nine months. A few days ago a had a strong drive to experiment with the PI's GPIO interface and connect a heat sensors to measure temperatures.

This project comprises of three distinct phases namely: a) Electronics Circuitry, b) Software Development and c) Testing and Integration.

a) Electronics Circuitry (EC): The EC phase entails the assembly of the temperature components as a complete unit onto the breadboard. One of the Dallas sensor is placed directly on the breadboard, The second sensor is wired on the other end of the ethernet cable.
b) Software Development (SD): The SD phase entails preparing the suitable software application to control and manage the EC assembly. Various option exist which languages could be used to develop an application to read, process and store temperature readings. Python is an excellent choice and probably the easiest. However, I am Pascal kind of person both on Windows and Linux operating systems.
Bear in mins that in the absence of any form of a software package, the PI is not able to make any temperature readings, even if the sensors are connected correctly to the GPIO pins. My SD environment is as follows:
  • Free Pascal compiler in CLI mode to develop an executable that takes readings from the senors.
  • Sqlite 3 database to store the temperature readings as per the FPC CLI program.
  • A cron job to run the FPC program every 5 minutes.
c) Testing and Integration (T&I): TI in essence means integrating the EC and SD components into a single functional module.
My bill of materials was:
  • 1x Raspberry Pi 2 B (including PSU, card and box).
  • 2x Dallas DS18B20 temperature sensors.
  • 1x 4K7 Ω resistor.
  • 1x Breadboard.
  • A dozen male to female jumper wires.
  • 1x 3m long UTP ethernet cable.

The final assembly is illustrated in the image below:
Raspberry PI with Temperature sensors on a Breadboard
The sensor on the ethernet cable is temporarily placed outside a room to measure the outdoor temperatures while the breadboard is placed indoors. Below is an extract form the temperature log file (csv formatted with the temperature in celsius degrees being the last 3 characters): 
2016-01-04 00:00:01,28-000006df1322,27.5
2016-01-04 00:00:02,28-0000059a01ed,22.7
2016-01-04 00:05:02,28-000006df1322,27.5
2016-01-04 00:05:03,28-0000059a01ed,22.6
2016-01-04 00:10:02,28-000006df1322,27.5
2016-01-04 00:10:03,28-0000059a01ed,22.6
2016-01-04 00:15:02,28-000006df1322,27.5
2016-01-04 00:15:03,28-0000059a01ed,22.4
2016-01-04 00:20:02,28-000006df1322,27.4
2016-01-04 00:20:03,28-0000059a01ed,22.4
The listing below comprises the complete Pascal program used to read and store temperature readings into  Sqlite 3 database table:
program tempsensors;

{$mode objfpc}

uses Classes, SysUtils, db, sqlite3ds;

const appVersion = '0.1';

var sl       : TStringlist;
    rows     : integer;
    temp     : string;
    slDevs   : TStringlist; //devicesList
    i        : integer;
    devCount : integer;
    devFile  : string;

    logOutput : string;

    dsTempLog : TSqlite3Dataset;
    sqlstr  : string;

function parseTemperature(tempStr: string):string;
{*
 Function parses and returns a temperature value from the given string tempStr.
 tempStr = temperature string.
*}
var
    x : integer;   //index used to parse temperature value in a string.
    c : integer;   //temperature reading in celsius.
    f : real;      //temperature value / 1000.

begin
 result := '';

 if tempStr = '' then
 exit;

 x := pos('=', tempStr) + 1;

 begin
   c := strtoint(copy(tempStr,x,5));
   f := c/1000;

   result := floatToStrF(f,ffFixed,2,1);
 end;
end;


function logDateStamp:string;
var current : TDateTime;
begin
 current := now;

 result := formatDateTime('YYYY/MM/DD hh:mm:ss', current);
end;


procedure logToTextFile(aFn, aLogdata: string);
var fh : TextFile;   //filename to log to.
begin
 assignFile(fh,aFn);

 if not fileExists(aFn) then
 begin
   rewrite(fh);
 end
 else
 begin
   append(fh);
 end;

 try
   writeln(fh,aLogData);
 finally
   closeFile(fh)
 end;
end;

begin {begin of main program.}

// writeln('Script started by user.');
// writeln('Hello Pascal on Raspberry Pi.');


 //Exit this program if prescribed file does not exists:
 if not fileExists('/home/pi/progs/pascal/sensorDevices.txt') then
 begin
   writeln('Alert: Error in opening the sensor devices descriptor file.');
   exit;
 end;


 //Load into the devces stringlist a text file that contains declared sensor devices:
 slDevs := TStringlist.create;

 dsTemplog := TSqlite3Dataset.create(nil);
 dsTemplog.Filename   := '/home/pi/progs/pascal/templog.db';
 dsTemplog.Tablename  := 'temps';
 dsTemplog.PrimaryKey := 'id';

 try
   slDevs.loadfromfile('/home/pi/progs/pascal/sensorDevices.txt');

   devCount := slDevs.count;

   //Declare String list that will hold conrtents of sensor device w1_slave file contents:
   sl := TStringlist.create;


   try
      //Iterate through each device file name
      for i := 0 to devCount-1 do
      begin
         logOutput := '';

         devFile := '/sys/bus/w1/devices/' + slDevs[i] + '/w1_slave';

         if not fileexists(devFile) then
         begin
            writeln('Alert: Sensor device system file not found.');
            exit;
         end;

         //Load fiel contents of w1_slave file to extract the temperature:
         sl.loadfromfile(devFile);

         rows := sl.count;

         //Display temperature log reading if prescribed conditions are met, else display error message.
         if (rows = 2) and (pos('YES', sl[0]) > 0)  then
         begin
            temp := sl[1];
            writeln('Processing  device with index : [' + inttostr(i) + ']. Row count: ' + inttostr(rows));
            logOutput := logDateStamp + ',' + slDevs[i] + ',' + parseTemperature(temp);

            writeln(logOutput);

            try
{               sqlstr := 'insert into temps (date_log,device_id,temp) ' +
                         'values ' +
                         '(%f, ''%s'', %f)';
}

               //Construct the SQL insert statement
               sqlstr := 'INSERT INTO temps ' +
                         '(date_log,device_id, temp) ' +
                         'VALUES '+
                         '('''+logDateStamp+''','+''''+slDevs[i]+''','+''''+parseTemperature(temp)+''')';

//               dsTemplog.sql := Format(sqlstr, [logDateStamp, slDevs[i], parseTemperature(temp)]);
//               dsTemplog.sql := Format(sqlstr, ['2016-01=03 10:00:00', slDevs[i], '28.0']);
               dsTemplog.sql := sqlstr;
               dsTemplog.ExecSql;
            except
              writeln('Alert: Error in inserting data to the DB table with sql statement:');
              writeln(sqlstr);
            end;

            logToTextFile('/home/pi/progs/pascal/tempreadings.log',logOutput);
         end
         else
         begin
            writeln('Alert: Temperature string not found');
          end;
      end;
   finally
      sl.free;
   end;
 finally
   dsTemplog.free;
   slDevs.free;
 end;

end.
Going forward my intention is to:
  • Duplicate the project on a Raspberry PI Zero.
  • Add a dozen more DS18B20 temperature sensors.
  • Provide environmental proofing of the sensors.
  • Develop a web portal that accesses the Sqlite table for display and control capabilities.

Sunday, 3 January 2016

A Web Portal in Dart

In my previous post I shared my initial views on programming with Dart. To date I have developed a few projects, both in the private and business realm, and my experiences have been extremely favourable.

The most recent projects entailed a web portal for company. Considering that my Javascriot/JQuery has never been my strength, Dart evolved as a natural substitute for the limited PHP/JQuery skills set I had. The high level features of the web portal are:

  • Web technology based portal.
  • Dart front end.
  • JSON based back end integration.
  • User login based access control.

Web Portal in Dart

Needless to say, the back end server is developed in PHP and primarily serves to interface the portal to a MySQL database by means of JSON. However, in the future the PHP implementation will be replaced by either a Golang or Dart version.

Below is a code snippet used to render the most recent articles on the portal:
void xhrFetchJson_articles(HttpRequest request, String aContext, String aUrlAction) {
  /* 
   * Function is used to list actual imagery content as retrieved from a database table.
   * 
   * 1. This function initiates an HttpRequest to fetch json data from a PHP backend script.
   * 2. The JSON data is decoded in a dart Map structure to enable the relevant fields.
   * 3. The relevant MAP structure fields are the used to generate a table that includes an edit buton.
  */  
    
  print("[Debug] Evoked function rxhrFetchJson_articles");
  print("[Debug] Function argument aContext   = " + aContext);
  print("[Debug] Function argument aUrlAction = " + aUrlAction);
  print("[Debug] ---------------End.");

  if(request.status == 200) {
    print("[Debug] function xhrFetchJson_articles Data fetched from http server (200).");
    
    if(request.responseText == "zero.rows.found"){
      
      window.alert("Alert: No content found.");
      querySelector("#output").appendHtml(gallery.displayGallery_WIP("images/contentnotfound.png"));
      
      return;
  }
  
  //Proceeed if valid content has been returned:
    
    //Debug messages to print responsetext received from the xhr function: 
//      print(request.responseText);
    
    querySelector("#output").text = "";

    JsonObject data = new JsonObject.fromJsonString(request.responseText);    
    
    String aArticleAuthor   = "";
    String aArticleTitle    = "";
    String aArticlePubDate  = "";
    String aArticleText     = "";
    String aArticleImageUrl    = "";
    
    //Loop through the JSON data instance and creaye a link navigation menus:
    for(int i = 0; i < data.length; i++) {
      aArticleAuthor    = data[i].author.toString();
      aArticleTitle     = data[i].title.toString();
      aArticlePubDate   = data[i].date_pub.toString();
      aArticleText      = data[i].article_text.toString();
      aArticleImageUrl     = data[i].url_image_intro.toString();
      
//      displayNews_Content(String aTitle, String aAuthor, String aPubDate, String aArticleText, String aFilename) {

      querySelector("#output").appendHtml(displayNews_Content(aArticleTitle,
                                                              aArticleAuthor,
                                                              aArticlePubDate,
                                                              aArticleText,
                                                              aArticleImageUrl));
            
    }
    
  }    
}
In comparison to other web oriented development environments I have used before, I really found that Dart is a very capable, suitable  and powerful in its ability to manipulate the HTML DOM and processing of JSON interfaces.

It may be  noteworthy to mention that 3rd party frameworks are not incorporated into the web application. However, I did make use of a 3rd party JSON Object library as indicated below:
import 'dart:html';
import 'package:json_object/json_object.dart';
//import 'dart:convert';
//import 'nlc_serverroom.dart' as server;
import 'nlc_lib_contacts.dart' as contacts;
import 'nlc_lib_galleries.dart' as gallery;
import 'nlc_lib_pbx.dart' as pbx;
import 'nlc_lib_assets.dart' as assets;
import "fn_authentication.dart" as libAuthenticate;
import 'trials.dart' as trial;
import 'package:intl/intl.dart';

Sunday, 12 April 2015

Coding in Dart

The Dart programming language was introduced around October 2011. Last year in July 2014 I downloaded the stable Dart SDK version 1.8.3 to experiment with this relatively new language. From the onset, let me list the key objective of Dart as espoused by Google:
  • Dart is a structured language with optional typed capability.
  • Dart is targeted at both client and server side development.
  • Dart is an alternative to JavaScript coding.
I have successfully developed a couple web applications where the browser side is Dart and the server side is PHP. I have tested several features such as Json, MySQL and an Http server. The image below (I could not figure out how to insert formatted text) is a screenshot of the entire code for sending an email using my Google credentials. It works flawlessly, though I still have to test send an email with an attachment or two:


Dart Editor



You may have recognised the similarity of the Dart editor to Eclipse, particularly if you have used Google's SDK editor for native Android development.

In terms of serve side development, Dart's inherent asynchronous feature can lead to some unexpected results. A good grasp of the "Futures" feature will go a long way in writing code that meets your expectation in the sequence of event that should result in predictable output.

Google for dartlang and explore the suitability of Dart in your new projects - even if it for experimental purposes only.

Thursday, 9 April 2015

Cellphone Ownership - A History Through Time

I have taken a decision to be less agnostic about cell phone handset brand names. There used to be time when a brand name of a device equated to a specific value proposition in the sense of: quality, sophistication, productivity and value added pricing if there ever is such a thing.

Just half over 2014 I opted to take ownership of an LG based cell phone handset. This was the first time I deviated from an established norm in terms of traditional cell phone brands.

In January 2015, I had an urgent need for a dual SIM cell phone device and voila, a Hisense device it was.
Ericsson T68

Allow me to contextualise the the bias of brands I have owned since around 1995:The chronology of cell brands I have personally owned since around the mid 1990s is listed below:

  • 1995/6: Siemens S3
  • 2001: Ericsson T68
  • 2002: Siemens SX1
  • 2003/4: Nokia 9300i
  • 2006/7: Nokia E90 Communicator
  • 2008: HTC Desire
  • 2014: LG G3
  • 2015: Hisense HS-U939
Needless to say, up to 2 years or so, I have had an illustrious yet conservative interaction with a limited range of cell phone handsets. The conservative aspect is the bias towards eurocentric based cell phone OEM manufactures. However, from 2008 onward, the bias diametrically swung towards the OEMs in the Far East.

My choice of handsets is usually very much informed by the need to be able to develop custom applications to address specific I have. Since I never liked the Symbian development environment, the arrival of the Android OS environment was a welcome introduction. I started learning Java in earnest (and probably with focused passion) in order to develop a few native applications. That was certainly a lot of fun.

LG G3

In the near future I am keen to "experiment" with a Microsoft based cell phone device. I still find the Windows 8 inspired rectangular shapes rather peculiar, but the Microsoft hardware seems to have an appealing attraction worth interrogating.

Similarly and for totally different reasons I might consider an Apple based device to learn to appreciate what the fuss is about these iOS devices. I am owning the first model iPad to date and quite frankly, I have a huge challenge making it meet my basic requirements - even the HTC Desire is such a more useful and pleasant device to use!

I have not yet ventured into neither Blackberry nor Samsung based devices. I have no intention to do so in the long term (next ten years) though that is certainly not a decision cast in stone.

Wednesday, 7 May 2014

Exploring The Raspberry PI

Taking ownership of a Raspberry PI-B (RPI) had eluded me for far too long since it was launched early 2012. I had read a lot about this diminutive device fitted out with an ARM processor, HDMI, USB ports, an ethernet port to mention a few.

Since the RPI runs primarily (if not almost exclusively) on a Linux based operating system, prior knowledge of basic Linux is of immense benefit considering that:
  • Remote SSH connectivity allows for operational flexibility.
  • Installation of new applications extends overall features.
  • Headless server configuration mode is the strength of the device

Warning: The RPI being a Single Board Computer (SBC) and dressed out as such, requires prudent handling. All due care must be exercised to avoid damage through unintended forceful handling, unforeseen antistatic discharge, accidental short-circuiting of pins and any other exposed components.

The installation procedure is briefly listed below:
  • Download Raspbian Wheezy.
  • Download Win32DiskImager and install it (Windows OS based procedure).
  • Use Win32DiskImager to burn the Raspbian image to an SD card (I used an 8GB card).
  • Optionally: connect RPI to a monitor via an HDMI cable.
  • Optionally: connect a wireless dongle for a keyboard and mouse (this allows for 1x USB port to remain free).
  • Optionally: plug in an ethernet cable into the ethernet socket.
  • Insert the SD card into the RPI slot.
  • Plug in the micro USB power adapter connector.
The RPI then lights up, commences and completes the boot procedure. The boot procedure can be followed visually if the monitor is connected and switched on.

Raspberry PI - B


There is a sense of achievement when the monitor confirms a functional RPI, ready awaiting you to take control over it. From there on it is really about experimenting with the various configuration options available.

One is tempted to undermine the capability and performance of RPI, however, within a few days from installing the RPI, I managed to configure a LAMP environment. I had strange problems installing the necessary packages only to find that my 3G based broadband connection was too weak and erratic. After moving to another location, the installation proceeded seamlessly.

Presently, the RPI LAMP system has temporarily replaced the erstwhile PC based LAMP server platform. I am strongly considering a permanent arrangement at a later stage once the temporary setup has been comprehensively assessed and evaluated.

The RPI has proven to be a device that is certainly capable and easy to use - a worthwhile investment indeed.

Thursday, 27 February 2014

Programming As A Hobby

The word "programming" generally refers to the activity of writing software code for use by some form of a computing device. Allow me to share how I became introduced to programming.
If you are looking for:
  • A definition of a programming language,
  • A comparative assessment of programming languages,
  • Introduction to programming,
  • Sample codes to solve that tricky code that simply refuses to run correctly,
  • A doctoral thesis on computer languages,
  • A flame war on languages,
then this post will not meet your expectations.

I was introduced to programming in my last year of high school many years ago in 1989, mainly out of curiosity more than anything else. At that time, tinkering with electronics gadgets (transistors, resistors, capacitors, bread/vero boards, soldering iron and so on) was my formal hobby.

At high school, my first introduction to a programming language was some variant of BASIC - to be honest, I had no clue what I was supposed to do with that so called "simple" language.

I do grasp the concept of languages - that is spoken languages I am referring to. I myself speak a couple of languages, others better, Other languages I write better and of course, others are so foreign both in terms of writing, reading, speaking never mind trying to listen and understand.

Learning a programming language, though in many respects akin to learning a spoken language, has a particularly invisible, yet effective barrier that I call the Concept of Implied Systematic Logic (CoISL). Without going into details of CoISL, have you ever had someone remark to you something to the effect of:

"...This is logical...", "...Based on common sense..." or "...You  should have known that if x = x + 5 is equal to x + 5..." 

After my high school I studied electrical engineering (light current) as it was called then. Light current implied focus on electronics, digital systems and telecommunications. It was in the same year when I started the engineering course that my real interest in programming developed. We had a module on MS-Basic. It was now less arcane then when I saw it in high school. There was a lecture who introduced the class to True Basic - what a phenomenal variant of Basic it was. I was then able to draw sine waves and other graphics on that poor little CRT monitor.

Well, it did not take long and I started to learn Pascal using the Turbo Pascal compiler. That was even more phenomenal for reasons I do not remember now and probably are less important as well. Post Turbo Pascal I was introduced to Borland Delphi 2 at a store when I was inquiring about Visual Basic. I opted for the Borland IDE and eventually upgraded to Delphi 3 followed by Delphi 4. Now I primarily use Free Pascal due to its strong similarity to traditional Delphi.


Well the rest is history. Over the past years I have learned other languages such as Java, Ruby, PHP and C#. I have also dabbled with C/C++, Perl and Python. C/C++ is still useful when programming up microcontrollers. It would be misleading on my part if I did not mention HTML, CSS, JQuery and JavaScript - and yes, there was a time when I thought and believed that JavaScript was the same as Java. I learned very quickly how ignorant. Trust me, that believe was quickly and quietly discarded.

Of course, I have made it a point to learn SQL, it is immensely beneficial  for database administrations. I can now confirm that CoISL is not an issue for me any longer.