Introduction: Hp Jetdirect Home Automation Device.

About: computoman.blogspot.com Bytesize articles instead of a trilogy in one post.

Did not contact X-10, but I did contact Insteon about getting some demo units to help sell their products. Since they turned me down, I will use the HP Jet directs instead. The jet directs can control a multitude of devices with minimum additional hardware cost.You should be able to get he jet directs at a fraction of the cost of the Insteon equipment.  What I wanted to do is to reuse old HP Jet directs with parallel ports for home automation. With the units that have three parallel ports instead of one. you can be a real powerhouse for control. This instructable is for techie oriented computer users who have done work with the parallel port.

Note: I will be updating this instructable as we go along. Still needs some polish. I do not condone Ebay or it's sellers, but you can get the jet directs for a reasonable price compared to insteon or X-10.

Note: We are going to experiment with an Airlink unit also.

Step 1: Wiring.

For each port, you will need a 74ls04 or equivalent. A cmos 4009 (inverting)  dip might works also. You will have to adjust the wiring set up though. if you made the no solder break out cable (https://www.instructables.com/id/Mini-parallel-port-break-out-cable/ or https://www.instructables.com/id/No-solder-parallel-port-break-out/) , it will also be perfect for this project.

if you use a logic tester pin 9 on the 7404 shoud be high. (red)
if you use a logic tester pin 8 on the 7404 shoud be low.  (green)

Note: try this at your own risk. Older jetdirects may need a latch (74ls373) to hold the data bits.I will post an additional circuit to do this once I get it working and tested. On the test unit, we are using pin 1 from the db25 for +5.

Step 2: Interfacing.

There are already a zillion instructables on how to interface digital ports with external electronic devices. Did not add that part as  to not  reinvent the wheel. but I will later add an example of using gmail and your server to control the ports from outside your network.

https://www.instructables.com/id/External-device-control-ie-coffee-machine/

Preview:

(Exerpt from tweeting with linux)

You can also grab your gmail and save it as ascii and do the same sort of thing. It will be more private and you do not have to use twitter.

You could use the following as a starting point.

getgmail.sh
[code]
username="Yourusername"
pword="Yourpassword"
curl -u $username:$pword --silent "https://mail.google.com/mail/feed/atom" | tr -d '\n' | awk -F '<entry>' '{for (i=2; i<=NF; i++) {print $i}}' | perl -pe 's/^<title>(.*)<\/title><summary>(.*)<\/summary>.*?<name>(.*?)<\/name>.*$/\n$3\n\t$1\n\t$2/' >> currentmail
[/code]

Make it executable.
$ chmod +x getgmail.sh

Have it check for mail every hour
$ crontab -e

*  */1  * * * /home/eddie/bin/getgmail.sh

gedit/vim/nano currentmail

currentmal:
[text]
me
    inre. project.
    Marie: We have decided to go ahead with the project. Good luck
[/text]

Step 3: MS .NET Net Code.

Do not have an ms windows machine that can run this but you are welcome to try the code.
Call the output method specifying the port as ipaddress:port and the output value:

Here is the simple c#.net class which I use to access the print server. Say you wanted to turn on pins 2, 4 and 6. Combine the pin values

Pin2=1
Pin3=2
Pin4=4
Pin5=8
Pin6=16
Pin7=32
Pin8=64
Pin9=128

Required value to tun on pins 2, 4 and 6 is 1+4+16=21


(Most print servers use tcp port 9100, multi port JetDirects use 9100 for port one, 9101 for port two etc)

IpPortAccess.Output(192.168.1.10:9100,21);

using System.Net;
using System.Net.Sockets;
using System;
using System.Collections.Generic;
using System.Text;

namespace PowerControl
{
class IpPortAccess
    {
        public static void Output(string port,int value)
        {
            string[] ipport = port.Split(new char[] { ':' });
            string _ip = ipport[0];
            int _port = Convert.ToInt32(ipport[1]);
            Socket soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            soc.Connect(_ip,_port);
            byte[] sendData = new byte[1];
            sendData[0] = Convert.ToByte(value);
            soc.Send(sendData);
            soc.Close();
        }
    }

Step 4: Php Code.

Php code for server. Note if the wiring is not correct you will  get and error.

[code]
<hr>
<center>
<h2> Jet direct control page <h3>
</center>
<hr>
<br>

 <?php

/***********************************************************************************
 * Network Something - php script.
 * Original idea from Praxis Doktor Andy
 * (http://www.doktor-andy.de/joomla/index.php?option=com_content&task=view&id=40&Itemid=52)
 * This script was created by Jason Hensler (www.colddarkness.com)
 * This script is released under the GNU/GPL License.
 ********************************************************************************/


 // error_reporting ( E_ALL ); //turn on error reporting for debugging this can be commented out

 /*if(isset($_POST[&#39;Submit&#39;])) {
 *      echo "<pre>";
 *      print_r($_POST);
 *      echo "</pre>";
 *}
 */
        //generate user input form
 ?>
 <form id="form1" name="form1" method="post" action="">
 <p>Bits to send to print server:<br>
 <label><input type="checkbox" name="bit8" value="true" /></label>
 <label><input type="checkbox" name="bit7" value="true" /></label>
 <label><input type="checkbox" name="bit6" value="true" /></label>
 <label><input type="checkbox" name="bit5" value="true" /></label>
 <label><input type="checkbox" name="bit4" value="true" /></label>
 <label><input type="checkbox" name="bit3" value="true" /></label>
 <label><input type="checkbox" name="bit2" value="true" /></label>
 <label><input type="checkbox" name="bit1" value="true" /></label>
 Reset all <label><input type="checkbox" name="resetall" value="true" /><label>
 <br>
 IP: <input name="ip" value="192.168.1.98">
 <input type="button" value="default" onclick="document.form1.ip.value = '192.168.1.98'"><br>
 PORT: <input name="port" value="9101"><br>

  <input type="submit" name="Submit" value="Send" />
  <input type="reset"/>

 </form>
<br>
<br>
<hr>
Messages:
<hr>
<br>
<?
 if(isset($_POST['Submit'])) //check if user submitted form
 {
 //if user has submited data
 // The raw port number for the print server
 $service_port = $_POST['port'];
 // The network address of the print server
 // This can be an ip address or a network name
 $address = gethostbyname($_POST['ip']);

 echo " ";
 echo "Creating socket...";
 $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); //create the socket or fail
 if ($socket === false) {
 echo "<br><b>socket_create() failed: reason: " .
 socket_strerror(socket_last_error()) . "</b>\n";
 die();
 } else {
  echo "OK.<br>";
 }
 echo "Connecting to print server: " . $address . "...";
 $result = socket_connect($socket, $address, $service_port); //connect to the print server
 if ($result === false) {
  echo "<br><b>socket_connect() failed.\nReason: ($result) " .
 socket_strerror(socket_last_error($socket)) . "</b>\n";
  die();
 } else {
 echo "OK.<br>";
 }
 $out=0;
 //check to see if which boxes have been checked and add thier bit value to $out
 // bit num: 8   7  6  5  4  3  2  1
 // value:  128 64 32 16  8  4  2  1
 //if(isset($_POST['resetall']){
 //    $out = 0;
 //}
 //else{
      if(isset($_POST['bit8'])) {
           $out +=1;
      }
      if(isset($_POST['bit7'])) {
           $out += 2;
      }
      if(isset($_POST['bit6'])) {
           $out += 4;
      }
      if(isset($_POST['bit5'])) {
           $out += 8;
      }
      if(isset($_POST['bit4'])) {
           $out +=16;
      }
      if(isset($_POST['bit3'])) {
           $out += 32;
      }
      if(isset($_POST['bit2'])) {
           $out += 64;
      }
      if(isset($_POST['bit1'])) {
           $out += 128;
      //}
 }
 if(isset($_POST['resetall'])){
    $out = 0;
 }
 echo "Sending to print server...<br>";
 // since php does not have byte type varables and wants to send ascii over sockets
 // we use chr($out) to send the char with the matching value of the value we want to send
 socket_write($socket, chr($out), strlen(chr($out)));
 socket_close($socket); // close the socket
 echo "Sent!<br>";
 }
 ?>
[/code]

Step 5: Hp Hacking Code (linux).

Linux

[root@balrog root]# gcc -o hphack hp.c
hp.c:28:12: warning: multi-line string literals are deprecated
[root@balrog root]# ./hphack 192.168.1.14  "Irongeek"
HP Display hack -- sili@l0pht.com
Hostname: 192.168.1.14
Message: Irongeek
Connecting....
Sent 54 bytes
[root@balrog root]#


-------------------------------------------------------------------------------
See atachment.

Step 6: Hacking Code (MSwindows).

MsWindows:

C:\>hpnt npi769e71 "Irongeek"
HP Display hack -- sili@l0pht.com
Hostname: npi769e71
Message: Irongeek
Connecting....
Sent 54 bytes

C:\>hpnt 192.168.1.14 "Irongeek Also"
HP Display hack -- sili@l0pht.com
Hostname: 192.168.1.14
Message: Irongeek Also
Connecting....
Sent 59 bytes

C:\>

---------------------------------------------------------------------------------
Must be compiled under mswindows.
See attachment.


Attachments

Step 7: Yet Another Way That Might Work.

This step by step instruction describes how to setup a HP Jetdirect 170x print server so that the 8 bits output can be controlled by a user made program
or from a PHP script.

To make a fresh start you can factory reset the Jetdirect 170x.

Procedure as follows:

1. Unplug the power to the Jetdirect.

2. Press and hold the 'Test' button while plugging the power back in for 5 seconds.

3. The Jetdirect should be reset now and is configured by default to obtain an IP address automatically.

Take a DB25 male connector and connect pins 1, 10, 13 and 15 together.

Plug in the DB25 connector.

Start your web browser and go to the Jetdirect's web interface by typing its IP address in the location bar. (e.g. http://192.168.1.xxx).

Give the Java engine some time to start.

The printer status should show 'On-Line' - now you know your DB25 connector is soldered well.

Click Administration and go to the Configuration tab and tick the Snmp checkbox.

Enter 'private' (without the quotes) as New Set Community Name. This community name functions as a password, we will need it later on.

Press Apply and wait for the device to reset.

Now we need to change a (hardware) register inside the Jetdirect.

It is the npPortCentronicsHandshaking register which controls handshaking between printer and Jetdirect.

To accomplish this you need a tool that can send (and receive) SNMP commands.

A simple tool will do. E.g. SNMPGetSet.exe, obtained here: http://www.fileguru.com/SNMPGetSet/download

Start the program and type the Jetdirect's IP address. Click SNMP Get All. This should give a result of 3 out of 5.

DO NOT use this program when you're in a hurry - you might screw up your print server!!!!

Registers are read and written by using Object Identifiers (OIDs) - it is the dotted numerical strings you see.

The npPortCentronicsHandshaking register is addressed by OID 1.3.6.1.4.1.11.2.4.3.13.4.0 .

Copy this OID to the lower panel of the program to do a Selective SNMP Get.

Click SNMP Get and note the returned value.

We need to set this register value to '2'.

Type '2' as value and click SNMP Set. The value will be written using the Write community name (top right) as password.

Give the Jetdirect some time to store the new value. It is retained after a power cycle.

Now you are ready to control the eight bits output of your print server by PHP or any other home made program.

Use TCP port 9100 to write your bytes to.

Step 8: Yet Another Way That Might Work.