Announcing the "ST_Anything" Arduino/ThingShield Project

More information.
This is what I got from the ST IDE live log.

5249eca4-ffdd-4770-98a1-f2333abfa462 ‎12‎:‎01‎:‎55‎ ‎AM: debug Using ip: 192.168.1.200 and port: 8090 for device: 5249eca4-ffdd-4770-98a1-f2333abfa462

5249eca4-ffdd-4770-98a1-f2333abfa462 ‎12‎:‎01‎:‎55‎ ‎AM: debug Executing ‘sendEthernet’ switch on

5249eca4-ffdd-4770-98a1-f2333abfa462 ‎12‎:‎01‎:‎55‎ ‎AM: debug Executing ‘switch on’

5249eca4-ffdd-4770-98a1-f2333abfa462 ‎12‎:‎01‎:‎31‎ ‎AM: debug Using ip: 192.168.1.200 and port: 8090 for device: 5249eca4-ffdd-4770-98a1-f2333abfa462

5249eca4-ffdd-4770-98a1-f2333abfa462 ‎12‎:‎01‎:‎31‎ ‎AM: debug Executing ‘sendEthernet’ switch off

5249eca4-ffdd-4770-98a1-f2333abfa462 ‎12‎:‎01‎:‎31‎ ‎AM: debug Executing ‘switch off’

Jess,

You may want to send me a Private Message (PM) so I can try to help you debug things a little more. I will need to see your Arduino source code and the Device Handler source code, along with some screen captures of your Device Settings in the Arduino IDE.

Ignore the following section of the sketch. You don’t need to change it all. It is there for more advanced situations when you want to know immediately, within the Arduino sketch, when data is transferred to the ST cloud. This then provides you with an opportunity to take local action as necessary, without relying on the ST cloud. An example might be that build some sort of Arduino based gadget that controls power to a heater element. You add a temperature probe as well. You could add local Arduino logic within your sketch to detect an over temperature condition and turn off the heater element (without having to depend/wait on the ST cloud!)

Ray,

There are two sets of relay output contacts, Normally Open and Normally Closed. The “alarm” device with the Arduino Sketch allows you to choose the initial state of the output. Play around with the arguments in the sketch to get the desired behavior. I use this same feature on the “switch” device for my garage door opener, so I know it can work correctly. I do NOT want my door to open/closed whenever power is lost/restored.

Change the “Starting State” and “Invert Logic” arguments in your sketch until you get the relay to behave correctly. Some relays have inverted logic, so you will need to use trial and error to get it right. Once the relay is quiet through a power cycle, and clicks “on” and “off” when you press the “Alarm” or “Test” tiles, you’ll know you’ve got it figured out.

//			  st::EX_Alarm() 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 output
//				- bool startingState - OPTIONAL - the value desired for the initial state of the switch.  LOW = "off", HIGH = "on"
//				- bool invertLogic - OPTIONAL - determines whether the Arduino Digital Output should use inverted logic

