Announcing the "ST_Anything" Arduino/ThingShield Project

@jake1164

Jason,

You’re use case is actually a nice and simple one. Since you only have 1 Contact Sensor, 1 Garage Door Control, 1 Temperature Sensor, and 1 Humidity Sensor… I believe you can simply use the following Device Handler and you will not need the Multiplexer and Virtual Devices (if you’re trying to use those…) I have not tried to use this code at all as I am away from my main computer, and thus I cannot test it.

/**
 *  ST_AnyThing.groovy
 *
 *  Copyright 2014 Dan G Ogorchock & Daniel J 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-01-03  Dan & Daniel   Original Creation
 *    2016-02-23  Dan Ogorchock  Modified for Jason Jackson's use case
 *
 */
  
metadata {
	definition (name: "ST_AnyThing", namespace: "ogiewon", author: "Daniel Ogorchock") {
		capability "Configuration"
		capability "Temperature Measurement"
		capability "Relative Humidity Measurement"
		capability "Switch"
		capability "Sensor"
		capability "Contact Sensor"
		capability "Polling"
		capability "Door Control"
		capability "Garage Door Control"
   
		command "pushGarage"
	}

    simulator {
 
    }


    // Preferences
	preferences {    	
    	input "temphumidSampleRate", "number", title: "Temperature/Humidity Sensor Sampling Interval (seconds)", description: "Sampling Interval (seconds)", defaultValue: 30, required: true, displayDuringSetup: true
	}

	// Tile Definitions
	tiles {
		standardTile("garageDoor", "device.door", width: 1, height: 1, canChangeIcon: true, canChangeBackground: true) {
			state "closed", label: 'Closed', action: "pushGarage", icon: "st.doors.garage.garage-closed", backgroundColor: "#79b821", nextState: "closed"
            		state "open", label: 'Open', action: "pushGarage", icon: "st.doors.garage.garage-open", backgroundColor: "#ffa81e", nextState: "open"
            		state "opening", label: 'Opening', action: "pushGarage", icon: "st.doors.garage.garage-opening", backgroundColor: "89C2E8", nextState: "opening"
            		state "closing", label: 'Closing', action: "pushGarage", icon: "st.doors.garage.garage-closing", backgroundColor: "89C2E8", nextState: "closing"
 		}
        
 		standardTile("garageSideDoor", "device.contact", 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")
 		}       
    
        	valueTile("temperature", "device.temperature", width: 1, height: 1) {
			state("temperature", label:'${currentValue}°', 
				backgroundColors:[
					[value: 31, color: "#153591"],
					[value: 44, color: "#1e9cbb"],
					[value: 59, color: "#90d2a7"],
					[value: 74, color: "#44b621"],
					[value: 84, color: "#f1d801"],
					[value: 95, color: "#d04e00"],
					[value: 96, color: "#bc2323"]
				]
			)
		}
        
        	valueTile("humidity", "device.humidity", inactiveLabel: false) {
			state "humidity", label:'${currentValue}% humidity', unit:""
		}
       
		standardTile("configure", "device.configure", inactiveLabel: false, decoration: "flat") {
			state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
		}

        main(["temperature","humidity"])
        details(["garageDoor","garageSideDoor","temperature","humidity","configure"])
	}
}

// parse events into attributes
def parse(String description) {
    log.debug "Parsing '${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

    def result = createEvent(name: name, value: value)

    log.debug result

    return result
}

// handle commands
def pushGarage() {
    log.debug "Executing 'pushGarage' = 'garageDoor on'"
    zigbee.smartShield(text: "garageDoor on").format()
}

def open() {
    pushGarage()
}

def close() {
    pushGarage()
}

def poll() {
	//temporarily implement poll() to issue a configure() command to send the polling interval settings to the arduino
	configure()
}

def configure() {
	log.debug "Executing 'configure'"
	log.debug "temphumid " + temphumidSampleRate
	[
	    zigbee.smartShield(text: "temphumid " + temphumidSampleRate).format()
	]
}
1 Like

Hi Dan,

