Dashboard and dev just spinning?


#21

you mean clicking “Refresh client secret (warning: this will make your current secret invalid)”

I have tried that also :frowning:


#22

Ok, dive in with me here. I get the impression that you’re at least fairly technical, so let me know if you need more info on any of the steps I gloss over below.

First thing to figure out is whether a specific piston is responsible for this. You’re already at step 4 since you showed the URL but other steps included for the benefit of others.

  1. Open the dashboard in Chrome (or whichever browser you use that has a network inspector)
  2. Open Developer Tools to the network tab
  3. Refresh the dashboard, filter network requests that show up on the text dashboard/load
  4. There is probably only one and it’s probably red, right click and select Open in new tab
  5. Replace /intf/dashboard/load? with /intf/dashboard/piston/get?id=& but don’t load that page yet because we need to get the id
  6. Open developer.smartthings.com in a new tab and click through My Locations > Home > List SmartApps
  7. Find webCoRE then for each of the pistons nested below it:
    1. Click the piston name
    2. Copy the id shown under Event Subscriptions which will look like :19ac3370d57aafca115c3f7033ed973c:, including the colons
    3. Paste that between the id= and the & in the earlier URL
    4. Load the page and see if there is an error, no error will be a bunch of code starting with angular.callbacks

If it looks like all of them will error out after trying a few that’s fine we can look for something else. Otherwise, my hope is that one but not all of these will throw an error.


Dashboard Loads, but Pistons Won't
#23

Rise of the machines? Is it coming true?


#24

I would!


#25

Seems like I did something wrong - will check again but I get:

angular.callbacks._2({“name”:“NC \ webCoRE_1”,“error”:“ERR_INVALID_TOKEN”,“now”:1510258545656})


#26

Hm, maybe clear your cookies and try to get the load URL again?


#27

I also remember with old CoRE, when I reset the token I had to do something in the mobile app after… will dig into some of my old posts.


#28

The /load shows the same error though when a token is invalid so I think it might be how you edited it. Can you paste here redacted or in a PM to me?


#29

I’ll PM you - sent


#30

I keep thinking something is broken somewhere like that - some thing that hooks all this magic together I just have no idea where to find it.


#31

The URL included /intf/dashboard/load?token=&pin= with a value for the pin but no token. I think something got stuck halfway through signing you in to the dashboard. Open up the browser console and run the command localforage.clear();

This will reset the data cached in your browser and require you to re-authorize that browser to use webCoRE. Once you’ve done that let’s see if it loads up or if we need to keep debugging.


#32

So I register and then next screen asks me my password. When I enter that I get stuck and I get the 500 error. Token is blank


#33

I take it you’ve tried the dashboard button in the mobile app instead of register a browser?

Have you tried going to the smartapps tab of a device and accessing a piston from there?

Are you able to install a second instance and access that?


#34
  1. I have tried from the mobile app hitting dashboard - just spins.
  2. smartapp tab pulls up info on the piston but if I try to view in dashboard I get “Sorry, an error occured while retrieving the piston data”
  3. I do have a second instances of webcore running for my presence sensor and that works fine.

#35

Ok, so I see that the token comes back from a call to /load via a request with just the pin like you have, then the frontend uses the token thereafter but can’t get the token in your case since /load doesn’t work. Let’s approach this from a different angle.

