Announcing the "ST_Anything" Arduino/ThingShield Project

Dan,
Okay, all of that makes sense. I just did all of those things.
Now the only issue is that the multiplexer App will not let me finalize the connection with the Virtual Contact and the Arduino. I am able to choose the ST_Anything Doors device and the Virtual Contact Sensor input, however when I go to hit the done button it says “Oops! Looks like you need to double-check some inputs” in a red box at the top. Any ideas on why that is happening?
Once again thanks so much for your help! I really appreciate it!

Thanks,
Ryan

sounds like the smart app wants all 6 virtual devices, 4-virtual contact sensors AND 2-virtual door controls, plus the Arduino.

That all worked beautifully! Yes, you were correct about the smart app. My door sensors work great!
How hard is it to link the smart app with a virtual motion sensor? I tried to create one by modifying the code to active and inactive and motion commands. There must be something that I am missing. Have you created anything to connect motion sensors to virtual motion sensors? One motion sensor that I have hardwired is registering on the app through the arduino now I just need to link it.

@ryanscottgray

So, are you trying to connect multiple motion detectors to a single Arduino? Using the default ST_Anything_Doors code from my Github repo, a single motion detector should “just work” as that is exactly how I am using it currently. Any SmartApp that is “looking for” a device that implements the SmartThings “Motion Sensor” device capability will show the Arduino as an option and can be used directly. Same with the Temperature and Humidity Measurement capabilities.

If you want to use multiple motion detectors, you’ll need to modify numerous pieces of code, including the Sketch, Arduino Device Type, Multiplexer Smart App, and create a new Virtual Motion Detector Device Type.

Dan

Hey Dan,
Yes, I was successful in connecting a single motion detector to the Arduino and having it work great within the confines of the ST_Anything_Doors project. It did just work. Also it does register with SmartApps as you mentioned. I will have multiple motion detectors wired in to the Arduino eventually.
I can modify the code in the Sketch for more sensors. I was also able to modify the SmartApp to have an input for a Virtual Motion Sensor. I guess where I am confused is I am using the Virtual Contact code and changing the devices such as device.contact to device.motion, open and closed to active / inactive or motion/no motion. Basically I was just trying to use the Virtual Contact code and change the device names and other info.