Thanks for adding support for the DS18B20 OneWire. Is the current PS__DS18B20_Temperature.h limited to a single DS18B20 sensor? I’d like to be able to run multiple (3-7) over the same pin (I believe it will support up to 8).

Thanks again for your work on this project!

-Brian

BOOM! There it is! I knew this question would be asked eventually. I just thought it would take a little longer than 6 days. :relaxed:

Brian,

Currently, the ST_Anything library’s PS_DS18B20_Temperature class does not support more than one DS18B20. I do have an idea of a possible way to add additional ones. My thought is that the system would just report back to ST the temperatures of any of the DS18B20’s that it discovers on the OneWire network (i.e. one Arduino pin) and simply append an index number to the string sent back. So, instead of just “Temperature 72” being sent back, it would send a series of strings back to the ST Device Handler in the form of

"Temperature1 72"
"Temperature2 67"
"Temperature3 87"
"Temperature4 45"
“Temperature5 90”

This way, you still only create one DS18B20 device from the PS_DS18B20_Temperature in your sketch’s setup() routine. I would probably add an optional constructor argument to determine whether or not to return the first found sensor’s temp only (i.e. current behavior), or all of the temps. The one concern I have with this is whether or not the sensors are always discovered in the same order or not. The user will also have to figure out which temperature represents which real world sensor.

Give me some time and I’ll look into it. I am away from my main development system currently, so no Arduino available for testing. I am also not sure if I have multiple DS18B20 sensors on hand.

Dan

Ok, Progress has been made!

Your changes solved the crash and now the relay works (without crashing the app), however both contact switches stopped working.

It appears to be something with the device.door / device.contact not working, When I switch them back to
device.garageDoor (to match the name) the contact works but the relay (push the button) crashes the app. I have not dug into the underlying framework yet so figured I would ask.

In the arduino I have the following sensors:

static st::IS_Contact sensor1(F("garageSideDoor"), PIN_CONTACT_GARAGE_SIDE_DOOR, LOW, true, 500);
 static st::PS_TemperatureHumidity sensor2(F("temphumid"), 120, 10, PIN_TEMPERATUREHUMIDITY, st::PS_TemperatureHumidity::DHT11);   
 static st::IS_DoorControl sensor3(F("garageDoor"), PIN_CONTACT_GARAGE_DOOR, LOW, true, PIN_RELAY_GARAGE_DOOR, LOW, true, 1000);

Thanks for your work on this project, the flexibility is quite amazing.

Great, thanks again Dan. I spent a few hours today looking over all your code and how it works.

Your gift for coding is quite amazing! When I study code like this I always get a headache, but i learn ALOT by doing so.

On a side note, have you given any more thought on integrating with my sensors.org (or any wireless mesh solution) ?

This would be such a pivotal movement for the Hacker/SmartThings community!

Thanks again, and no rush on the oneWire single pin update.

@bseal

Brian,

I have updated my GitHub repo with changes to support multiple DS18B20 temperature sensors via an optional argument of the PS_DS18B20_Temperature constructor called num_sensors. If omitted this will default to a value of 1 and everything will behave exactly the same way it does today.

If you add this argument (see the last argument, 5, below for an example) then the system will report back to ST the num_sensors you requested, by appending the index # to the name of the sensor.

  static st::PS_DS18B20_Temperature sensor1(F("temperature"), 120, 0, PIN_DS18B20_Temperature, false, 10, 5);

It will send a series of strings back to the ST Device Handler in the form of

"temperature1 72"
"temperature2 67"
"temperature3 87"
"temperature4 45"
“temperature5 90”

where “temperature” is what you supplied as the first argument of the constructor, and the “1” through “5” is the index into the temperature array returned by the DallasTemperature library used within the PC_18B20_Temperature class of ST_Anything.

NOTE: It is up to the user to determine which index number refers to each real-world sensor. In my testing, after multiple power cycles, the three sensors I used in my test always were reported back in the same order. You will also need to create the proper ST tiles in your ST Device Handler to properly handle the incoming data. Traditionally, each ST_Anything device had a 1 to 1 correlation with a tile in the Device Handler code. If you enable multiple sensor support in this class, it is up to the user to create the proper number of Device Handler tiles to hold all of the temperature values.