In SmartThings developer can you make the following edit to webCoRE smart app around line 934? Add two forward slashes to comment out the pistons: getChildApps() line as shown, then save and publish:

	return [
        name: location.name + ' \\ ' + (app.label ?: app.name),
        instance: [
	    	account: [id: hashId(hubUID ?: app.getAccountId(), updateCache)],
//        	pistons: getChildApps().findAll{ it.name == name }.sort{ it.label }.collect{ [ id: hashId(it.id, updateCache), 'name': it.label, 'meta': state[hashId(it.id, updateCache)] ] },
            id: hashId(app.id, updateCache),
            locationId: hashId(location.id, updateCache),
            name: app.label ?: app.name,
            uri: state.endpoint,

Try to refresh the dashboard again. Just trying to get the dashboard to load at this point, you’ll have a big sad face since it doesn’t know about your pistons after commenting out that line.


#36

Same spins forever :frowning:


#37

Cool cool cool. Before we kill off anything else that looks like it could error out let’s see where the error happens. Since I don’t know any better way to get more info from ST exceptions let’s just throw in some log messages:

In the webCoRE smart app replace the api_get_base_result code with the following:

private api_intf_dashboard_load() {
	def result
    debug 'A'
    recoveryHandler()
    debug 'B'
    //install storage app
    def storageApp = getStorageApp(true)
    debug 'C'
    //debug "Dashboard: Request received to initialize instance"
	if (verifySecurityToken(params.token)) {
    	result = api_get_base_result(params.dev, true)
    	if (params.dashboard == "1") {
            startDashboard()
         } else {
         	stopDashboard()
         }
    } else {
	    debug 'D'
    	if (params.pin) {
            debug 'E'
        	if (settings.PIN && (md5("pin:${settings.PIN}") == params.pin)) {
                debug 'F'
            	result = api_get_base_result()
                debug 'G'
                result.instance.token = createSecurityToken()
                debug 'H'
            } else {
		        error "Dashboard: Authentication failed due to an invalid PIN"
            }
        }
        if (!result) result = api_get_error_result("ERR_INVALID_TOKEN")
    }
    //for accuracy, use the time as close as possible to the render
    result.now = now()
	render contentType: "application/javascript;charset=utf-8", data: "${params.callback}(${groovy.json.JsonOutput.toJson(result)})"
}

#38

small sample of the logging:

713686f8-6e0b-4230-af47-8d5401a376a3 4:40:26 PM: debug B
713686f8-6e0b-4230-af47-8d5401a376a3 4:40:26 PM: debug D
713686f8-6e0b-4230-af47-8d5401a376a3 4:40:26 PM: debug A
713686f8-6e0b-4230-af47-8d5401a376a3 4:40:26 PM: debug F
713686f8-6e0b-4230-af47-8d5401a376a3 4:40:26 PM: debug E
713686f8-6e0b-4230-af47-8d5401a376a3 4:40:26 PM: debug F
713686f8-6e0b-4230-af47-8d5401a376a3 4:40:26 PM: debug D
713686f8-6e0b-4230-af47-8d5401a376a3 4:40:26 PM: debug F
713686f8-6e0b-4230-af47-8d5401a376a3 4:40:26 PM: debug F
713686f8-6e0b-4230-af47-8d5401a376a3 4:40:26 PM: debug A
713686f8-6e0b-4230-af47-8d5401a376a3 4:40:26 PM: debug A
713686f8-6e0b-4230-af47-8d5401a376a3 4:40:26 PM: debug A
713686f8-6e0b-4230-af47-8d5401a376a3 4:40:26 PM: debug F
713686f8-6e0b-4230-af47-8d5401a376a3 4:40:26 PM: debug E


#39

Perfect, no G means we’re on the right track. Let’s rip more out of the base result. It would be a good idea at this point to open the /load URL in a browser tab so that the dashboard doesn’t do anything whacky with all of this data missing.

private api_get_base_result(deviceVersion = 0, updateCache = false) {
	def tz = location.getTimeZone()
    def currentDeviceVersion = state.deviceVersion
	def Boolean sendDevices = (deviceVersion != currentDeviceVersion)
    def name = handle() + ' Piston'
    def incidentThreshold = now() - 604800000
	return [
        name: location.name + ' \\ ' + (app.label ?: app.name),
        instance: [
	    	account: [id: hashId(hubUID ?: app.getAccountId(), updateCache)],
//        	pistons: getChildApps().findAll{ it.name == name }.sort{ it.label }.collect{ [ id: hashId(it.id, updateCache), 'name': it.label, 'meta': state[hashId(it.id, updateCache)] ] },
            id: hashId(app.id, updateCache),
            locationId: hashId(location.id, updateCache),
            name: app.label ?: app.name,
            uri: state.endpoint,
            deviceVersion: currentDeviceVersion,
            coreVersion: version(),
            enabled: !settings.disabled,
            settings: state.settings ?: [:],
            lifx: state.lifx ?: [:],
//            virtualDevices: virtualDevices(updateCache),
            globalVars: listAvailableVariables(),
        ], //+ (sendDevices ? [contacts: listAvailableContacts(false, updateCache), devices: listAvailableDevices(false, updateCache)] : [:]),
        location: [
//            contactBookEnabled: location.getContactBookEnabled(),
//            hubs: location.getHubs().collect{ [id: hashId(it.id, updateCache), name: it.name, firmware: hubUID ? 'unknown' : it.getFirmwareVersionString(), physical: it.getType().toString().contains('PHYSICAL'), powerSource: it.isBatteryInUse() ? 'battery' : 'mains' ]},
//            incidents: hubUID ? [] : location.activeIncidents.collect{[date: it.date.time, title: it.getTitle(), message: it.getMessage(), args: it.getMessageArgs(), sourceType: it.getSourceType()]}.findAll{ it.date >= incidentThreshold },
            id: hashId(location.id, updateCache),
//            mode: hashId(location.getCurrentMode().id, updateCache),
//            modes: location.getModes().collect{ [id: hashId(it.id, updateCache), name: it.name ]},
            shm: hubUID ? 'off' : location.currentState("alarmSystemStatus")?.value,
            name: location.name,
            temperatureScale: location.getTemperatureScale(),
            timeZone: tz ? [
                id: tz.ID,
                name: tz.displayName,
                offset: tz.rawOffset
            ] : null,
            zipCode: location.getZipCode(),
        ],
        now: now(),
    ]
}

If it works you can remove the commented-out portions until it doesn’t work again. If it doesn’t work you can comment out more things…


#40

There is an error in that somewhere I think - I have to run out for 30 min and will look into why when I get back unless anyone beats me to it:

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
script_app_metadata_f04c0aa5_611f_4b1e_8359_33fbc5d623a1: 966: expecting ‘]’, found ‘}’ @ line 966, column 1.
}
^

1 error

*I added an extra ] near the end and good for now but that’s likely not the right spot