I noticed that the multiplexer app has the code:
section(“Select the Arduino ST_Anything_Doors device”) {
input “arduino”, "capability.contactSensor"
So I tried to put:
input “arduino”, "capability.motionSensor"
directly underneath of it. It had an issue with that so I created another line and then on my phone it showed up with two selections to choose the Arduino.

I guess my main goal is to get the ST_Anything_Doors and multiplexer with the existing motion sensor, to talk to a virtual motion sensor just like it talks to a virtual contact.

My question is, can I just change the names of devices in the code to reflect what kind of device i’m using or is there extra code that I need to add because it is a motion sensor as opposed to a contact sensor?

I hope some of that made sense. I apologize for my lack of knowledge on coding.

Thanks,
Ryan

Quick Question about the whole project. What uses the MOST memory? If I remove the temp, lux, and water does that remove enough to add in 4 contact closures?

does temperature only take less than the temp+humidity?

Just trying to use an existing older arduino I have here instead of moving up to a pro.

I want to do garage door Activation along with open/close detection, Garage motion, service door open/close detect and another relay pulse to push the “rain delay” button on my sprinkler system. and possibly an outdoor motion detector on the back of the garage.

Will that be too much for an older ATmega328 or ATmega128?

Tim,

Check out my ST_Anything_Doors example in my Github repo. This example is very close to what you’re looking to do, and it runs fine on an Arduino UNO R3. I have this exact configuration running in my garage without issue.

  • 2 garage doors (1 contact sensor and 1 relay each)
  • 4 normal doors (1 contact sensor each)
  • 1 temperature/humidity sensor
  • 1 motion detector

Dan

1 Like

@Timgray I just did a quick check of size by “Device Capability” as your question made me curious as to which capability used the most Arduino memory. 2048 bytes of RAM goes very quickly!

Here’s what the Arduino Compiler says each uses in bytes:

  • Temperature/Humidity - 103
  • Illuminance - 63
  • Water - 57
  • Motion - 52
  • Contact Sensor - 49
  • Switch - 35
  • Alarm - 33

@ogiewon Do you know what it means if the door contact tile keeps flashing from open to closed when hooked up to an alarm? I got everything seemingly working when not hooked up to my alarm system and it reports a constant “closed” when pin 10 is connected to ground on the arduino but when I try to wire it to one of the zones on my alarm it just constantly changes from open to closed.

This is my alarm panel…
https://global.discourse-cdn.com/smartthings/original/2X/0/019eb2293e4ff55bb5edb188ed40f48f050be6c3.JPG

I was going to try to connect to the 4 zones at first then maybe attempt to wire to each individual door/window instead of a general zone but got tripped up when it kept flashing from open to close.

I think I figured it out, the alarm wires had resistors on them and I needed to tap the arduino in before the resistors to get it to work properly. Thanks for the project! Working well so far.

Glad to hear you got it working. Are you using an Arduino UNO or MEGA? Just curious.

Also, I made some improvements a few days ago to my SmartThings ThingShield library. You may want to grab the latest version as it behaves better using the latest Arduino IDE versions.

Thanks I updated the library last night. I’m using an UNO and the ST_Anything_Doors sketch. Hoping to get about 13 door/window contacts working and 1 motion sensor. Not sure if it can handle all of that but will post back with an update.

I think SmartThings would be very wise to consider buying @ogiewon’s libraries as a really good way to refresh the ThingShield product. The official Shield library isn’t bad, but has a few loose ends that haven’t been addressed since it was written years ago. Dan’s libraries add some great features while providing a better baseline.

3 Likes

Yep, Dan’s library is far better than the ST version.

3 Likes

Question… I don’t see anything that mentions how to add more sensors and change the names. I’m attempting to do something like this but not sure of everywhere that the names need to be changed:

In st_anything_doors.ino

//Window Pins
#define PIN_CONTACT_KITCHEN_WINDOW1  5
#define PIN_CONTACT_KITCHEN_WINDOW2  7
#define PIN_CONTACT_KITCHEN_WINDOW3  8
#define PIN_CONTACT_MASTER_WINDOW1   9
#define PIN_CONTACT_MASTER_WINDOW2   10
#define PIN_CONTACT_OFFICE_WINDOW1   11
#define PIN_CONTACT_OFFICE_WINDOW2   12
#define PIN_CONTACT_GUEST_WINDOW1    13
#define PIN_CONTACT_GUEST_WINDOW2    14


//House Door Pins
#define PIN_CONTACT_FRONT_DOOR       A1
#define PIN_CONTACT_KITCHEN_DOOR     A2
#define PIN_CONTACT_GARAGE_DOOR      A3
#define PIN_CONTACT_BEDROOM_DOOR     A4

and…

//Interrupt Sensors 
  static st::IS_Motion sensor1(F("motion"), PIN_MOTION, HIGH, false);
  static st::IS_Contact sensor2(F("garagesideDoor"), PIN_CONTACT_KITCHEN_WINDOW1, LOW, true);
  static st::IS_Contact sensor3(F("frontDoor"), PIN_CONTACT_KITCHEN_WINDOW2, LOW, true);
  static st::IS_Contact sensor4(F("backDoor"), PIN_CONTACT_KITCHEN_WINDOW3, LOW, true);
  static st::IS_Contact sensor5(F("kitchenDoor"), PIN_CONTACT_MASTER_WINDOW1, LOW, true);
  static st::IS_Contact sensor5(F("kitchenDoor"), PIN_CONTACT_MASTER_WINDOW2, LOW, true);
  static st::IS_Contact sensor5(F("kitchenDoor"), PIN_CONTACT_OFFICE_WINDOW1, LOW, true);
  static st::IS_Contact sensor5(F("kitchenDoor"), PIN_CONTACT_OFFICE_WINDOW2, LOW, true);
  static st::IS_Contact sensor5(F("kitchenDoor"), PIN_CONTACT_GUEST_WINDOW1, LOW, true);
  static st::IS_Contact sensor5(F("kitchenDoor"), PIN_CONTACT_GUEST_WINDOW2, LOW, true);
  static st::IS_Contact sensor5(F("kitchenDoor"), PIN_CONTACT_FRONT_DOOR, LOW, true);
  static st::IS_Contact sensor5(F("kitchenDoor"), PIN_CONTACT_KITCHEN_DOOR, LOW, true);
  static st::IS_Contact sensor5(F("kitchenDoor"), PIN_CONTACT_GARAGE_DOOR, LOW, true);
  static st::IS_Contact sensor5(F("kitchenDoor"), PIN_CONTACT_BEDROOM_DOOR, LOW, true);

I haven’t change all of the “kitchendoor” instances above yet. Is there a specific format I need to stick to? I’m not very familiar with how to code this. Does it need to have “Door” in it or can I change it to, “officeWindow1” etc…? And any other files that they need to be added to?

Thanks

@ogiewon Dan,

I added sensors to my garage door so I could use them to trigger the myQ refresh.

I have an issue and an enhancement suggestion.

The issue I have is the sensors bounce, so I get three updates everytime the state changes. Is there something I can do to prevent that?

The enhancement suggestion would be a way to delay the state change being reported to ST. Here’s the situation. the myQ app uses polling, which is unreliable and places a load on the mesh. They added the ability to trigger a refresh based on a contact sensor. The problem is that when the door starts opening, the sensor triggers, which triggers a refresh, but that refresh shows a status of “opening”. I’d like to wait 10 (or 15 or 20 - configurable would be cool) seconds so that by the time the refresh hits the ST hub, the door is “Open” and it then can run rules for open.

Thoughts?

Thanks.
-Todd

Todd,

Not sure which of my Arduino sensor classes you’re using, but I am guessing it is the ContactSensor?

If so, just read the top comment section of either the .h or .cpp file and you’ll see all of the optional arguments. Debounce is already built-in, as I anticipated this issue. You just need to increase the value from the default as you see fit for your application. Here’s a snippet of the comments from the Contact Sensor files.

//			  st::IS_Contact() constructor requires the following arguments
//				- String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
//				- byte pin - REQUIRED - the Arduino Pin to be used as a digital input
//				- bool iState - REQUIRED - LOW or HIGH - determines which value indicates the interrupt is true
//				- bool internalPullup - OPTIONAL - true == INTERNAL_PULLUP
//				- long numReqCounts - OPTIONAL - number of counts before changing state of input (prevent false alarms)

The two optional arguments (internalPullup and numReqCounts) default as follows:

	IS_Contact(const __FlashStringHelper *name, byte pin, bool iState, bool internalPullup = false, long numReqCounts = 0); //(defaults to NOT using internal pullup resistors, and required counts = 0)

So, in your Arduino sketch, change your definition from something like:

  static st::IS_Contact sensor5(F("garagesideDoor"), PIN_CONTACT_SIDEGARAGE_DOOR, LOW, true);

to something like:

  static st::IS_Contact sensor5(F("garagesideDoor"), PIN_CONTACT_SIDEGARAGE_DOOR, LOW, true, 1000);

Adjust the last argument (i.e. 1000 above) to whatever value gives you a good debounce to prevent false changes in the state of your garage door. Note: The units of this parameters are just counts. How many times in a row the Arduino needs to see the digital input pin either high or low before it sends data to SmartThings. You’ll have to use a stopwatch to determine how big a value you’ll need as it depends on how complicated your sketch is (i.e. how many sensors you have defined.)

Let me know if you have any questions.

Dan

@mweston

Here’s what your sketch should look like. I am assuming you’re using an Arduino UNO, correct? If so, I have corrected some of your pin assignments as your code referenced PIN 14 which does not exist on an UNO.

Note: This is only the sketch code. You’ll need to modify the ST_Anything_Doors_Doors.DeviceType.groovy code (update: I have included the groovy Device Type later in this thread) to have corresponding tiles that match each and every one of the sensor names in the sketch below. The sensor names are in the double quotes below. That should be enough to get you started down the right path. Let me know if you need more help. The harder part will be creating all of the Virtual Contact Sensor devices and then mapping them to the Arduino via a modified ST_Anything_Doors_Multiplexer.SmartApp.groovy piece of code. It’s not hard work, but just tedious. I am not the best Groovy programmer, so I am sure there is probably a better way to go about that task than my example, but at least it works.

//******************************************************************************************
//  File: ST_Anything_Doors.ino
//  Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
//
//  Summary:  This Arduino Sketch, along with the ST_Anything library and the revised SmartThings 
//            library, demonstrates the ability of one Arduino + SmartThings Shield to 
//            implement a multi input/output custom device for integration into SmartThings.
//            The ST_Anything library takes care of all of the work to schedule device updates
//            as well as all communications with the SmartThings Shield.
//
//            ST_Anything_Doors implements the following:
//              - 2 x Door Control devices (used as Garage Doors)
//              - 4 x Contact Sensor devices (used to monitor magnetic door sensors)
//              - 1 x Motion device (used to detect motion in the garage)
//              - 1 x Temperature/Humidity device (unsed to monitor temp & humidity in the garage)
//
//            During the development of this re-usable library, it became apparent that the 
//            Arduino UNO R3's very limited 2K of SRAM was very limiting in the number of 
//            devices that could be implemented simultaneously.  A tremendous amount of effort
//            has gone into reducing the SRAM usage, including siginificant improvements to
//            the SmartThings Arduino library.  The SmartThings library was also modified to
//            include support for using Hardware Serial port(s) on the UNO, MEGA, and Leonardo.
//            During testing, it was determined that the Hardware Serial ports provide much
//            better performance and reliability versus the SoftwareSerial library.  Also, the
//            MEGA 2560's 8K of SRAM is well worth the few extra dollars to save your sanity
//            versus always running out of SRAM on the UNO R3.  The MEGA 2560 also has 4 Hardware
//            serial ports (i.e. UARTS) which makes it very easy to use Hardware Serial instead 
//            of SoftwareSerial, while still being able to see debug data on the USB serial 
//            console port (pins 0 & 1).  
//
//            Note: We did not have a Leonardo for testing, but did fully test on UNO R3 and 
//            MEGA 2560 using both SoftwareSerial and Hardware Serial communications to the 
//            Thing Shield.
//    
//  Change History:
//
//    Date        Who            What
//    ----        ---            ----
//    2015-01-03  Dan & Daniel   Original Creation
//    2015-01-07  Dan Ogorchock  Modified for Door Monitoring and Garage Door Control
//    2015-03-28  Dan Ogorchock  Removed RCSwitch #include now that the libraries are split up
//    2015-03-31  Daniel O.      Memory optimizations utilizing progmem
//
//******************************************************************************************

//******************************************************************************************
// SmartThings Library for Arduino Shield
//******************************************************************************************
#include <SoftwareSerial.h> //Arduino UNO/Leonardo uses SoftwareSerial for the SmartThings Library
#include <SmartThings.h>    //Library to provide API to the SmartThings Shield
#include <avr/pgmspace.h>

//******************************************************************************************
// ST_Anything Library 
//******************************************************************************************
#include <Constants.h>       //Constants.h is designed to be modified by the end user to adjust behavior of the ST_Anything library
#include <Device.h>          //Generic Device Class, inherited by Sensor and Executor classes
#include <Sensor.h>          //Generic Sensor Class, typically provides data to ST Cloud (e.g. Temperature, Motion, etc...)
#include <InterruptSensor.h> //Generic Interrupt "Sensor" Class, waits for change of state on digital input 
#include <PollingSensor.h>   //Generic Polling "Sensor" Class, polls Arduino pins periodically
#include <Everything.h>      //Master Brain of ST_Anything library that ties everything together and performs ST Shield communications


#include <IS_Motion.h>       //Implements an Interrupt Sensor (IS) to detect motion via a PIR sensor
#include <IS_Contact.h>      //Implements an Interrupt Sensor (IS) to monitor the status of a digital input pin

//******************************************************************************************
//Define which Arduino Pins will be used for each device
//  Notes: -Serial Communications Pins are defined in Constants.h (avoid pins 0,1,2,3
//          for inputs and output devices below as they may be used for communications)
//         -Always avoid Pin 6 as it is reserved by the SmartThings Shield
//
//******************************************************************************************
//"RESERVED" pins for SmartThings ThingShield - best to avoid
#define PIN_O_RESERVED               0  //reserved by ThingShield for Serial communications OR USB Serial Monitor
#define PIN_1_RESERVED               1  //reserved by ThingShield for Serial communications OR USB Serial Monitor
#define PIN_2_RESERVED               2  //reserved by ThingShield for Serial communications
#define PIN_3_RESERVED               3  //reserved by ThingShield for Serial communications
#define PIN_6_RESERVED               6  //reserved by ThingShield (possible future use?)

//Window Pins
#define PIN_CONTACT_KITCHEN_WINDOW1  4
#define PIN_CONTACT_KITCHEN_WINDOW2  5
#define PIN_CONTACT_KITCHEN_WINDOW3  7
#define PIN_CONTACT_MASTER_WINDOW1   8
#define PIN_CONTACT_MASTER_WINDOW2   9
#define PIN_CONTACT_OFFICE_WINDOW1   10
#define PIN_CONTACT_OFFICE_WINDOW2   11
#define PIN_CONTACT_GUEST_WINDOW1    12
#define PIN_CONTACT_GUEST_WINDOW2    13


//House Door Pins
#define PIN_CONTACT_FRONT_DOOR       A1
#define PIN_CONTACT_KITCHEN_DOOR     A2
#define PIN_CONTACT_GARAGE_DOOR      A3
#define PIN_CONTACT_BEDROOM_DOOR     A4

//motion pins
#define PIN_MOTION                   A5

//******************************************************************************************
//Arduino Setup() routine
//******************************************************************************************
void setup()
{
  //******************************************************************************************
  //Declare each Device that is attached to the Arduino
  //  Notes: - For each device, there is typically a corresponding "tile" defined in your 
  //           SmartThings DeviceType Groovy code
  //         - For details on each device's constructor arguments below, please refer to the 
  //           corresponding header (.h) and program (.cpp) files.
  //         - The name assigned to each device (1st argument below) must match the Groovy
  //           DeviceType Tile name.  (Note: "temphumid" below is the exception to this rule
  //           as the DHT sensors produce both "temperature" and "humidity".  Data from that
  //           particular sensor is sent to the ST Shield in two separate updates, one for 
  //           "temperature" and one for "humidity")
  //******************************************************************************************
 
  static st::IS_Motion sensor1(F("motion"), PIN_MOTION, HIGH, false);
  static st::IS_Contact sensor2(F("kitchenWindow1"), PIN_CONTACT_KITCHEN_WINDOW1, LOW, true, 500);
  static st::IS_Contact sensor3(F("kitchenWindow2"), PIN_CONTACT_KITCHEN_WINDOW2, LOW, true, 500);
  static st::IS_Contact sensor4(F("kitchenWindow3"), PIN_CONTACT_KITCHEN_WINDOW3, LOW, true, 500);
  static st::IS_Contact sensor5(F("masterWindow1"), PIN_CONTACT_MASTER_WINDOW1, LOW, true, 500);
  static st::IS_Contact sensor6(F("masterWindow2"), PIN_CONTACT_MASTER_WINDOW2, LOW, true, 500);
  static st::IS_Contact sensor7(F("officeWindow1"), PIN_CONTACT_OFFICE_WINDOW1, LOW, true, 500);
  static st::IS_Contact sensor8(F("officeWindow2"), PIN_CONTACT_OFFICE_WINDOW2, LOW, true, 500);
  static st::IS_Contact sensor9(F("guestWindow1"), PIN_CONTACT_GUEST_WINDOW1, LOW, true, 500);
  static st::IS_Contact sensor10(F("guestWindow2"), PIN_CONTACT_GUEST_WINDOW2, LOW, true, 500);
  static st::IS_Contact sensor11(F("frontDoor"), PIN_CONTACT_FRONT_DOOR, LOW, true, 500);
  static st::IS_Contact sensor12(F("kitchenDoor"), PIN_CONTACT_KITCHEN_DOOR, LOW, true, 500);
  static st::IS_Contact sensor13(F("garageDoor"), PIN_CONTACT_GARAGE_DOOR, LOW, true, 500);
  static st::IS_Contact sensor14(F("bedroomDoor"), PIN_CONTACT_BEDROOM_DOOR, LOW, true, 500);
  
  //*****************************************************************************
  //  Configure debug print output from each main class 
  //  -Note: Set these to "false" if using Hardware Serial on pins 0 & 1
  //         to prevent communication conflicts with the ST Shield communications
  //*****************************************************************************
  st::Everything::debug=true;
  st::Executor::debug=true;
  st::Device::debug=true;
  st::PollingSensor::debug=true;
  st::InterruptSensor::debug=true;
  
  //*****************************************************************************
  //Initialize the "Everything" Class
  //*****************************************************************************
  st::Everything::init();
  
  //*****************************************************************************
  //Add each sensor to the "Everything" Class
  //*****************************************************************************
  st::Everything::addSensor(&sensor1);
  st::Everything::addSensor(&sensor2);
  st::Everything::addSensor(&sensor3);
  st::Everything::addSensor(&sensor4); 
  st::Everything::addSensor(&sensor5); 
  st::Everything::addSensor(&sensor6);
  st::Everything::addSensor(&sensor7); 
  st::Everything::addSensor(&sensor8);
  st::Everything::addSensor(&sensor9);
  st::Everything::addSensor(&sensor10); 
  st::Everything::addSensor(&sensor11); 
  st::Everything::addSensor(&sensor12);
  st::Everything::addSensor(&sensor13); 
  st::Everything::addSensor(&sensor14);
  //*****************************************************************************
  //Add each executor to the "Everything" Class
  //*****************************************************************************
  //st::Everything::addExecutor(&executor1);
  
  //*****************************************************************************
  //Initialize each of the devices which were added to the Everything Class
  st::Everything::initDevices();
  //*****************************************************************************
}

//******************************************************************************************
//Arduino Loop() routine
//******************************************************************************************
void loop()
{
  //*****************************************************************************
  //Execute the Everything run method which takes care of "Everything"
  //*****************************************************************************
  st::Everything::run();
}

@mweston

One more thing, I noticed that your basically maxing out the number of inputs on the Arduino, which I do not think will be a problem due to all of the optimizations my son has done in the ST_Anything library to conserve RAM. However, we did have a limit on the number of sensors one could have in a sketch, which was set to 10. Your application needs 14, so you’ll need to edit a file within the ST_Anything library, called Constants.h.

Please change the following line of code within Constants.h to look like:

		//Maximum number of SENSOR objects
		static const byte MAX_SENSOR_COUNT = 14;				//Used to limit the number of sensor devices allowed.  Be careful on Arduino UNO due to 2K SRAM limitation

@mweston

Here is a revised version of my ST_Anything_Doors groovy Device Type code that you’ll need to define and assign in the ST Developers IDE.

/**
 *  ST_Anything_Doors Device Type - ST_Anything_Doors.device.groovy
 *
 *  Copyright 2015 Daniel Ogorchock
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at:
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
 *  for the specific language governing permissions and limitations under the License.
 * 
 *  Change History:
 *
 *    Date        Who            What
 *    ----        ---            ----
 *    2015-10-31  Dan Ogorchock  Original Creation
 *
 *
 */

metadata {
	definition (name: "ST_Anything_Doors_Example", namespace: "ogiewon", author: "Daniel Ogorchock") {
		capability "Contact Sensor"
		capability "Motion Sensor"
		capability "Sensor"

		attribute "frontDoor", "string"
		attribute "bedroomDoor", "string"
		attribute "kitchenDoor", "string"
		attribute "garageDoor", "string"
 		attribute "kitchenWindow1", "string"
		attribute "kitchenWindow2", "string"       
		attribute "kitchenWindow3", "string"       
		attribute "masterWindow1", "string"       
		attribute "masterWindow2", "string"       
		attribute "officeWindow1", "string"       
		attribute "officeWindow2", "string"       
		attribute "guestWindow1", "string"       
		attribute "guestWindow2", "string"           
	}

    simulator {
        status "on":  "catchall: 0104 0000 01 01 0040 00 0A21 00 00 0000 0A 00 0A6F6E"
        status "off": "catchall: 0104 0000 01 01 0040 00 0A21 00 00 0000 0A 00 0A6F6666"

        // reply messages
        reply "raw 0x0 { 00 00 0a 0a 6f 6e }": "catchall: 0104 0000 01 01 0040 00 0A21 00 00 0000 0A 00 0A6F6E"
        reply "raw 0x0 { 00 00 0a 0a 6f 66 66 }": "catchall: 0104 0000 01 01 0040 00 0A21 00 00 0000 0A 00 0A6F6666"
    }
	
    // Preferences

	// tile definitions
	tiles {
        standardTile("frontDoor", "device.frontDoor", width: 1, height: 1, canChangeIcon: true, canChangeBackground: true) {
			state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
			state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
 		}
        standardTile("kitchenDoor", "device.kitchenDoor", width: 1, height: 1, canChangeIcon: true, canChangeBackground: true) {
			state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
			state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
 		}
        standardTile("garageDoor", "device.garageDoor", width: 1, height: 1, canChangeIcon: true, canChangeBackground: true) {
			state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
			state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
 		}
        standardTile("bedroomDoor", "device.bedroomDoor", width: 1, height: 1, canChangeIcon: true, canChangeBackground: true) {
			state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
			state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
 		}
        standardTile("kitchenWindow1", "device.kitchenWindow1", width: 1, height: 1, canChangeIcon: true, canChangeBackground: true) {
			state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
			state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
 		}
        standardTile("kitchenWindow2", "device.kitchenWindow2", width: 1, height: 1, canChangeIcon: true, canChangeBackground: true) {
			state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
			state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
 		}
        standardTile("kitchenWindow3", "device.kitchenWindow3", width: 1, height: 1, canChangeIcon: true, canChangeBackground: true) {
			state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
			state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
 		}
        standardTile("masterWindow1", "device.masterWindow1", width: 1, height: 1, canChangeIcon: true, canChangeBackground: true) {
			state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
			state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
 		}
        standardTile("masterWindow2", "device.masterWindow2", width: 1, height: 1, canChangeIcon: true, canChangeBackground: true) {
			state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
			state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
 		}
        standardTile("officeWindow1", "device.officeWindow1", width: 1, height: 1, canChangeIcon: true, canChangeBackground: true) {
			state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
			state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
 		}
        standardTile("officeWindow2", "device.officeWindow2", width: 1, height: 1, canChangeIcon: true, canChangeBackground: true) {
			state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
			state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
 		}
        standardTile("guestWindow1", "device.guestWindow1", width: 1, height: 1, canChangeIcon: true, canChangeBackground: true) {
			state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
			state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
 		}
        standardTile("guestWindow2", "device.guestWindow2", width: 1, height: 1, canChangeIcon: true, canChangeBackground: true) {
			state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
			state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
 		}

        standardTile("motion", "device.motion", width: 1, height: 1) {
			state("active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#53a7c0")
			state("inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff")
		}
        
        main (["motion"])
        details(["motion","frontDoor","kitchenDoor","garageDoor","bedroomDoor","kitchenWindow1","kitchenWindow2","kitchenWindow3","masterWindow1","masterWindow2","officeWindow1","officeWindow2","guestWindow1","guestWindow2"])
	}
}

//Map parse(String description) {
def parse(String description) {
    def msg = zigbee.parse(description)?.text
    log.debug "Parse got '${msg}'"

    def parts = msg.split(" ")
    def name  = parts.length>0?parts[0].trim():null
    def value = parts.length>1?parts[1].trim():null

    name = value != "ping" ? name : null
	
    //if (name == "temperature") 
    //{
    //	value = fahrenheitToCelsius(value.toDouble())
    //}
    
    def result = createEvent(name: name, value: value, isStateChange: true)

    log.debug result

    return result
}