As for MySensors.org support… Nope, haven’t had any real need for adding yet another mesh network. Somebody should be able to simply modify one of the existing MySensors Gateways to talk to ST, and then add a nice DeviceHandler/SmartApp to auto generate virtual child devices with ST whenever a new MySensor device is added. I just don’t have the desire, need, or time to take that task on.

Dan

@jake1164

Jake,

I have it all working now… It did take some tweaking on names, which I did not expect, but in hindsight, I’m not surprised.

Here is the Arduino sketch (change the pin assignments as you see fit:

//******************************************************************************************
//  File: Jason_Jackson_ST_Anything.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 <dht.h>            //DHT Temperature and Humidity Library 
#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 <PS_TemperatureHumidity.h>  //Implements a Polling Sensor (PS) to measure Temperature and Humidity via DHT library
#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
#include <IS_DoorControl.h> //Implements an Interrupt Sensor (IS) and Executor to monitor the status of a digital input pin and control a digital output 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?)

//Motion and Temperature/Humidity Pins (Note: using Analog pins as Digital inputs)
#define PIN_TEMPERATUREHUMIDITY      5

//Garage Door Pins 
#define PIN_RELAY_GARAGE_DOOR    9
#define PIN_CONTACT_GARAGE_DOOR  11

//House Door Pins
#define PIN_CONTACT_GARAGE_SIDE_DOOR  10



//******************************************************************************************
//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")
  //******************************************************************************************
  //Polling Sensors
  static st::PS_TemperatureHumidity sensor2(F("temphumid"), 120, 10, PIN_TEMPERATUREHUMIDITY, st::PS_TemperatureHumidity::DHT11);
  
  //Interrupt Sensors 
  static st::IS_Contact sensor1(F("contact"), PIN_CONTACT_GARAGE_SIDE_DOOR, LOW, true, 500);
  static st::IS_DoorControl sensor3(F("door"), PIN_CONTACT_GARAGE_DOOR, LOW, true, PIN_RELAY_GARAGE_DOOR, LOW, true, 1000);
 
  
  //*****************************************************************************
  //  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);
  
  //*****************************************************************************
  //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();
} 

And here is the Groovy Device Handler code

/**
 *  ST_AnyThing.groovy
 *
 *  Copyright 2014 Dan G Ogorchock & Daniel J 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-01-03  Dan & Daniel   Original Creation
 *    2016-02-23  Dan Ogorchock  Modifed for Jason Jackson's use case
 *
 */
  
metadata {
	definition (name: "Jason_Jackson_ST_AnyThing", namespace: "ogiewon", author: "Daniel Ogorchock") {
		capability "Configuration"
		capability "Temperature Measurement"
		capability "Relative Humidity Measurement"
		capability "Switch"
		capability "Sensor"
		capability "Contact Sensor"
		capability "Polling"
		capability "Door Control"
		capability "Garage Door Control"
   
		command "pushGarage"
        //attribute "garagesidedoor", "string"
        //attribute "garagedoor", "string"
	}

    simulator {
 
    }

    // Preferences
	preferences {    	
    	input "temphumidSampleRate", "number", title: "Temperature/Humidity Sensor Sampling Interval (seconds)", description: "Sampling Interval (seconds)", defaultValue: 30, required: true, displayDuringSetup: true
	}

	// Tile Definitions
	tiles {
		standardTile("door", "device.door", width: 1, height: 1, canChangeIcon: true, canChangeBackground: true) {
			state "closed", label: 'Closed', action: "pushGarage", icon: "st.doors.garage.garage-closed", backgroundColor: "#79b821", nextState: "closed"
			state "open", label: 'Open', action: "pushGarage", icon: "st.doors.garage.garage-open", backgroundColor: "#ffa81e", nextState: "open"
			state "opening", label: 'Opening', action: "pushGarage", icon: "st.doors.garage.garage-opening", backgroundColor: "89C2E8", nextState: "opening"
			state "closing", label: 'Closing', action: "pushGarage", icon: "st.doors.garage.garage-closing", backgroundColor: "89C2E8", nextState: "closing"
 		}
        
 		standardTile("contact", "device.contact", 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")
 		}       
    
		valueTile("temperature", "device.temperature", width: 1, height: 1) {
			state("temperature", label:'${currentValue}°', 
				backgroundColors:[
					[value: 31, color: "#153591"],
					[value: 44, color: "#1e9cbb"],
					[value: 59, color: "#90d2a7"],
					[value: 74, color: "#44b621"],
					[value: 84, color: "#f1d801"],
					[value: 95, color: "#d04e00"],
					[value: 96, color: "#bc2323"]
				]
			)
		}
        
		valueTile("humidity", "device.humidity", inactiveLabel: false) {
			state "humidity", label:'${currentValue}% humidity', unit:""
		}
       
		standardTile("configure", "device.configure", inactiveLabel: false, decoration: "flat") {
			state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
		}

        main(["temperature","humidity"])
        details(["door","contact","temperature","humidity","configure"])
	}
}

