Skip to content
Lieven Hollevoet edited this page Sep 22, 2014 · 1 revision

Table of Contents

New Class Structure

How to add comments

Wiki markup: ``// Please add your comments in italics, with your name - Matt //``

results in: //Please add your comments in italics, with your name - Matt//

Overview

This is a live design and discussion document for the revamp of the current mh class structure. Please feel free to edit this text and add comments. The goals of this effort are:

  • Moving all non core functionality from into libraries
  • Easier integration of non X10 hardware and objects
  • Pluggable functionality

High Level View

There will be three class trees, each with its own base class:

  • - providing low level access to hardware such as serial ports, USB ports and sockets
  • - providing basic item functionality, representing a controllable object in the real world environment
  • - providing protocol specific functionality such as parsing received data, grouping commands and preparing data for transmission

mh/bin/mh

Things to rip out / place into library / class files:

  • dealing with serial data
  • dealing with socket data
  • any hardware specific code
  • display / response code (not sure about these two)
All hardware interfaces must be derived from Device_Interface. All Device_Interfaces will be polled through a standard API to check for new data.

Class Trees

Interface.pm

Interface.pm will define the basic API for accessing hardware. Functionality includes:

  • opening and closing devices
  • reading / writing data
  • checking for new data being available
Sample children of Interface.pm:
  • Serial_Interface.pm - adds IOCTLs specific to serial ports (setting baud rate is an example)
  • USB_Interface.pm - adds O/S specific support for manipulating USB ports. Linux support will likely be much easier to implement as we will leverage libusb which creates device nodes. It is currently unknown how we will support Windows based USB devices.
  • Socket_Interface - allows connection to remove daemons via TCP, UDP or UNIX sockets.
Example for CM11

Interface > -> Serial_Interface (CM11s are connected via serial ports) >> -> CM11

When a new CM11 object is created, it will register with , letting it know that CM11s provide "X10" functionality. This is an important step, as when X10_Items are created later on, they will ask for a list of devices that provide "X10". See the Item stuff below for more info.

//I wonder if interfaces should register for the type of polling (or frequency) they want. So rather than mh poll every interface on// //every pass of the mh loop mh will be able to make that distinction based what the interface expects. - SteveG.//

//You can register for 'polling' by adding your check_for_data routine to the &::MainLoop_pre_add_hook here's the code I use in my Insteon_PLU.pm ://

code format="perl"

    &::MainLoop_pre_add_hook(\&Insteon_PLU::check_for_data, 1);

code

This allows MH to poll your device each time through the program loop. Note that the name of the routine is not important. You could call it poll and pass that to the MainLoo_pre_add_hook method and it will still be called.

I hope to add more details later. Right now I'm trying to extend the Device_Item class. Linux HA

Protocol.pm

Protocol.pm will define the basic API for protocol specific processing:

  • processing received data
  • preparing data for transmission
  • grouping commands
  • preparing status reports for devices - these can either be remembered states or true polling of current status if supported by hardware
Sample children of protocol.pm:
  • X10_Protocol.pm
  • Insteon_Protocol.pm
  • UPB_Protocol.pm
Example for CM11:

Protocol > -> X10_Protocol >> -> CM11

As can be seen, from this chain and the example interface chain, CM11 @ISA (Serial_Interface, X10_Protocol) as it is a serially connect X10_Interface.

Item.pm

Item.pm will define the basic API for manipulation of real-world objects:

  • defining relationship between $states and what is now termed $id, which may need renaming. When you , this is what translates 'on' into the correct format
  • requesting a copy of a valid Interface object from and storing it as a data member (likely to be called . I.e. an X10_Item will be requesting a Interface object that provides "X10" and will store a copy of it in }
  • registering itself with its enclosed Interface so that the Interface knows for which Item a received data stream represents
  • registering with the table system in mh/bin/mh with the number of parameters, their type, and regexes to validate data entery. I.e. X10_Items need an X10 identifier (e.g. H12) and an optional interface name (e.g. cm11). This will allow the table system to automagically know how to create a form letting people add new items.
  • keeping a global list of all known $state <-> $id relationships
Some children of Item.pm:
  • X10_Item
  • Insteon_Item
  • UPB_Item
Example for X10_Sensor:

Item > -> X10_Item >> -> X10_Sensor

Data Flow

Setting an object

  • The Item will have its "set" method called with a state (e.g. X10_Item set to 'on')
  • The Item will translate the state to the correct data stream (e.g. 'on' translated to 'B1BJ')
  • The Item will call the "set" method of its enclosed Interface with the correct data stream
  • The Interface will use its derived Protocol to process the string (e.g. 'B1BJ' likely untouched)
  • The Interface will then do device specific manipulation of the string (adding headers, checksums, etc.)
  • The Interface will then send the data out the physical port

Receiving data

  • In every loop, will ask all known Interfaces to check for new data
  • When new data is received, the Interface will do device specific parsing of the data (checking/removing checksums, etc.)
  • The Interface will then do Protocol specific manipulation of the data
  • The Interface will then check its list of known data stream / registered Items for a match with received data
  • If the Interface finds a match, it will pass the data onto the correct Item
  • If the Interface does not find a match, it will ask Item.pm to find a match within its global list of $state <-> $id relationships.
Clone this wiki locally