ady624 / webcore Goto Github PK
View Code? Open in Web Editor NEWwebCoRE is a web version of CoRE
License: GNU General Public License v3.0
webCoRE is a web version of CoRE
License: GNU General Public License v3.0
Hello-
Can you pls update the timezone list your application use? I live in Brazil and last quarter it has changed the daylight saving time rules and apparently it is not yet reflected here
I have a simple piston that turns on my lights if certain conditions are met + TIME is between 2 global variables (variables type = time). Piston code -> 49neg
The thing is, when the piston checks the is between condition, it returns false because 1 of the global variables has the year 1970...
Comparison 66708334 is_between 1970-01-01T16:00:00.000Z .. 2017-07-10T01:00:00.000Z = false (14ms)
Those are the values, in local time of my global variables used with this piston:
Any ideas of why the global variable gets set with the year 1970 and how to fix this?
Tks vm and congrats for the project, it is amazing!!
When I try to load the dashboard.webcore.co/fuel page, it shows a permanent spinner.
Looking at my developer console I can see an XHR request to https://api-us-f.webcore.co:9287/fuelStreams/list failing / timing out (after 21 seconds).
This then seems to result into an unhandled rejected Promise. See here: https://pastebin.com/cCz5kKmy
(note: I stripped the Auth Token from the paste).
Happy to provide more information to help debugging upon request!
Using registered browser Google Chrome via a Chromebook
Incognito window
I installed the SmartApp via the smart things site and using the GitHub Repos.
I believe I followed the instructions correctly.
I get 403 when attempting to create a piston.
I tried multiple Samsung smart things accounts.
Chrome log attached.
dashboard.webcore.co-1523810476888.log
I setup an array of integers and try to access them in a for loop. On the first iteration using $index, the array[0] returns 0 (or null if I log it alone without strings) no matter what. I can access array[0] without using index variable.
+374ms | ║index: 0; array: 0
+417ms | ║index: 1; array: 79
+456ms | ║index: 2; array: 77
+503ms | ║array[0]: 81; array[1]: 79; array[2] 77
Possibly a bug, for the button
attribute it only shows gets
as a trigger. For other attributes it shows a whole host of triggers.
This limits the way the button devices can be used since buttons are often held
which means they will continue to show held
as the status until they are released and the piston should be able to use the current status of a button in a if condition when triggered by another device.
e.g. keep holding the button which triggers a volume increase which triggers the piston which checks if the button is still held and then increases the volume and this continues in a loop into until the button is released.
Ideally it should show the same triggers as any other attribute (e.g. switch or alarm).
So, I am getting up to speed on WebCoRE. What I am trying to do is create a tri-state switch for controlling my HVAC states (Cooling, Heating, off).
I thought I would create 3 virtual switches for each state, and when one is turned on it will turn off the others.
What I am not sure about how to do is can the actuating switch set the state of the other switches WITHOUT triggering the piston for that switch?
Does that make sense?
I used it before deleting my webCoRE installation and lost all of my pistons as there's no way to restore from the backup file currently.
Disabling or displaying a warning would be sweet for users.
Thanks for the awesome project!
This is specifically to support ActionTiles which has limited to no capability to show any data from WebCoRE unless it is via a SmartThings supported device. ActionTiles does have capability to show images.
Request a way to add text to an image. Maybe each piston could have an 'external image' URL similar to the piston external URL. The new URL would return GIF or PNG(???) image as created by the piston new text2image commands. Some options to control font size would be useful as well (title larger font, footer info small font etc).
WebCore tiles are oviously very similar, so maybe they could be extended to provide an external image URL.
ImageMagick comes up frequently when searching net for 'adding text to image' Some possibly useful (???) resources....
http://im4java.sourceforge.net/
https://stackoverflow.com/questions/1636913/which-java-groovy-library-to-overlay-text-on-an-image
https://stackoverflow.com/questions/18800717/convert-text-content-to-image
I accidentally deleted the WebCoRE smartApp from Smartthings IDE. When I went back to try and add it back in through the settings button, I received the subject error message. I researched through the issues section and noted that a similar issue was resolved by logging out of github and then logging back in. This did not resolve the issue in my case.
I realize you are still in alpha. I just wanted to let you know of issue i was seeing in testing.
Error calling comparison comp_stays_greater_than_or_equal_to: groovy.lang.MissingMethodException: No signature of method: script1491876398496636377990.comp_stays_greater_than_or_equal_to() is applicable for argument types: (java.util.LinkedHashMap, java.util.LinkedHashMap, java.util.LinkedHashMap) values: [[logging:[error:true, warn:true, info:true, ...], ...], ...]
After creating /Publishing the Parent SmartApp (My Device Handler) , we attempt to create the Child SmartApp (My SmartApp) and observe this error -?-
Is there any obvious issues, or is there a method of troubleshot and verify that the syntax is correctly written, that can be recommended /thz -?-
Parent SmartApp
/*
definition(
name: "ABC Manager",
namespace: "stephack",
singleInstance: true,
author: "Stephan Hackett",
description: "Configure devices with buttons like the Aeon Labs Minimote and Lutron Pico Remotes.",
category: "My Apps",
iconUrl: "https://cdn.rawgit.com/stephack/ABC/master/resources/images/abcNew.png",
iconX2Url: "https://cdn.rawgit.com/stephack/ABC/master/resources/images/abcNew.png",
iconX3Url: "https://cdn.rawgit.com/stephack/ABC/master/resources/images/abcNew.png",
)
preferences {
page(name: "mainPage")
page(name: "aboutPage")
}
def mainPage() {
return dynamicPage(name: "mainPage", title: "", install: true, uninstall: true) {
def childApps = getAllChildApps()
def childVer = "InitialSetup"
if(childApps.size() > 0) {
childVer = childApps.first().version()
}
section("Create a new button device mapping.") {
app(name: "childApps", appName: "ABC Child Creator", namespace: "stephack", title: "New Button Device Mapping", multiple: true)
}
section("Version Info, User's Guide") {
href (name: "aboutPage", title: "Advanced Button Controller \n"+childVer,
description: "Tap to get Smartapp Info and User's Guide.",
image: verImgCheck(childVer), required: false, // check repo for image that matches current version. Displays update icon if missing
page: "aboutPage"
)
}
remove("Uninstall ABC App","WARNING!!","This will remove the ENTIRE SmartApp, including all configs listed above.")
}
}
def verImgCheck(childVer){
def params = [
uri: "https://cdn.rawgit.com/stephack/ABC/master/resources/images/abc_${childVer}.png",
]
try {
httpGet(params) { resp ->
resp.headers.each {
//log.debug "${it.name} : ${it.value}"
}
log.debug "ABC appears to be running the latest Version"
return params.uri
}
} catch (e) {
log.error "ABC does not appear to be the latest version: Please update from IDE"
return "https://cdn.rawgit.com/stephack/ABC/master/resources/images/update.png"
}
}
def installed() {
initialize()
}
def updated() {
unsubscribe()
initialize()
}
def initialize() {
}
private def textHelp() {
def text =
section("User's Guide - Advanced Button Controller") {
paragraph "This smartapp allows you to use a device with buttons including, but not limited to:\n\n Aeon Labs Minimotes\n"+
" HomeSeer HS-WD100+ switches**\n HomeSeer HS-WS100+ switches\n Lutron Picos***\n\n"+
"It is a heavily modified version of @DaleC's 'Button Controller Plus' which is in turn"+
" a version of @bravenel's 'Button Controller+'."
}
section("Some of the included changes are:"){
paragraph "A complete revamp of the configuration flow. You can now tell at a glance, what has been configured for each button."+
"The button configuration page has been collapsed by default for easier navigation."
paragraph "The original apps were hardcoded to allow configuring 4 or 6 button devices."+
" This app will automatically detect the number of buttons on your device or allow you to manually"+
" specify (only needed if device does not report on its own)."
paragraph "Allows you to give your buton device full speaker control including: Play/Pause, NextTrack, Mute, VolumeUp/Down."+
"(***Standard Pico remotes can be converted to Audio Picos)\n\nThe additional control options have been highlighted below."
}
section("Available Control Options are:"){
paragraph " Switches - Toggle \n"+
" Switches - Turn On \n"+
" Switches - Turn Off \n"+
" Dimmers - Toggle \n"+
" Dimmers - Set Level (Group 1) \n"+
" Dimmers - Set Level (Group 2) \n"+
" *Dimmers - Inc Level \n"+
" Dimmers - Dec Level \n"+
" Fans - Low, Medium, High, Off \n"+
" Shades - Up, Down, or Stop \n"+
" Locks - Unlock Only \n"+
" Speaker - Play/Pause \n"+
" Speaker - Next Track \n"+
" Speaker - Mute/Unmute \n"+
" Speaker - Volume Up \n"+
" Speaker - Volume Down \n"+
" Set Modes \n"+
" Run Routines \n"+
" Sirens - Toggle \n"+
" Push Notifications \n"+
" SMS Notifications"
}
section (" Quirk for HS-WD100+ on Button 5 & 6:"){
paragraph "Because a dimmer switch already uses Press&Hold to manually set the dimming level"+
" please be aware of this operational behavior. If you only want to manually change"+
" the dim level to the lights that are wired to the switch, you will automatically"+
" trigger the 5/6 button event as well. And the same is true in reverse. If you"+
" only want to trigger a 5/6 button event action with Press&Hold, you will be manually"+
" changing the dim level of the switch simultaneously as well.\n"+
"This quirk doesn't exist of course with the HS-HS100+ since it is not a dimmer."
}
section(" Lutron Pico Requirements:"){
paragraph "Lutron Picos are not natively supported by SmartThings. A Lutron SmartBridge Pro, a device running @njschwartz's python script (or node.js) and the Lutron Caseta Service Manager"+
" SmartApp are also required for this functionality!\nSearch the forums for details."
}
}
Child SmartApp
/* DO NOT PUBLISH !!!!
*
- small adjustments to "Configure Button" page layout
definition(
name: "ABC Child Creator",
namespace: "stephack",
author: "Stephan Hackett",
description: "SHOULD NOT BE PUBLISHED",
category: "My Apps",
parent: "stephack:ABC Manager",
iconUrl: "https://cdn.rawgit.com/stephack/ABC/master/resources/images/abcNew.png",
iconX2Url: "https://cdn.rawgit.com/stephack/ABC/master/resources/images/abcNew.png",
iconX3Url: "https://cdn.rawgit.com/stephack/ABC/master/resources/images/abcNew.png",
)
preferences {
page(name: "chooseButton")
page(name: "configButtonsPage")
page(name: "timeIntervalInput", title: "Only during a certain time") {
section {
input "starting", "time", title: "Starting", required: false
input "ending", "time", title: "Ending", required: false
}
}
}
def chooseButton() {
dynamicPage(name: "chooseButton", install: true, uninstall: true) {
section("Step 1: Select Your Button Device") {
input "buttonDevice", "capability.button", title: "Button Device", multiple: false, required: true, submitOnChange: true
}
if(buttonDevice){
state.buttonType = buttonDevice.typeName
if(state.buttonType.contains("Aeon Minimote")) state.buttonType = "Aeon Minimote"
log.debug "Device Type is now set to: "+state.buttonType
state.buttonCount = manualCount?: buttonDevice.currentValue('numberOfButtons')
//if(state.buttonCount==null) state.buttonCount = buttonDevice.currentValue('numButtons') //added for kyse minimote(hopefully will be updated to correct attribute name)
section("Step 2: Configure Your Buttons"){
if(state.buttonCount<1) {
paragraph "The selected button device did not report the number of buttons it has. Please specify in the Advanced Config section below."
}
else {
for(i in 1..state.buttonCount){
href "configButtonsPage", title: "Button ${i} - (Tap to Edit)", description: getDescription(i), params: [pbutton: i]
}
}
}
}
section("Set Custom Name (Optional)") {
label title: "Assign a name:", required: false
}
section("Advanced Config:", hideable: true, hidden: hideOptionsSection()) {
input "manualCount", "number", title: "Set/Override # of Buttons?", required: false, description: "Only set if DTH does not report", submitOnChange: true
input "collapseAll", "bool", title: "Collapse Unconfigured Sections?", defaultValue: true
input "hwSpecifics", "bool", title: "Hide H/W Specific Details?", defaultValue: false
}
section(title: "Only Execute When:", hideable: true, hidden: hideOptionsSection()) {
def timeLabel = timeIntervalLabel()
href "timeIntervalInput", title: "Only during a certain time", description: timeLabel ?: "Tap to set", state: timeLabel ? "complete" : null
input "days", "enum", title: "Only on certain days of the week", multiple: true, required: false,
options: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
input "modes", "mode", title: "Only when mode is", multiple: true, required: false
}
}
}
def configButtonsPage(params) {
if (params.pbutton != null) state.currentButton = params.pbutton.toInteger()
dynamicPage(name: "configButtonsPage", title: "CONFIGURE BUTTON ${state.currentButton}:\n${state.buttonType}", getButtonSections(state.currentButton))
}
def getButtonSections(buttonNumber) {
return {
def picNameNoSpace = "${state.buttonType}${state.currentButton}.png"-" "-" "-" "-"/"
//log.debug picNameNoSpace
section(){ //"Hardware specific info on button selection:") {
if(hwSpecifics== false) paragraph image: "https://cdn.rawgit.com/stephack/ABC/master/resources/images/${picNameNoSpace}", "${getSpecText()}"
}
section("Switches (Turn On)", hideable: true, hidden: !shallHide("lightOn_${buttonNumber}")) {
input "lightOn_${buttonNumber}pushed", "capability.switch", title: "When Pushed", multiple: true, required: false, submitOnChange: collapseAll
if(showHeld()) input "lightOn${buttonNumber}held", "capability.switch", title: "When Held", multiple: true, required: false, submitOnChange: collapseAll
}
section("Switches (Turn Off)", hideable: true, hidden: !shallHide("lightOff${buttonNumber}")) {
input "lightOff_${buttonNumber}pushed", "capability.switch", title: "When Pushed", multiple: true, required: false, submitOnChange: collapseAll
if(showHeld()) input "lightOff${buttonNumber}held", "capability.switch", title: "When Held", multiple: true, required: false, submitOnChange: collapseAll
}
section("Switches (Toggle On/Off)", hideable: true, hidden: !shallHide("lights${buttonNumber}")) {
input "lights_${buttonNumber}pushed", "capability.switch", title: "When Pushed", multiple: true, required: false, submitOnChange: collapseAll
if(showHeld()) input "lights${buttonNumber}held", "capability.switch", title: "When Held", multiple: true, required: false, submitOnChange: collapseAll
}
section(" "){}
section("Dimmers (On to Level - Group 1)", hideable: true, hidden: !(shallHide("lightDim${buttonNumber}") || shallHide("valLight${buttonNumber}"))) {
input "lightDim_${buttonNumber}pushed", "capability.switchLevel", title: "When Pushed", multiple: true, required: false, submitOnChange: collapseAll
input "valLight${buttonNumber}pushed", "number", title: "Bright Level", multiple: false, required: false, description: "0 to 100%"
if(showHeld()) input "lightDim${buttonNumber}held", "capability.switchLevel", title: "When Held", multiple: true, required: false, submitOnChange: collapseAll
if(showHeld()) input "valLight${buttonNumber}held", "number", title: "Bright Level", multiple: false, required: false, description: "0 to 100%"
}
section("Dimmers (On to Level - Group 2)", hideable: true, hidden: !(shallHide("lightD2m${buttonNumber}") || shallHide("valLight2${buttonNumber}"))) {
input "lightD2m${buttonNumber}pushed", "capability.switchLevel", title: "When Pushed", multiple: true, required: false, submitOnChange: collapseAll
input "valLight2${buttonNumber}pushed", "number", title: "Bright Level", multiple: false, required: false, description: "0 to 100%"
if(showHeld()) input "lightD2m${buttonNumber}held", "capability.switchLevel", title: "When Held", multiple: true, required: false, submitOnChange: collapseAll
if(showHeld()) input "valLight2${buttonNumber}held", "number", title: "Bright Level", multiple: false, required: false, description: "0 to 100%"
}
section("Dimmers (Increase Level By)", hideable: true, hidden: !(shallHide("dimPlus${buttonNumber}") || shallHide("valDimP${buttonNumber}"))) {
input "dimPlus${buttonNumber}pushed", "capability.switchLevel", title: "When Pushed", multiple: true, required: false, submitOnChange: collapseAll
input "valDimP${buttonNumber}pushed", "number", title: "When Pushed Increase by", multiple: false, required: false, description: "0 to 15"
if(showHeld()) input "dimPlus${buttonNumber}held", "capability.switchLevel", title: "When Held", multiple: true, required: false, submitOnChange: collapseAll
if(showHeld()) input "valDimP${buttonNumber}held", "number", title: "When Held Increase by", multiple: false, required: false, description: "0 to 15"
}
section("Dimmers (Decrease Level By)", hideable: true, hidden: !(shallHide("dimMinus${buttonNumber}") || shallHide("valDimM${buttonNumber}"))) {
input "dimMinus${buttonNumber}pushed", "capability.switchLevel", title: "When Pushed", multiple: true, required: false, submitOnChange: collapseAll
input "valDimM${buttonNumber}pushed", "number", title: "When Pushed Decrease by", multiple: false, required: false, description: "0 to 15"
if(showHeld()) input "dimMinus${buttonNumber}held", "capability.switchLevel", title: "When Held", multiple: true, required: false, submitOnChange: collapseAll
if(showHeld()) input "valDimM${buttonNumber}held", "number", title: "When Held Decrease by", multiple: false, required: false, description: "0 to 15"
}
section("Dimmers (Toggle OnToLevel/Off)", hideable: true, hidden: !(shallHide("lightsDT${buttonNumber}") || shallHide("valDT${buttonNumber}"))) {
input "lightsDT${buttonNumber}pushed", "capability.switchLevel", title: "When Pushed", multiple: true, required: false, submitOnChange: collapseAll
input "valDT${buttonNumber}pushed", "number", title: "Bright Level", required: false, description: "0 to 100%"
if(showHeld()) input "lightsDT${buttonNumber}held", "capability.switchLevel", title: "When Held", multiple: true, required: false, submitOnChange: collapseAll
if(showHeld()) input "valDT${buttonNumber}held", "number", title: "Bright Level", required: false, description: "0 to 100%"
}
section(" "){}
section("Speakers (Toggle Play/Pause)", hideable: true, hidden: !shallHide("speakerpp${buttonNumber}")) {
input "speakerpp${buttonNumber}pushed", "capability.musicPlayer", title: "When Pushed", multiple: true, required: false, submitOnChange: collapseAll
if(showHeld()) input "speakerpp${buttonNumber}held", "capability.musicPlayer", title: "When Held", multiple: true, required: false, submitOnChange: collapseAll
}
section("Speakers (Increase Vol By)", hideable: true, hidden: !(shallHide("speakervu${buttonNumber}") || shallHide("valSpeakU${buttonNumber}"))) {
input "speakervu${buttonNumber}pushed", "capability.musicPlayer", title: "When Pushed", multiple: true, required: false, submitOnChange: collapseAll
input "valSpeakU${buttonNumber}pushed", "number", title: "When Pushed Increase by", multiple: false, required: false, description: "0 to 15"
if(showHeld()) input "speakervu${buttonNumber}held", "capability.musicPlayer", title: "When Held", multiple: true, required: false, submitOnChange: collapseAll
if(showHeld()) input "valSpeakU${buttonNumber}held", "number", title: "When Held Increase by", multiple: false, required: false, description: "0 to 15"
}
section("Speakers (Decrease Vol By)", hideable: true, hidden: !(shallHide("speakervd${buttonNumber}") || shallHide("valSpeakD${buttonNumber}"))) {
input "speakervd${buttonNumber}pushed", "capability.musicPlayer", title: "When Pushed", multiple: true, required: false, submitOnChange: collapseAll
input "valSpeakD${buttonNumber}pushed", "number", title: "When Pushed Decrease by", multiple: false, required: false, description: "0 to 15"
if(showHeld())input "speakervd${buttonNumber}held", "capability.musicPlayer", title: "When Held", multiple: true, required: false, submitOnChange: collapseAll
if(showHeld())input "valSpeakD${buttonNumber}held", "number", title: "When Held Decrease by", multiple: false, required: false, description: "0 to 15"
}
section("Speakers (Go to Next Track)", hideable: true, hidden: !shallHide("speakernt${buttonNumber}")) {
input "speakernt${buttonNumber}pushed", "capability.musicPlayer", title: "When Pushed", multiple: true, required: false, submitOnChange: collapseAll
if(showHeld()) input "speakernt${buttonNumber}held", "capability.musicPlayer", title: "When Held", multiple: true, required: false, submitOnChange: collapseAll
}
section("Speakers (Toggle Mute/Unmute)", hideable: true, hidden: !shallHide("speakermu${buttonNumber}")) {
input "speakermu${buttonNumber}pushed", "capability.musicPlayer", title: "When Pushed", multiple: true, required: false, submitOnChange: collapseAll
if(showHeld()) input "speakermu${buttonNumber}held", "capability.musicPlayer", title: "When Held", multiple: true, required: false, submitOnChange: collapseAll
}
section(" "){}
section("Sirens (Toggle)", hideable: true, hidden: !shallHide("sirens${buttonNumber}")) {
input "sirens${buttonNumber}pushed","capability.alarm" ,title: "When Pushed", multiple: true, required: false, submitOnChange: collapseAll
if(showHeld()) input "sirens${buttonNumber}held", "capability.alarm", title: "When Held", multiple: true, required: false, submitOnChange: true
}
section("Locks (Lock Only)", hideable: true, hidden: !shallHide("locks${buttonNumber}")) {
input "locks${buttonNumber}pushed", "capability.lock", title: "When Pushed", multiple: true, required: false, submitOnChange: collapseAll
if(showHeld()) input "locks${buttonNumber}held", "capability.lock", title: "When Held", multiple: true, required: false, submitOnChange: collapseAll
}
section("Fans (Adjust - Low, Medium, High, Off)", hideable: true, hidden: !shallHide("fanAdjust${buttonNumber}")) {
input "fanAdjust${buttonNumber}pushed", "capability.switchLevel", title: "When Pushed", multiple: true, required: false, submitOnChange: collapseAll
if(showHeld()) input "fanAdjust${buttonNumber}held", "capability.switchLevel", title: "When Held", multiple: true, required: false, submitOnChange: collapseAll
}
section("Shades (Adjust - Up, Down, or Stop)", hideable: true, hidden: !shallHide("shadeAdjust${buttonNumber}")) {
input "shadeAdjust${buttonNumber}pushed", "capability.doorControl", title: "When Pushed", multiple: true, required: false, submitOnChange: collapseAll
if(showHeld()) input "shadeAdjust${buttonNumber}held", "capability.doorControl", title: "When Held", multiple: true, required: false, submitOnChange: collapseAll
}
section(" "){}
section("Set Mode", hideable: true, hidden: !shallHide("mode${buttonNumber}")) {
input "mode${buttonNumber}pushed", "mode", title: "When Pushed", required: false, submitOnChange: collapseAll
if(showHeld())input "mode${buttonNumber}held", "mode", title: "When Held", required: false, submitOnChange: collapseAll
}
def phrases = location.helloHome?.getPhrases()*.label
if (phrases) {
section("Run Routine", hideable: true, hidden: !shallHide("phrase${buttonNumber}")) {
//log.trace phrases
input "phrase_${buttonNumber}pushed", "enum", title: "When Pushed", required: false, options: phrases, submitOnChange: collapseAll
if(showHeld()) input "phrase${buttonNumber}held", "enum", title: "When Held", required: false, options: phrases, submitOnChange: collapseAll
}
}
section("Notifications:\nSMS, In App or Both", hideable: true, hidden: !shallHide("notifications${buttonNumber}")) {
paragraph "\nWHEN PUSHED\n"
input "notifications_${buttonNumber}pushed", "text", title: "Message", description: "Enter message to send", required: false, submitOnChange: collapseAll
input "phone${buttonNumber}_pushed","phone" ,title: "Send Text To", description: "Enter phone number", required: false, submitOnChange: collapseAll
input "valNotify${buttonNumber}pushed","bool" ,title: "Notify In App?", required: false, defaultValue: false, submitOnChange: collapseAll
if(showHeld()) paragraph "\nWHEN HELD\n"
if(showHeld()) input "notifications${buttonNumber}held", "text", title: "Message", description: "Enter message to send", required: false, submitOnChange: collapseAll
if(showHeld()) input "phone${buttonNumber}held", "phone", title: "Send Text To", description: "Enter phone number", required: false, submitOnChange: collapseAll
if(showHeld()) input "valNotify${buttonNumber}held", "bool", title: "Notify In App?", required: false, defaultValue: false, submitOnChange: collapseAll
}
if(enableSpec()){
section(" "){}
section("Special", hideable: true, hidden: !shallHide("container${buttonNumber}")) {
input "container${buttonNumber}pushed", "device.VirtualContainer", title: "When Pushed", required: false, submitOnChange: collapseAll
if(showHeld())input "container${buttonNumber}_held", "device.VirtualContainer", title: "When Held", required: false, submitOnChange: collapseAll
}
}
}
}
def enableSpec() {
return false
}
def showHeld() {
if(state.buttonType.contains("100+ ")) return false
else return true
}
def shallHide(myFeature) {
if(collapseAll) return (settings["${myFeature}_pushed"]||settings["${myFeature}_held"]||settings["${myFeature}"])
return true
}
def getDescription(dNumber) {
def descript = "Nothing Configured"
def anySettings = settings.find{it.key.contains("${dNumber}")}
if(anySettings) descript = "PUSHED:"+getDescDetails(dNumber,"_pushed")+"\n\nHELD:"+getDescDetails(dNumber,"_held")//"CONFIGURED : Tap to edit"
return descript
}
def getDescDetails(bNum, type){
def numType=bNum+type
def preferenceNames = settings.findAll{it.key.contains("_${numType}")}.sort() //get all configured settings that: match button# and type, AND are not false
if(!preferenceNames){
return " Not Configured"
}
else {
def formattedPage =""
preferenceNames.each {eachPref->
def prefDetail = getPreferenceDetails().find{eachPref.key.contains(it.id)} //gets decription of action being performed(eg Turn On)
def prefDevice = " : ${eachPref.value}" - "[" - "]" //name of device the action is being performed on (eg Bedroom Fan)
def prefSubValue = settings[prefDetail.sub + numType]?:"(!Missing!)"
if(prefDetail.type=="normal") formattedPage += "\n- ${prefDetail.desc}${prefDevice}"
if(prefDetail.type=="hasSub") formattedPage += "\n- ${prefDetail.desc}${prefSubValue}${prefDevice}"
if(prefDetail.type=="bool") formattedPage += "\n- ${prefDetail.desc}"
}
return formattedPage
}
}
def installed() {
initialize()
}
def updated() {
unsubscribe()
initialize()
}
def initialize() {
log.debug "INITIALIZED with settings: ${settings}"
app.label==app.name?app.updateLabel(defaultLabel()):app.updateLabel(app.label)
subscribe(buttonDevice, "button", buttonEvent)
state.lastshadesUp = true
}
def defaultLabel() {
return "${buttonDevice} Mapping"
}
def getPreferenceDetails(){
def detailMappings =
[[id:'lights_',desc:'Toggle On/Off',comm:toggle, type:"normal"],
[id:'lightsDT_', desc:'Toggle Off/Dim to ', comm:dimToggle, sub:"valDT", type:"hasSub"],
[id:'lightOn_',desc:'Turn On ',comm:turnOn, type:"normal"],
[id:"lightOff_",desc:'Turn Off',comm:turnOff, type:"normal"],
[id:"lightDim_",desc:'Dim to ',comm:turnDim, sub:"valLight", type:"hasSub"],
[id:"lightD2m_",desc:'Dim to ',comm:turnDim, sub:"valLight2", type:"hasSub"],
[id:'dimPlus_',desc:'Brightness +',comm:levelUp, sub:"valDimP", type:"hasSub"],
[id:'dimMinus_',desc:'Brightness -',comm:levelDown, sub:"valDimM", type:"hasSub"],
[id:"fanAdjust_",desc:'Adjust',comm:adjustFan, type:"normal"],
[id:"shadeAdjust_",desc:'Adjust',comm:adjustShade, type:"normal"],
[id:"locks_",desc:'Lock',comm:setUnlock, type:"normal"],
[id:"speakerpp_",desc:'Toggle Play/Pause',comm:speakerplaystate, type:"normal"],
[id:'speakernt_',desc:'Next Track',comm:speakernexttrack, type:"normal"],
[id:'speakermu_',desc:'Mute',comm:speakermute, type:"normal"],
[id:'speakervu_',desc:'Volume +',comm:levelUp, sub:"valSpeakU", type:"hasSub"],
[id:"speakervd_",desc:'Volume -',comm:levelDown, sub:"valSpeakD", type:"hasSub"],
[id:"mode_",desc:'Set Mode',comm:changeMode, type:"normal"],
[id:"notifications_",desc:'Send Push Notification',comm:messageHandle, sub:"valNotify", type:"bool"],
[id:'sirens_',desc:'Toggle',comm:toggle, type:"normal"],
[id:"phone_",desc:'Send SMS',comm:smsHandle, sub:"notifications_", type:"normal"],
[id:"phrase_",desc:'Run Routine',comm:runRout, type:"normal"],
[id:"container_",desc:'Cycle Playlist',comm:cyclePL, type:"normal"],
]
return detailMappings
}
def buttonEvent(evt) {
if(allOk) {
def buttonNumber = evt.jsonData.buttonNumber
def pressType = evt.value
log.debug "$buttonDevice: Button $buttonNumber was $pressType"
def preferenceNames = settings.findAll{it.key.contains("${buttonNumber}${pressType}")}
preferenceNames.each{eachPref->
def prefDetail = getPreferenceDetails()?.find{eachPref.key.contains(it.id)} //returns the detail map of id,desc,comm,sub
def PrefSubValue = settings["${prefDetail.sub}${buttonNumber}_${pressType}"] //value of subsetting (eg 100)
if(prefDetail.sub) "$prefDetail.comm"(eachPref.value,PrefSubValue)
else "$prefDetail.comm"(eachPref.value)
}
}
}
def turnOn(devices) {
log.debug "Turning On: $devices"
devices.on()
}
def turnOff(devices) {
log.debug "Turning Off: $devices"
devices.off()
}
def turnDim(devices, level) {
log.debug "Dimming (to $level): $devices"
devices.setLevel(level)
}
def adjustFan(device) {
log.debug "Adjusting: $device"
def currentLevel = device.currentLevel
if(device.currentSwitch == 'off') device.setLevel(15)
else if (currentLevel < 34) device.setLevel(50)
else if (currentLevel < 67) device.setLevel(90)
else device.off()
}
def adjustShade(device) {
log.debug "Shades:
if(device.currentMotor in ["up","down"]) {
state.lastshadesUp = device.currentMotor == "up"
device.stop()
} else {
state.lastshadesUp ? device.down() : device.up()
// if(state.lastshadesUp) device.down()
// else device.up()
state.lastshadesUp = !state.lastshadesUp
}
}
def speakerplaystate(device) {
log.debug "Toggling Play/Pause: $device"
device.currentValue('status').contains('playing')? device.pause() : device.play()
}
def speakernexttrack(device) {
log.debug "Next Track Sent to: $device"
device.nextTrack()
}
def speakermute(device) {
log.debug "Toggling Mute/Unmute: $device"
device.currentValue('mute').contains('unmuted')? device.mute() : device.unmute()
}
def levelUp(device, inclevel) {
log.debug "Incrementing Level (by +$inclevel: $device"
def currentVol = device.currentValue('level')[0] //currentlevel return a list...[0] is first item in list ie volume level
def newVol = currentVol + inclevel
device.setLevel(newVol)
log.debug "Level increased by $inclevel to $newVol"
}
def levelDown(device, declevel) {
log.debug "Decrementing Level (by -declevel: $device"
def currentVol = device.currentValue('level')[0]
def newVol = currentVol.toInteger()-declevel
device.setLevel(newVol)
log.debug "Level decreased by $declevel to $newVol"
}
def setUnlock(devices) {
log.debug "Locking: $devices"
devices.lock()
}
def toggle(devices) {
log.debug "Toggling: $devices"
if (devices*.currentValue('switch').contains('on')) {
devices.off()
}
else if (devices*.currentValue('switch').contains('off')) {
devices.on()
}
else if (devices*.currentValue('alarm').contains('off')) {
devices.siren()
}
else {
devices.on()
}
}
def dimToggle(devices, dimLevel) {
log.debug "Toggling On/Off | Dimming (to $dimLevel): $devices"
if (devices*.currentValue('switch').contains('on')) devices.off()
else devices.setLevel(dimLevel)
}
def runRout(rout){
log.debug "Running: $rout"
location.helloHome.execute(rout)
}
def messageHandle(msg, inApp) {
if(inApp==true) {
log.debug "Push notification sent"
sendPush(msg)
}
}
def smsHandle(phone, msg){
log.debug "SMS sent"
sendSms(phone, msg ?:"No custom text entered on: $app.label")
}
def changeMode(mode) {
log.debug "Changing Mode to: $mode"
if (location.mode != mode && location.modes?.find { it.name == mode }) setLocationMode(mode)
}
def cyclePL(device) {
//int currPL = device.currentValue('lastRun')
// int nextPL = currPL+1
device.cycleChild()
//device.on(nextPL)
}
// execution filter methods
private getAllOk() {
modeOk && daysOk && timeOk
}
private getModeOk() {
def result = !modes || modes.contains(location.mode)
log.trace "modeOk = $result"
result
}
private getDaysOk() {
def result = true
if (days) {
def df = new java.text.SimpleDateFormat("EEEE")
if (location.timeZone) {
df.setTimeZone(location.timeZone)
}
else {
df.setTimeZone(TimeZone.getTimeZone("America/New_York"))
}
def day = df.format(new Date())
result = days.contains(day)
}
log.trace "daysOk = $result"
result
}
private getTimeOk() {
def result = true
if (starting && ending) {
def currTime = now()
def start = timeToday(starting).time
def stop = timeToday(ending).time
result = start < stop ? currTime >= start && currTime <= stop : currTime <= stop || currTime >= start
}
log.trace "timeOk = $result"
result
}
private hhmm(time, fmt = "h:mm a") {
def t = timeToday(time, location.timeZone)
def f = new java.text.SimpleDateFormat(fmt)
f.setTimeZone(location.timeZone ?: timeZone(time))
f.format(t)
}
private hideOptionsSection() {
(starting || ending || days || modes || manualCount) ? false : true
}
private timeIntervalLabel() {
(starting && ending) ? hhmm(starting) + "-" + hhmm(ending, "h:mm a z") : ""
}
private def textHelp() {
def text =
section("User's Guide - Advanced Button Controller") {
paragraph "This smartapp allows you to use a device with buttons including, but not limited to:\n\n Aeon Labs Minimotes\n"+
" HomeSeer HS-WD100+ switches**\n HomeSeer HS-WS100+ switches\n Lutron Picos***\n\n"+
"It is a heavily modified version of @DaleC's 'Button Controller Plus' which is in turn"+
" a version of @bravenel's 'Button Controller+'."
}
section("Some of the included changes are:"){
paragraph "A complete revamp of the configuration flow. You can now tell at a glance, what has been configured for each button."+
"The button configuration page has been collapsed by default for easier navigation."
paragraph "The original apps were hardcoded to allow configuring 4 or 6 button devices."+
" This app will automatically detect the number of buttons on your device or allow you to manually"+
" specify (only needed if device does not report on its own)."
paragraph "Allows you to give your buton device full speaker control including: Play/Pause, NextTrack, Mute, VolumeUp/Down."+
"(***Standard Pico remotes can be converted to Audio Picos)\n\nThe additional control options have been highlighted below."
}
section("Available Control Options are:"){
paragraph " Switches - Toggle \n"+
" Switches - Turn On \n"+
" Switches - Turn Off \n"+
" Dimmers - Toggle \n"+
" Dimmers - Set Level (Group 1) \n"+
" Dimmers - Set Level (Group 2) \n"+
" *Dimmers - Inc Level \n"+
" Dimmers - Dec Level \n"+
" Fans - Low, Medium, High, Off \n"+
" Shades - Up, Down, or Stop \n"+
" Locks - Unlock Only \n"+
" Speaker - Play/Pause \n"+
" Speaker - Next Track \n"+
" Speaker - Mute/Unmute \n"+
" Speaker - Volume Up \n"+
" Speaker - Volume Down \n"+
" Set Modes \n"+
" Run Routines \n"+
" Sirens - Toggle \n"+
" Push Notifications \n"+
" SMS Notifications"
}
section (" Quirk for HS-WD100+ on Button 5 & 6:"){
paragraph "Because a dimmer switch already uses Press&Hold to manually set the dimming level"+
" please be aware of this operational behavior. If you only want to manually change"+
" the dim level to the lights that are wired to the switch, you will automatically"+
" trigger the 5/6 button event as well. And the same is true in reverse. If you"+
" only want to trigger a 5/6 button event action with Press&Hold, you will be manually"+
" changing the dim level of the switch simultaneously as well.\n"+
"This quirk doesn't exist of course with the HS-HS100+ since it is not a dimmer."
}
section(" Lutron Pico Requirements:"){
paragraph "Lutron Picos are not natively supported by SmartThings. A Lutron SmartBridge Pro, a device running @njschwartz's python script (or node.js) and the Lutron Caseta Service Manager"+
" SmartApp are also required for this functionality!\nSearch the forums for details."
}
}
def getSpecText(){
if(state.buttonType == "Lutron Pico") {
switch (state.currentButton){
case 1: return "Top Button"; break
case 2: return "Bottom Button"; break
case 3: return "Middle Button";break
case 4: return "Up Button"; break
case 5: return "Down Button"; break
}
}
if(state.buttonType.contains("Aeon Minimote")) {
switch (state.currentButton){
case 1: return "Top Left Button"; break
case 2: return "Top Right Button"; break
case 3: return "Lower Left Button";break
case 4: return "Lower Right"; break
}
}
if(state.buttonType.contains("WD100+ Dimmer")) {
switch (state.currentButton){
case 1: return "Double-Tap Upper Paddle"; break
case 2: return "Double-Tap Lower Paddle"; break
case 3: return "Triple-Tap Upper Paddle";break
case 4: return "Triple-Tap Lower Paddle"; break
case 5: return "Press & Hold Upper Paddle\n(See user guide for quirks)"; break
case 6: return "Press & Hold Lower Paddle\n(See user guide for quirks)"; break
case 7: return "Single Tap Upper Paddle\n(See user guide for quirks)"; break
case 8: return "Single Tap Lower Paddle\n(See user guide for quirks)"; break
}
}
if(state.buttonType.contains("WS100+ Switch")) {
switch (state.currentButton){
case 1: return "Double-Tap Upper Paddle"; break
case 2: return "Double-Tap Lower Paddle"; break
case 3: return "Triple-Tap Upper Paddle";break
case 4: return "Triple-Tap Lower Paddle"; break
case 5: return "Press & Hold Upper Paddle"; break
case 6: return "Press & Hold Lower Paddle"; break
case 7: return "Single Tap Upper Paddle";break
case 8: return "Single Tap Lower Paddle"; break
}
}
if(state.buttonType.contains("Inovelli")) {
switch (state.currentButton){
case 1: return "NOT OPERATIONAL - DO NOT USE"; break
case 2: return "2X Tap Upper Paddle = Pushed\n2X Tap Lower Paddle = Held"; break
case 3: return "3X Tap Upper Paddle = Pushed\n3X Tap Lower Paddle = Held"; break
case 4: return "4X Tap Upper Paddle = Pushed\n4X Tap Lower Paddle = Held";break
case 5: return "5X Tap Upper Paddle = Pushed\n5X Tap Lower Paddle = Held"; break
case 6: return "Hold Upper Paddle = Pushed\nHold Lower Paddle = Held"; break
}
}
return "Not Specified By Device"
}
/*FOR NEW INPUTS//////////////
FOR NEW BUTTON DEVICE TYPES///////////////
*/
I notice several of my pistons run when they don't actually need to. This may just be a limitation of SmartThings and event subscriptions, but there are a wide variety of events which can be referenced in a piston which don't need to be subscribed to 24/7. They basically boil down to patterns of A && B && C; if A is currently false, events from B and C are irrelevant and can be ignored. (For example, my logs are filled with motion sensor triggers by my cats while the location is in a mode that doesn't actually do anything when motion is detected.)
(Events of the type "rises above" or "stays" do this too, though that seems somewhat unavoidable. They might be handled in a layer above the piston, but something still has to run enough to see whether the condition has returned to a state where the event can take place in the future.)
When using "Changes to" as a trigger, it misses a lot of events. This has been verified by another forum member. However "On Event" works 100%. Seems to miss ~35% of events.
I created 3 pistons.
Testing - Changes To (import code: wdt3)
This piston increments a variable each time a virtual momentary button gets pressed. It detected it being pressed by using "Changes To".
Testing - On Event (import code: ciwc)
This piston increments a variable each time a virtual momentary button gets pressed. It detected it being pressed by using "On Event" then checks the variable "$currentEventValue" to see if it is "on".
Testing - Push (import code: n66h)
Pushes the virtual button every 30 seconds.
It didn't take long for the "Changes To" piston to miss events. After 10 minutes it missed 8 events.
When it missed the events it had this in the logs... Notice that "changes_to on" evaluates to false.
5/26/2017, 6:29:08 PM +583ms
+1ms ╔Received event [Test Button].switch = on with a delay of 30ms
+210ms ║RunTime Analysis CS > 18ms > PS > 177ms > PE > 15ms > CE
+223ms ║Runtime (31439 bytes) successfully initialized in 177ms (v0.1.0b1.20170524) (220ms)
+225ms ║╔Execution stage started
+385ms ║║Comparison on changes_to on = false (1ms)
+387ms ║║Condition #6 evaluated false (10ms)
+388ms ║║Condition group #1 evaluated false (state did not change) (13ms)
+428ms ║╚Execution stage complete. (203ms)
+444ms ╚Event processed successfully (444ms)
5/26/2017, 6:29:08 PM +614ms
+2ms ╔Received event [Test Button].switch = off with a delay of 56ms
+182ms ║RunTime Analysis CS > 21ms > PS > 147ms > PE > 14ms > CE
+194ms ║Runtime (31440 bytes) successfully initialized in 147ms (v0.1.0b1.20170524) (192ms)
+195ms ║╔Execution stage started
+211ms ║║Comparison off changes_to on = false (1ms)
+213ms ║║Condition #6 evaluated false (8ms)
After 2 hours...
After a long time...
Forum Post: https://community.smartthings.com/t/private-webcore-momma-wants-grandkids-channel-6/87598/589?u=whoismoses
Howdy!
I'm the maintainer of the Python WebCore web framework (see the master branch commit history) and got a neat Google Alert regarding a forum question about your webCoRE project. My WebCore project has been in production use since 2009. Your package is quite new—Nov 2016 repo, March 2017 wiki—and documentation (wiki, etc.) inconsistent in the application of capitalization to your product name, often referred to as simply webcore
or webCore
.
Unfortunately, packages under most package management systems do not use Github account prefixes. For example, Gentoo ebuilds or RedHat / Ubuntu /Debian packages.
It pollutes internet searches for the term with multiple competing web development software packages (common problem domain); the WebCore web framework is currently ranked 2nd on Duckduckgo (better for testing as it doesn't personalize result ordering; this up from 4th in early March, 2016, ref: stentle/laravel-web-core#1) and is mixed with Apple's WebKit results, because Apple's internal API naming conventions. (ImageCore, TextCore, … ;)
Having dug a bit into what you're doing, I love the idea of your project; I've been progressively automating things at home for the last year or so. Nothing quite as magical as arriving home and having a dozen things happen automatically, locks unlock, lights switch, TV says "hi". (Stretching it a bit on the last, of course…) What shall we do about this potential conflict, if anything? :)
Have a great day,
— Alice.
Right now, local variables with devices will create subscriptions correctly. However, global variables do not create subscriptions properly despite showing the lightning bolt icon.
Note how the lightning icon is present in the code view, but the yellow warning is still present and the list of subscriptions is empty.
Hi,
I'm trying to debug an issue with a piston and can't figure out which condition is triggering the command:
5/18/2017, 1:55:32 PM +352ms
+1ms ╔Received event Home].time = 1495140932896 with a delay of -545ms
+360ms ║RunTime Analysis CS > 130ms > PS > 95ms > PE > 135ms > CE
+375ms ║Runtime (33150 bytes) successfully initialized in 95ms (v0.1.0a7.20170515) (374ms)
+377ms ║╔Execution stage started
+475ms ║║Condition #15 evaluated true (1ms)
+477ms ║║Condition group #7 evaluated true (changed) (15ms)
+515ms ║║Executed physical command Garage Light Switch].off() (29ms)
+516ms ║║Executed Garage Light Switch].off (33ms)
+827ms ║║Fast executing schedules, waiting for 563ms to sync up
+1418ms ║║Condition #15 evaluated true (1ms)
+1419ms ║║Condition group #7 evaluated true (did not change) (6ms)
+1446ms ║║Executed physical command Garage Light Switch].off() (21ms)
+1447ms ║║Executed Garage Light Switch].off (23ms)
+1660ms ║║Fast executing schedules, waiting for 1040ms to sync up
+2740ms ║║Condition #15 evaluated true (3ms)
+2743ms ║║Condition group #7 evaluated true (did not change) (9ms)
+2767ms ║║Executed physical command Garage Light Switch].off() (16ms)
+2768ms ║║Executed Garage Light Switch].off (18ms)
+3050ms ║╚Execution stage complete. (2673ms)
+3145ms ║Setting up scheduled job for Thu, May 18 2017 @ 1:58:34 PM PDT (in 179.5s), with 5 more jobs pending
+3173ms ╚Event processed successfully (3174ms)
I think what would help is if you added a text representation of the condition or label the conditions in the editor.
Thanks,
Matt
Since v0.2.0fb, pistons can no longer execute from a global variable. I have documented this issue in the forum which includes a test piston, and the resulting logs.
https://community.webcore.co/t/last-update-broke-global-variable-subscription/2143
Hi! Is there a developer chat forum for this project? Like Gitter?
The new timer warning is appearing on any timer event, even top level statements.
I am unable to add devices or even get into the settings. It spools and then bounces me back to the main page in the SmartApp for WebCore.
I am guessing it is a Samsung thing but wanted to inquire with you.
Hello,
I have been trying to port my pistons from Core to Webcore. Most work, however I cannot get the device power readings to work correctly. See below
The condition I have is:
Washing Machine's power was greater than 10W for 1min
this evaluates to (in the log):
Comparison (decimal) 16.3 was_greater_than (decimal) 10.0 = false (42ms)
Which should evaluate to true, not false.
Any help appreciated.
Is web core designed to allow security-minded people to run it on their own servers?
I think that having a variable that can be observed / listened to that tells whether SHM has detected an intrusion / had the intrusion dismissed would be very useful.
One of my use cases is turning on interior cameras when an intrusion is detected during 'Armed/Stay', then turning them off once the intrusion is dismissed.
I can look into adding this if you're interested / can point me in the right direction.
Approx. 21:30 BST I was attempting to edit a piston and received the error message 'Sorry, an error occurred while retrieving the piston data' Only option is to click 'Go home'. Other pistons open fine.
Is there anyway to retrieve the piston?
Checking the live log, I am getting the following error...
physicalgraph.exception.StateCharacterLimitExceededException: State cannot be greater than 100000.0 characters @ line 792
Assume I've over done it?!
I have tried to create a copy by creating a new piston from this one, but the resulting piston is empty, same issues I would imagine :(
If I can't get it back (it appears to still be running), is there a way to delete it and start again?
I'm hoping you can add contact book support like the old CoRE :)
I noticed that it is possible to create lists for local variables but not for globals. I am not sure if this is by design or an oversight, but I thought I'd mention it.
I had some z-wave issues with my ST hub last week, and it looks (I do not know how to recover older logs) like any pistons that contained devices that were flakey threw some sort of NPE and failed.
I am just recovering from this with the day off today, so I can not reproduce nor paste in logs.
In the pistons in question, the failing devices' names were replaced with a numeric ID - that's how it lead me to believe this is what is happening.
Sorry I do not have better diagnostics on this.
Seems like the desired behavior would be the piston skipping the devices that do not resolve to anything real, but doing its best to complete the other actions.
Devices such as the new local Sonos integration no longer include the custom capability playText and its derivatives. As devices more move to local execution such as the new Sonos they no longer have access to the TTS cloud service required to generate the TTS sounds. The solution to this problem is to have the SmartApp use the textToSpeech API as seen here in BigTalker:
Once the sounds is generated it can then be sent to any capability that can play a url. For Sonos and most other the speakers this would be the Audio Notification capability.
Supporting this in WebCore will enable it to again play TTS sounds to Sonos and future local speakers from pistons.
This week my garage door sensor based pistons stopped working. It looks like there is a json error happening. the error is:
An error occurred while executing the event: groovy.json.JsonException: A JSON payload should start with an openning curly brace '{' or an openning square bracket ''. Instead, '1577' was found on line: 1, column: 1
When setting state through LIFX API, LIFX allows you to send a "fast" boolean attribute. In my testing, when set to true (default is false), this causes a significant improvement in speed. I am hoping you could please add support for sending this optional parameter in actions.
Hi ,
If i run a routine it will not trigger the action on webcore it did work always before
The update notice has an extra "the" ("[…] update the all the […]")
https://github.com/ady624/webCoRE/blob/master/dashboard/js/app.js#L433
Getting the following error in webCore with web requests. I've also requested a wiki account so I can add this to the todo list
║Error executing virtual command [].httpRequest: (1ms) groovy.lang.MissingMethodException: No signature of method: script14921351763651536110737.vcmd_httpRequest() is applicable for argument types: (java.util.LinkedHashMap, java.util.ArrayList, java.util.ArrayList) values: [[logging:[error:true, warn:true, info:true, ...], ...], ...]
Any idea what I'm doing wrong with install?
I am trying to send the url from my iphone to my Mac and I get this message
Oops, you are not logged in!
Please open the SmartThings IDE, go to Live Logging, then open the SmartThings CoRE app and look for the dashboard URL in the Live Logging page. You will need to open that link for the first time.
If I follow these instructions my log view for webCoRE is blank.
MPEG snapshot to MMS
Changing
td i[star] {
display: inline-block;
color: #369;
font-size: 8px;
margin-top: -4px;
padding: 0px 4px 0px 0px;
vertical-align: middle;
}
to
td i[star] {
display: inline-block;
color: #369;
font-size: 8px;
margin-top: -4px;
padding: 1em 4px 0px 0px;
vertical-align: top;
}
Keeps the blue dot (recent indicator) for the piston aligned with the piston name even if the piston state spans across multiple lines
Are there any plans related to the new Smartthings app? They'll deprecate the classic app eventually and even if they offer a rules engine in the new app, there is always going to be things that are missing or that don't work the way the users want. Also, Samsung bringing all the devices under one roof, could give WebCore even more power.
Btw, thank you for all the hard work. Thanks to you everything (literally) in my house is automated :).
Nothing was working last night and found out it was a DST issue. I updated webcore and everything started working for a few hours. Now nothing is working again
How to solve this error which create manually
Hey guys, I'm liking the platform and have been thinking about building a separate reporting UI to start interacting with WebCoRE and graphing the data. However, after some thought, it seems pretty pointless if I can just contribute to this and build something up that everyone can benefit from.
Is it at all possible to contribute to this and any help getting something set up locally would be great :)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.