// parse events into attributes
def parse(String description) {
    log.debug "Parsing '${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

    def result = createEvent(name: name, value: value)

    log.debug result

    return result
}

// handle commands
def pushGarage() {
    log.debug "Executing 'pushGarage' = 'door on'"
    zigbee.smartShield(text: "door on").format()
}

def open() {
    pushGarage()
}

def close() {
    pushGarage()
}

def poll() {
	//temporarily implement poll() to issue a configure() command to send the polling interval settings to the arduino
	configure()
}

def configure() {
	log.debug "Executing 'configure'"
	log.debug "temphumid " + temphumidSampleRate
	[
	    zigbee.smartShield(text: "temphumid " + temphumidSampleRate).format()
	]
}

@ogiewon

Once again everything is working with the exception of when I press the open garage door button it crashes the smartthings android app. I dont have an iPhone to try it, although I could try and force the app onto my ipad.

So to recap I installed both the new groovy and the arduino code and set them up. Both contact switches turn on and off on both the arduino and the app. When I press the button to open the garage door it send the command to the arduino, which in turn opens the relay. A moment after the switch on the arduino opens the SmartThings app crashes saying the report has been sent to the developer.

I guess I will try and force clean the app cache and try again later today, and if that doesnt work I could try removing and re-installing the app. Any other suggestions since this seems to be an issue with the phone app?

Once again thanks for all the work on this, you go way above and beyond!
-J

Hey All, finally moved in and working on the boards. I’m working on getting 4 contact sensors working and in a bind. I can get everything to work triggering with the 5v and 3.3v on the board to the various inputs, but I’m having difficulty with the security board. Each sensor has two wires coming into the old security board, one plugs into a numbered port the other goes into a internally connected port named “COM” the voltage between the numbered port is 2.5v when the doors are closed and 5v when they are open. I’ve tied the numbered ports to the Arduino ports but nothing happens.

Do I have to connect the “COM” port to something?
I’ve disabled internal pullup and the old security system works normally while the Arduino is pulled in.

including code.

#include <Constants.h>
#include <Device.h>
#include <Everything.h>
#include <EX_Alarm.h>
#include <EX_Switch.h>
#include <Executor.h>
#include <InterruptSensor.h>
#include <IS_Contact.h>
#include <IS_DoorControl.h>
#include <IS_Motion.h>
#include <IS_Smoke.h>
#include <PollingSensor.h>
#include <PS_Illuminance.h>
#include <PS_PulseCounter.h>
#include <PS_Water.h>
#include <S_TimedRelay.h>
#include <Sensor.h>

//******************************************************************************************
//  File: ST_Anything_Doors_Windows.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_Example implements the following:
//              - 13 x Contact Sensor devices (used to monitor magnetic door/windows sensors)
//              - 1 x Motion device (used to detect motion)
//
//            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
//    2015-10-31  Dan Ogorchock  Revised for a specific user request
//
//******************************************************************************************