I am thinking of making a ceiling fan controller with an espduino (http://www.banggood.com/ESPDuino-Development-Board-ESP-13-WiFi-UNO-R3-from-ESP8266-p-1023370.html) and a 4-relay shield.
3 relays to control the 3-speed pull chain, 1 relay to control the light. This can all hide inside the fan housing. I hope wifi still works. However, Only issue is “local control”, if only, there’s another wire to sense the wall switch
Does anyone have any ideas? Also anyone wants to help with the Device Handler?

Your options are limited by the power source of your fan. If you have a secondary (always on) power source for your fan, then all the options below could be used. If you are using the switch wire as input power, then all the Low voltage options would not apply.

For “local control” assuming you are no longer using the switch, and are OK working with high voltage. (I doubt and Electrification would recommend any of the these options.)

  1. Run low voltage wire from switch to the fan controller and use as a switch
  2. Remove/terminate the input power at the switch and use the FORMALLY high voltage wire that runs to the fan as a low voltage switch (Only consider this if you completely understand Home Electrical and the fan’s wiring)
  3. Remove/terminate the input power at the switch and wire the old switch as a switch on an ESP-01. Use the ESP-01 Switch status to control your fan. You could also do this at the junction box for the fan using the high voltage (110V) to power (with 3.3V DC power supply) the ESP-01. (I know this seems a little strange.)

Some safer options but more expensive:
4. Z-wave wall switch form Home Depot/Lowes. Replace old switch, and you could just rewire as original. If you can’t use the high voltage source, then don’t use the outputs of the switch. Just write a smart app to control the fan based on the switch status.
5. Use a Aeon Labs DSC26103-ZWUS - Z-Wave In-Wall Micro Controller with the same options as 4.

I am curious what the ESPDuino is benefiting you as it’s just an ESP with a larger Arduino footprint? My initial thought was to use the EPS-12E NodeMCU with a Sunfounder relay.

Good Luck, Garnet

I’m thinking that if the ESP has a large capacitor to store enough charge, you can sense the wall switch being toggled by the wall-switch. So there’s still local control.
So using the Zwave wall-switch, as the main power source switch, a ESP in the fan housing can sense the power being toggle and this cycle through various combination of LIGHTON->FANON->LIGHTOFF->ALLOFF … The smartthings have full control of the fan speed and light.
If no zwave wall switch, then the automation will be completely off line if the wall-switch is off. That’s one flavor, I suppose.

Not sure how you would wire that up as it’s mixing high and low voltage, but I would recommend an alternative anyway.
If you have a Z-wave wall controller, and given what you want to do, I would consider writing a custom ST device type - probably be able to reuse someone else that has those states. Then you would wire up the fan hot all the time effectively just using the Z-wall switch as a remote. (So I’m saying you don’t even wire the fan to the wall switch.) With the setup you can also buy a $10 4 button Minimote and also have a remote.

@cslee

Why not simply use a GE Z-Wave 3 speed Fan Controller? It is safe and uses the existing home wiring. It provides both local control and remote via ST. I know the cost is a little higher, but I believe the UL safety rating is easily worth the money. You can add another Z-Wave switch/dimmer alongside for the light, assuming your house is wired with two switches. Added bonus is that if you sell your house, you can simply leave everything or just put back the old switches in the wall.

https://www.lowes.com/pd/GE-Z-Wave-3-Speed-Wireless-Rocker-Fan-Controls-Includes-White-and-Almond-Rockers/50353792

https://www.lowes.com/pd/GE-3-Way-Dimmer/50343474

You buy slightly cheaper by buying separety and adding another item to get total about 50$ and using $15 off $50 coupon, coupon codes $.99 all over ebay.

1 Like

Unfortunately, it’s not wired for fan / light, just on/off, hence the pull-chain ceiling fan

Is this a good candidate for a simple “ST Anything” controlled relay?

@cslee

It looks like an ESP-01 plugged into a relay board. If so, you “should” be able to program it and run ST_Anything, assuming you’re a proficient ESP8266 user already. Looks like you’re going to need a USB to Serial programming cable/module. Figuring out how to program one of these ESP-01 modules takes some effort, which is why I recommend the NodeMCU v1.0 ESP8266-12e boards for simplicity. I have successfully run the ST_Anything_ESP8266WiFi.ino sketch directly on a ESP-01 module. You only have 2 GPIO pins with ESP-01, which is plenty to run a single relay, but limiting if you’re planning on a larger project. The ESP8266-12E boards support 9 GPIO pins + 1 analog input.

Here is the USB to Serial module I use

Thanks for all the great info in this section. I have an Uno working with a thingshield and 4 relays and each of the relays is controlled by a virtual switch using the multiplexer smartapp.
I am now working on my NodeMCU ESP8266. I have it working with a DS18B20 temp probe and a single relay. The temp is showing correctly and I can control the relay but I am now trying to connect the relay to a virtual switch via the multiplexer and I cant seem to get it to work.
I am working my way through the code of the multiplexer, ST_AnyThing_Ethernet.device.groovy and the ST_Anything_ESP8266WiFi.ino and I cant seem to find the answer.
I have the temp set as my main tile for the device. The contact as tile 2 and the switch as tile 3. (currently)
I am trying to be able to use both the temp and switch off a single NodeMCU ESP8266 as a virtual thermostat.
Any suggestions.
thanks again…

If you only have 1 of each device capability defined in your sketch, there is no need for the Multiplxer SmartApp and virtual devices. Just make sure your devices in the sketch and the tiles in the DH are named the same as my ST_Anything_ESP8266.ino sketch.

Thanks. I’ll reread the DH guide…

My devices in the ST_Anything_ESP8266.ino sketch are named the same as the tiles in the DH. They work fine but I have the temp as the main tile showing on the Things view and the rest show on the device details screen. I am trying to get the relay switch to show in the Things view like I did with the multiplexer and virtual device on my Uno setup. I’m not seeing how to do that in the DH.

That’s very easy to change! Back in the v1.x ST Phone App, you could select any tile as the main tile for the device. ST broke this functionality when they released v2.x of the Phone Apps.

Simply change the following lines of code in the Device Handler to adjust the order of the tiles.

        main(["motion","temperature","humidity","illuminance","switch","contact","alarm","water"])
        details(["motion","temperature","humidity","illuminance","switch","contact","alarm","test","off","water","configure"])

For example, to have the Contact Sensor show up as the main tile for the device, change the first line as follows:

        main(["contact","motion","temperature","humidity","illuminance","switch","alarm","water"])
        details(["motion","temperature","humidity","illuminance","switch","contact","alarm","test","off","water","configure"])

I have that. I’m trying to get both the temperature and the switch to show on the Things view.
I have a virtual thermostat smartapp that uses 2 separate devices. A NodeMCU ESP8266 to sense the temp and then a second ‘off the shelf’ outlet control to activate a fan. I’m trying to use the relay and temp on a single NodeMCU ESP8266 with the virtual thermostat smartapp and to do that (unless I nave something wrong) I need to have both the temp and switch show on the Things view…

Looking for some ideas. I have the below in place and can see each individual motion sensor triggering when activated. The issue is that I can’t view the motion sensors outside of the Arduino/ST_Anything. I’m thinking this is done with multiplexing and virtual sensors but I’m not certain where to start. I have looked but don’t quite understand how it’s done.

//******************************************************************************************
// File: ST_Anything_WiFiEsp.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 + ESP-01 board 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 ESP-01 board.
//
// This example requires the use of an Arduino MEGA2560 since the ESP-01 WiFi board
// needs a high-speed UART for communications. This example assumes the ESP-01 is
// connected to the MEGA’s “Serial1” UART on pins 18 & 19.
//
//
// Change History:
//
// Date Who What
// ---- — ----
// 2015-01-03 Dan & Daniel Original Creation
// 2017-02-12 Dan Ogorchock Revised to use the new SMartThings v2.0 library
// 2017-02-20 Dan Ogorchock Revised to use the ESP-01 board
//
//******************************************************************************************
//******************************************************************************************
// SmartThings Library for Arduino + ESP-01 board combination.
//******************************************************************************************
#include <SmartThingsWiFiEsp.h> //Library to provide API to the SmartThings ESP-01 WiFi board

//******************************************************************************************
// 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 <Executor.h> //Generic Executor Class, typically receives data from ST Cloud (e.g. Switch)
#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_Illuminance.h> //Implements a Polling Sensor (PS) to measure light levels via a photo resistor

#include <PS_TemperatureHumidity.h> //Implements a Polling Sensor (PS) to measure Temperature and Humidity via DHT library
#include <PS_Water.h> //Implements a Polling Sensor (PS) to measure presence of water (i.e. leak detector)
#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_Button.h> //Implements an Interrupt Sensor (IS) to monitor the status of a digital input pin for button presses
#include <EX_Switch.h> //Implements an Executor (EX) via a digital output to a relay
#include <EX_Alarm.h> //Implements Executor (EX)as an Alarm Siren capability via a digital output to a relay

//**********************************************************************************************************
//Define which Arduino Pins will be used for each device
// Notes: Arduino communicates with the ESP-01 using the “Serial1” Hardware Serial UART.
// This is on digital pins 18 & 19 on the Mega.
//**********************************************************************************************************
//“RESERVED” pins for ESP-01 - best to avoid
#define PIN_18_RESERVED 18 //reserved ESP-01 on MEGA
#define PIN_19_RESERVED 19 //reserved ESP-01 on MEGA

#define PIN_WATER A4
#define PIN_ILLUMINANCE A5
#define PIN_TEMPERATUREHUMIDITY 5
#define PIN_MOTION0 6
#define PIN_MOTION1 2
#define PIN_MOTION2 3
#define PIN_MOTION3 4
#define PIN_CONTACT 7
#define PIN_SWITCH 8
#define PIN_ALARM 9
#define PIN_BUTTON1 10
#define PIN_BUTTON2 11

//******************************************************************************************
//WiFiEsp Information
//******************************************************************************************
String str_ssid = // <—You must edit this line!
String str_password = "; // <—You must edit this line!
IPAddress ip(; // Device IP Address // <—You must edit this line!
const unsigned int serverPort = 8090; // port to run the http server on

// Smartthings hub information
IPAddress hubIp( // smartthings hub ip // <—You must edit this line!
const unsigned int hubPort = 39500; // smartthings hub port

//******************************************************************************************
//st::Everything::callOnMsgSend() optional callback routine. This is a sniffer to monitor
// data being sent to ST. This allows a user to act on data changes locally within the
// Arduino sktech.
//******************************************************************************************
void callback(const String &msg)
{
Serial.print(F("ST_Anything Callback: Sniffed data = "));
Serial.println(msg);

//TODO: Add local logic here to take action when a device’s value/state is changed

//Masquerade as the ThingShield to send data to the Arduino, as if from the ST Cloud (uncomment and edit following line)
//st::receiveSmartString(“Put your command here!”); //use same strings that the Device Handler would send
}

//******************************************************************************************
//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 Hub in two separate updates, one for
// “temperature” and one for “humidity”)
//******************************************************************************************
//Polling Sensors
static st::PS_Illuminance sensor1(F(“illuminance”), 120, 0, PIN_ILLUMINANCE, 0, 1024, 0, 1000);
static st::PS_TemperatureHumidity sensor2(F(“temphumid”), 120, 10, PIN_TEMPERATUREHUMIDITY, st::PS_TemperatureHumidity::DHT22);
static st::PS_Water sensor3(F(“water”), 60, 20, PIN_WATER, 200);

//Interrupt Sensors
static st::IS_Motion sensor4(F(“motion0”), PIN_MOTION0, HIGH, false);
static st::IS_Motion sensor8(F(“motion1”), PIN_MOTION1, HIGH, false);
static st::IS_Motion sensor9(F(“motion2”), PIN_MOTION2, HIGH, false);
static st::IS_Motion sensor10(F(“motion3”), PIN_MOTION3, HIGH, false);

static st::IS_Contact sensor5(F(“contact”), PIN_CONTACT, LOW, true);
static st::IS_Button sensor6(F(“button:1”), PIN_BUTTON1);
static st::IS_Button sensor7(F(“button:2”), PIN_BUTTON2);

//Executors
static st::EX_Switch executor1(F(“switch”), PIN_SWITCH, LOW, true);
static st::EX_Alarm executor2(F(“alarm”), PIN_ALARM, LOW, true);

//*****************************************************************************
// Configure debug print output from each main class
//*****************************************************************************
st::Everything::debug=true;
st::Executor::debug=true;
st::Device::debug=true;
st::PollingSensor::debug=true;
st::InterruptSensor::debug=true;

//*****************************************************************************
//Initialize the “Everything” Class
//*****************************************************************************

//Initialize the optional local callback routine (safe to comment out if not desired)
st::Everything::callOnMsgSend = callback;

//Create the SmartThings WiFiEsp (ESP-01) Communications Object
st::Everything::SmartThing = new st::SmartThingsWiFiEsp(&Serial1, str_ssid, str_password, ip, serverPort, hubIp, hubPort, st::receiveSmartString);

//Initialize the Serial1 baudrate to match your ESP-01’s baud rate (e.g. 9600, 57600, 115200)
Serial1.begin(115200);

//Run the Everything class’ init() routine which establishes Ethernet communications with the SmartThings Hub
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);

//*****************************************************************************
//Add each executor to the “Everything” Class
//*****************************************************************************
st::Everything::addExecutor(&executor1);
st::Everything::addExecutor(&executor2);

//*****************************************************************************
//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();
}

Device Handler
/**

  • ST_Anything_Ethernet.device.groovy
  • Copyright 2017 Dan G 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

  • 2017-02-08 Dan Ogorchock Original Creation
  • 2017-02-12 Dan Ogorchock Modified to work with Ethernet based devices instead of ThingShield

*/

metadata {
definition (name: “ST_Anything_Ethernet”, namespace: “ogiewon”, author: “Dan Ogorchock”) {
capability "Configuration"
capability "Illuminance Measurement"
capability "Temperature Measurement"
capability "Relative Humidity Measurement"
capability "Water Sensor"
capability "Motion Sensor"
capability "Switch"
capability "Sensor"
capability "Alarm"
capability "Contact Sensor"
capability "Polling"
capability "Button"
capability “Holdable Button”

	command "test"
	command "alarmoff"
}

simulator {

}

// Preferences
preferences {
	input "ip", "text", title: "Arduino IP Address", description: "ip", required: true, displayDuringSetup: true
	input "port", "text", title: "Arduino Port", description: "port", required: true, displayDuringSetup: true
	input "mac", "text", title: "Arduino MAC Addr", description: "mac", required: true, displayDuringSetup: true
	input "illuminanceSampleRate", "number", title: "Light Sensor Inputs", description: "Sampling Interval (seconds)", defaultValue: 30, required: true, displayDuringSetup: true
	input "temphumidSampleRate", "number", title: "Temperature/Humidity Sensor Inputs", description: "Sampling Interval (seconds)", defaultValue: 30, required: true, displayDuringSetup: true
	input "waterSampleRate", "number", title: "Water Sensor Inputs", description: "Sampling Interval (seconds)", defaultValue: 30, required: true, displayDuringSetup: true
	input "numButtons", "number", title: "Number of Buttons", description: "Number of Buttons to be implemented", defaultValue: 0, required: true, displayDuringSetup: true

}

// Tile Definitions
tiles {
	valueTile("illuminance", "device.illuminance", width: 1, height: 1) {
		state("illuminance", label:'${currentValue} ${unit}', unit:"lux",
			backgroundColors:[
				[value: 9, color: "#767676"],
				[value: 315, color: "#ffa81e"],
				[value: 1000, color: "#fbd41b"]
			]
		)
	}        
    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("water", "device.water", width: 1, height: 1) {
		state "dry", icon:"st.alarm.water.dry", backgroundColor:"#ffffff"
		state "wet", icon:"st.alarm.water.wet", backgroundColor:"#53a7c0"
	}

	standardTile("motion0", "device.motion0", width: 1, height: 1) {
		state("active", label:'Kitchen', icon:"st.motion.motion.active", backgroundColor:"#53a7c0")
		state("inactive", label:'Kitchen', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff")
	}
    standardTile("motion1", "device.motion1", width: 1, height: 1) {
		state("active", label:'Droom', icon:"st.motion.motion.active", backgroundColor:"#53a7c0")
		state("inactive", label:'Droom', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff")
	}
    standardTile("motion2", "device.motion2", width: 1, height: 1) {
		state("active", label:'DStairs', icon:"st.motion.motion.active", backgroundColor:"#53a7c0")
		state("inactive", label:'DStairs', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff")
	}
    standardTile("motion3", "device.motion3", width: 1, height: 1) {
		state("active", label:'BroomUp', icon:"st.motion.motion.active", backgroundColor:"#53a7c0")
		state("inactive", label:'BroomUp', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff")
	}
    standardTile("switch", "device.switch", width: 1, height: 1, canChangeIcon: true) {
		state "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
		state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821"
	}

	standardTile("configure", "device.configure", inactiveLabel: false, decoration: "flat") {
		state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
	}

	standardTile("contact", "device.contact", width: 1, height: 1) {
		state("open", label:'${name}', icon:"st.contact.contact.open", backgroundColor:"#ffa81e")
		state("closed", label:'${name}', icon:"st.contact.contact.closed", backgroundColor:"#79b821")
	}

	standardTile("alarm", "device.alarm", width: 1, height: 1) {
		state "off", label:'off', action:'alarm.siren', icon:"st.alarm.alarm.alarm", backgroundColor:"#ffffff"
        state "strobe", label:'', action:'alarmoff', icon:"st.secondary.strobe", backgroundColor:"#cccccc"
        state "siren", label:'siren!', action:'alarmoff', icon:"st.alarm.beep.beep", backgroundColor:"#e86d13"
		state "both", label:'alarm!', action:'alarmoff', icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"
	}

	standardTile("test", "device.alarm", inactiveLabel: false, decoration: "flat") {
		state "default", label:'', action:"test", icon:"st.secondary.test"
	}
    
	standardTile("off", "device.alarm", , width: 1, height: 1) {
		state "default", label:'Alarm', action:"alarmoff", icon:"st.secondary.off"
	}
	//standardTile("off", "device.alarm", inactiveLabel: false, decoration: "flat") {
	//	state "default", label:'', action:"alarmoff", icon:"st.secondary.off"
	//}

    main(["motion1","temperature","humidity","illuminance","switch","contact","alarm","water","motion0","motion2","motion3"])
    details(["motion1","temperature","humidity","illuminance","switch","contact","alarm","test","off","water","configure","motion0","motion1","motion2","motion3"])
}

}

// parse events into attributes
def parse(String description) {
//log.debug "Parsing ‘${description}’"
def msg = parseLanMessage(description)
def headerString = msg.header

if (!headerString) {
	//log.debug "headerstring was null for some reason :("
}

def bodyString = msg.body

if (bodyString) {
    log.debug "BodyString: $bodyString"
	def parts = bodyString.split(" ")
	def name  = parts.length>0?parts[0].trim():null
	def value = parts.length>1?parts[1].trim():null
	def results = []
	if (name.startsWith("button")) {
    	def pieces = name.split(":")
        def btnName = pieces.length>0?pieces[0].trim():null
        def btnNum = pieces.length>1?pieces[1].trim():null
		//log.debug "In parse:  name = ${name}, value = ${value}, btnName = ${btnName}, btnNum = ${btnNum}"
    	results = createEvent([name: btnName, value: value, data: [buttonNumber: btnNum], descriptionText: "${btnName} ${btnNum} was ${value} ", isStateChange: true, displayed: true])
    }
    else {
		results = createEvent(name: name, value: value)
	}

	log.debug results
    return results

}

}

private getHostAddress() {
def ip = settings.ip
def port = settings.port

log.debug "Using ip: ${ip} and port: ${port} for device: ${device.id}"
return ip + ":" + port

}

def sendEthernet(message) {
log.debug "Executing ‘sendEthernet’ ${message}"
new physicalgraph.device.HubAction(
method: “POST”,
path: “/${message}?”,
headers: [ HOST: “${getHostAddress()}” ]
)
}

// handle commands

def on() {
log.debug "Executing ‘switch on’"
sendEthernet(“switch on”)
}

def off() {
log.debug "Executing ‘switch off’"
sendEthernet(“switch off”)
}

def alarmoff() {
log.debug "Executing ‘alarm off’"
sendEthernet(“alarm off”)
}

def strobe() {
log.debug "Executing ‘alarm strobe’"
sendEthernet(“alarm strobe”)
}

def siren() {
log.debug "Executing ‘alarm siren’"
sendEthernet(“alarm siren”)
}

def both() {
log.debug "Executing ‘alarm both’"
sendEthernet(“alarm both”)
}

def test() {
log.debug “Executing ‘alarm test’”
[
sendEthernet(“alarm both”),
“delay 3000”,
sendEthernet(“alarm off”)
]
}

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’"
updateDeviceNetworkID()
sendEvent(name: “numberOfButtons”, value: numButtons)
//log.debug "illuminance " + illuminanceSampleRate + "|temphumid " + temphumidSampleRate + "|water " + waterSampleRate
log.debug "water " + waterSampleRate
log.debug "illuminance " + illuminanceSampleRate
log.debug "temphumid " + temphumidSampleRate
[
sendEthernet("water " + waterSampleRate),
“delay 1000”,
sendEthernet("illuminance " + illuminanceSampleRate),
“delay 1000”,
sendEthernet("temphumid " + temphumidSampleRate)
]

}

def updateDeviceNetworkID() {
log.debug "Executing ‘updateDeviceNetworkID’"
if(device.deviceNetworkId!=mac) {
log.debug “setting deviceNetworkID = ${mac}“
device.setDeviceNetworkId(”${mac}”)
}
}

def updated() {
if (!state.updatedLastRanAt || now() >= state.updatedLastRanAt + 5000) {
state.updatedLastRanAt = now()
log.debug "Executing ‘updated’"
runIn(3, updateDeviceNetworkID)
sendEvent(name: “numberOfButtons”, value: numButtons)
}
else {
log.trace “updated(): Ran within last 5 seconds so aborting.”
}
}

def initialize() {
sendEvent(name: “numberOfButtons”, value: numButtons)
}

Nigel,

So…What we have here is effectively a “Multi Sensor” which means a device with more than one SmartThings Capability. For each device, only 1 of the capabilties can be exposed as the “main” capability.

Edit: Just re-read your reply above - A SmartApp does not need to “see” anything in the Things View. That is purely for display only. A SmartApp uses the Device Handler’s “Capabilities” list to determine what each device is capable of. As long as your tiles use the standard naming convention, which my base ST_Anything example sketches do, then any SmartApp can see these values from a multi-sensor device. If you’re still having issues, please post your Device Handler code so I can help you debug the issue.

Why is it so important to you to have both show up on the “Things View” in the Phone App? You could use something like SmartTiles/ActionTiles to create a custom display that will show you everything you want, from each of your devices, on a very nice-looking web-based display.

You could write a custom SmartApp to keep a separate virtual device up to date. While this works, it is not always 100% reliable. I use this technique for my “Multiplexer” SmartApps when I define more than one device of the same ST capability in an Arduino Sketch/ST Device Handler (for example, multiple Contact Sensors.) This is required because ST does not support having more than one of a given capability in a device handler. If I only have one of each capability, the normal behavior is exactly what my “ST_Anything” example code demonstrates. Simpler is always better, IMHO.

If you’re having trouble with writing a custom Multiplexer SmartApp, be careful to verify that the names of each device match exactly with the names in all of your code. The names are CaSe SeNsItIvE. :slight_smile:

There are some other options available as well like Simple Device Viewer which you might find helpful.

2 Likes