//******************************************************************************************
// 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 <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

//House Door Pins
#define PIN_CONTACT_MUD_DOOR         A8
#define PIN_CONTACT_FRONT_DOOR       A9
#define PIN_CONTACT_DECK_DOOR        A10
#define PIN_CONTACT_PATIO_DOOR       A11

//motion pins
//#define PIN_MOTION_MAIN_MOTION       A12
//#define PIN_MOTION_LOWER_MOTION      A13

//******************************************************************************************
//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.  
  //******************************************************************************************

  static st::IS_Contact sensor1(F("FrontDoor"), PIN_CONTACT_FRONT_DOOR, HIGH);
  static st::IS_Contact sensor2(F("MudDoor"), PIN_CONTACT_MUD_DOOR, HIGH);
  static st::IS_Contact sensor3(F("DeckDoor"), PIN_CONTACT_DECK_DOOR, HIGH);
  static st::IS_Contact sensor4(F("PatioDoor"), PIN_CONTACT_PATIO_DOOR, HIGH); 
  //static st::IS_Motion sensor5(F("MainMotion"), PIN_MOTION_MAIN_MOTION, HIGH);
  //static st::IS_Motion sensor6(F("LowerMotion"), PIN_MOTION_LOWER_MOTION, HIGH);
  
  //*****************************************************************************
  //  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::Device::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);
  
  //*****************************************************************************
  //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();
}

Groovy Code

/**
 *  ST_Anything_Doors_Windows Device Type - ST_Anything_Doors_Windows.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_Windows", namespace: "ogiewon", author: "Daniel Ogorchock") {
		capability "Contact Sensor"
		capability "Motion Sensor"
		capability "Sensor"
		attribute "FrontDoor", "string"
		attribute "MudroomDoor", "string"
		attribute "DeckDoor", "string"
		attribute "PatioDoor", "string"
 		attribute "MainMotion", "string"
		attribute "LowerMotion", "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("MudDoor", "device.MudDoor", 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("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("DeckDoor", "device.DeckDoor", 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("PatioDoor", "device.PatioDoor", 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("MainMotion", "device.MainMotion", 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")
		}
        standardTile("LowerMotion", "device.LowerMotion", 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(["FrontDoor"])
        details(["FrontDoor","MudDoor","DeckDoor","PatioDoor","MainMotion","LowerMotion"])
	}
}
//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
}

Jason,

I do not use Android, just iOS on my iPhone and iPad. Please load the SmartThings app on your iPad and let me know if it behaves as expected. Not sure why the Android version would crash, and I have no way of testing unless someone wants to donate an Android phone or tablet… :slightly_smiling:

Dan

Luke,

We need some more information… Most likely, you will need to tie the GND on the Arduino to the GND on the existing security panel. This will then allow both systems to have a common reference voltage. Again, please be sure the voltages are both 5V DC TTL level before connecting the two systems together. If the old alarm is running at 12V or 24V DC (or AC!!!) then you’re going to need to build a circuit similar to what Ken Washington showed earlier.

When you say you’re measuring +5v and +2.5v, we need to know exactly where you have you voltmeter leads attached. Is this completely at the old alarm panel? Or are you measuring voltages at the Arduino?

NOTE: Do NOT connect both the Arduino +5V and GND to the old Alarm Panel. You should only connect the GND on both systems together. If you were to connect both +5V and GND between both systems, you will start flowing current between the two power supplies, as there is no way both systems are at the exact same voltage. (If the old security system does have a decent +5VDC power source, you could actually use it to power the Arduino. In that case, you would remove the dedicated Arduino power supply altogether.)

Dan

The 5v and 2.5v are when the leads are in contact with either of the two wires from the sensor in the existing security panel. One of the wires goes into a numbered port and the other goes into a “COM” port that is tied to all the other “COM” ports.

I haven’t measured the voltage at the Arduino.

Which ground do i tie to the existing security system? Does it matter? Are we thinking the Ground for the existing system is the “COM” Port?

quick update

I connected the Adruino Ground to a ground post on the existing system. Right now its not connected to anything, but it seems to set a reference point. When I measure voltage its the same from wire to security system ground as wire to arduino ground.

Here is where its weird now. if all sensors are closed the voltage for each sensor sits around 2.1V. When one door is open it reads 4.6v while the remaining sensors read 0.6v.

When all sensors are closed smarthings goes haywire opening and closing doors at random. with one door open it stops and will (sometimes) read the correct door as open, sometimes a random door. But every other door will function perfectly as long as one other door is already open.

I have the trigger set at High, so my thought is that the system idleing at all closed 2.1-2.2v is the threshold for “High”. Is there a way to redefine “High”?

Dan,
I installed the iOS app and everything works perfectly, so it appears this is an android issue.

Thanks for your assistance, looks like I am off to troll the android app portion of the forum.

Thanks again,
Jason

1 Like

Luke,

There is no way to redefine the voltage level for HIGH on the Arduino. Have you tried setting your voltmeter to AC to see whether or not the old alarm panel might actually be using AC voltage instead of DC? Just something to verify.

It sound to me like you’re going to have to follow Ken’s additional circuit, or some thing simile, to get the old alarm system’s signal level shifted to the Arsuino’s TTL 5V requirements.

Without being able to see the schematic of the old alarm system, it is very hard to troubleshoot from here.

Dan

Wiring diagram you say…

It’s definitely DC,not sure what to do now

Ok, use your voltmeter on DC and measure the voltage between COM and one of the ZN terminals with the corresponding door or window sensor open and closed. Based on the wiring diagram, if the system is DC voltage based, you should see either 0 volts or some positive voltage.

Then repeat the same test with your voltmeter set to AC voltage. I am curious what these readings are. If the system is DC based, the AC readings should be ~0 VAC regardless of the door/window sensor state.

Based on the fact that the system has a 12VDC battery backup, it stands to reason that the system is probably DC based. You might even be able to power the Arduino from the 12VDC battery. Most likely the alarm panel board has an AC transformer to DC voltage rectifier circuit as well as a DC battery charging circuit.

If the system is 5VDC based, you should be able to connect the Arduino GND to the alarm panel COM. Then connect an Arduino digital input pin to a ZN terminal on the alarm panel. If the system is 12VDC based, you’re going to need to create a voltage divider circuit for each zone, or use a transistor design like @kewashi.

Between COM and ZN the VDC reads 2.5v closed and 5.2v open. VAC reads 0 across both.

I have it hooked up with the trigger set to High, but the contacts are reading Closed weather they are open or closed. I tried setting the trigger to Low but the same thing happens just reversed.

3V required to trip the trigger states and I would think that this should work.

I’m currently tying into port 22,24,26,28 and the GND at the base of the same row.

thoughts?

EDIT: Here’s a thought that my baboon-like-skull just had. Everything running into the COM ports has a 5600ohm resistor tied to it. (also listed on the wiring diagram) Perhaps i also need to run a 5600ohm resistor from my Arduino GND to the COM port?

OK, we’re getting somewhere… At least it seems like we are dealing with a 5VDC circuit, so that’s very good news. Can you please determine which of the 4 “Typical Zone Circuits” wiring diagrams your house is wired with?

Also, can you please disconnect one of the Zone wire pairs altogether from the alarm panel/Arduino and measure the resistance between the pair the zone wires with all doors/windows on that zone closed, as well as with one or more doors/windows on that zone open?

It almost seems like there must be another resistor somewhere in the circuit. for the voltage to be cut in half when all sensors on a zone are closed.

I believe its the “normally closed contact with EOL resistor”

I removed a wire pair.

Closed it read ~5600ohm
Open I couldn’t get a reading.

Alright I’ve posted a few conflicting voltages that I blame on me cross-wiring things really weirdly. This are the current (ha) readings. All reading are from the appropriate ZN port to COM

Everything Closed - All zones read 2.5v

One Zone Open - Open zone reads 5.5v all other closed zones read 2.5v

Two Zones open - Both open zones read 5.5v all other zones read 2.5v

Thanks for holding my hand