Trying to copy illuminance level into a virtual lux device

I'm trying to copy the lux value of a motion sensor into a virtual lux device that I have created.
In webCoRE this is piece of cake but I've had a good rummage around and cannot find a way to do this on HE without using webCoRE.
Any ideas anybody?
The reason BTW I'm trying to do this is I use a virtual lux sensor in most of my lighting pistons and if I need to change the lux level source, only one rule/piston needs to be changed, not 15.

You would need a little app to copy the physical device(s) into the virtual.

It shouldn't be too difficult to create.
You would just need to subscribe to the physical and send it to the virtual

Or you might be able to use Rule Machine with a subscription and a custom command to send the data to the virtual sensor

Are you looking to create an 'average' of multiple physical sensors to show on the virtual?

Andy

Ah. Yes and no. I have averaged a couple of Fibaro Motion Sensors before or used Weather underground. So I suppose both options.

If you let me have a look at your virtual sensor code I can see how best to do it

Andy

BTW
did you see my reply in the Presence Central thread?
Did this work for you?

Andy

Here's the Settable Lux Sensor driver I'm using.
Haven't looked at Presence Central yet. I must admit the wording does confuse me but at my age, most things do...................

/**
 *  Copyright 2015 Hubitat
 *  For Lux
 *
 */
metadata {
	definition (name: "Settable Lux Sensor", namespace: "", author: "") {
		capability "Illuminance Measurement"
		capability "Sensor"
        
        command "setLux", ["string"]
	}
    
    preferences {
    	section("Setting") {
			input "logging", "enum", title: "Log Level", required: true, defaultValue: "DEBUG", options: ["TRACE", "DEBUG", "INFO", "WARN", "ERROR"]
        }
    }

	// simulator metadata
	simulator {
		for (int i = 0; i <= 4000; i += 10) {
			status "${i}lx": "illuminance: $i lx"
		}
	}

	// UI tile definitions
	tiles {
		valueTile("illuminance", "device.illuminance", width: 3, height:2) {
			state("illuminance", label:'${currentValue}',
				backgroundColors:[
                    // Lux Color Range
                    [value: 0, color: "#000000"],
                    [value: 10, color: "#333300"],
                    [value: 50, color: "#666600"],
                    [value: 90, color: "#999900"],
                    [value: 200, color: "#cccc00"],
                    [value: 400, color: "#ffff00"],
                    [value: 600, color: "#ffff33"],
                    [value: 1000, color: "#ffff66"],
                    [value: 2000, color: "#ffff99"],
                    [value: 3000, color: "#ffffcc"],
                    [value: 4000, color: "#ffffff"]					
				]
			)
		}
        
        standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
			state "default", action:"refresh.refresh", icon:"st.secondary.refresh"
		}

		main(["illuminance"])
		details(["illuminance", "refresh"])
	}
}

def determineLogLevel(data) {
	if(data.toUpperCase() == "TRACE") {
    	return 0
    } else if(data.toUpperCase() == "DEBUG") {
    	return 1
    } else if(data.toUpperCase() == "INFO") {
    	return 2
    } else if(data.toUpperCase() == "WARN") {
    	return 3
    } else {
    	return 4
    }
}

def log(data, type) {
    
    data = "Settable Lux -- " + data
    
    try {
        if(determineLogLevel(type) >= determineLogLevel(logging)) {
            if(type.toUpperCase() == "TRACE") {
                log.trace "${data}"
            } else if(type.toUpperCase() == "DEBUG") {
                log.debug "${data}"
            } else if(type.toUpperCase() == "INFO") {
                log.info "${data}"
            } else if(type.toUpperCase() == "WARN") {
                log.warn "${data}"
            } else if(type.toUpperCase() == "ERROR") {
                log.error "${data}"
            } else {
                log.error "Settable Temp -- Invalid Log Setting"
            }
        }
    } catch(e) {
    	log.error ${e}
    }
}


// Parse incoming device messages to generate events
def parse(String description) {
	def name = parseName(description)
	def value = parseValue(description)
	def unit = name == "illuminance" ? lx : null
	def result = createEvent(name: name, value: value, unit: unit)
	log.debug "Parse returned ${result?.descriptionText}"
	return result
}

private String parseName(String description) {
	
    if (description?.startsWith("illuminance: ")) {
		return "illuminance"
	}
    
	null
}

private String parseValue(String description) {
	if (description?.startsWith("illuminance: ")) {
		return zigbee.parseHALuxValue(description, "illuminance: ", lx)
	} 
    
	null
}

def setLux(val) {
    log.debug "Setting illuminance for ${device.displayName} from external input, illuminance = ${val}."
	sendEvent(name: "illuminance", value: val, unit: lx)
}

def refresh() {
	log("Refresh", "DEBUG")
}

def updated() {
	log("Updated -- ${device.displayName} is ${device.currentState("illuminance")}.", "DEBUG")
   
}

There is an option to put a string in the device. Not sure if this can be used or not.
image

Hmmm
There is still a lot of code left over from ST which should be removed

The LUX value should really be a number or decimal rather than a string

Let me have a quick look and see if I can work on it (and an app)
(Might take a while though)

Andy

Thanks for you help.
I'm trying to get everything working as I have it on ST without using webCoRE if possible.
I've had issues with things running slowly as I have set the majority of things to run on webCoRE.
Gradually moving back all my devices to HE from ST and seeing if speed and reliability is maintained.
Thanks again.

The driver needs a bit of work before I can create the app but I can get that done.

Ok I reread the logging code. It should be ok.

Andy

@bobbles

I have rewritten some of the driver code and created a new app for you :slight_smile:

Driver is here:
https://github.com/CobraVmax/Hubitat/tree/master/Drivers/Average%20Illumination

And app is here
https://github.com/CobraVmax/Hubitat/tree/master/Apps/Average%20Illumination

With the app you can configure as many illuminance sensors as you like to average them out
(Including just one if you wish to just copy data from a physical to a virtual)

I have only tested with a couple of WU devices so cannot confirm that something like an aeon multi sensor would work (it should do!)

Have a play and let me know if it works correctly for you

Andy

1 Like

Brilliant. This is working great.
I'm using a Fibaro motion sensor and it is updating my virtual lux sensor straight away.

Can I make another request. :wink:
Is it possible to have an option so that it only updates the virtual device, say every 5 minutes.
The reason I'm requesting this is the Fibaro Sensor can be quite 'chatty' on HE. For some reason it updates every time the lux level changes even though it is set to update every 5 minutes.
This would take the load down on the hub with the rules continually running every time the lux level changes and only run every 5 minutes.

@bobbles
Bob,
I think this should be possible
Iā€™ll have a look to see if I can give you some kind of configurable ā€˜sendEventā€™ timing.

Andy

1 Like

This is a silly question but what's the purpose of having a virtual lux tagging a real switch? Is there a use case for this?

I'm not sure what you mean.
This is for copying a physical lux reading to a virtual lux sensor.
As I said above, it means I use the virtual lux sensor in my rules. If I change the physical lux sensor, I only have to change one app, not 10 rules.

I see. That sounds like a great idea. I was just curious and couldn't think straight on the reasoning.

The other thing the app does is 'average out' a number of sensors to produce one reading
So you could use a couple of different sensors in one area/room and use the average to turn on a light for example.

1 Like

Bob
I need to leave to pick the wife up from the train station now
I'll pick this up tomorrow for you

Andy

Thanks for this app, I asked about something a long while back as I missed the option to use average levels in webCore. This app seems to work great for my uses.

1 Like

No problem.
You've been more than helpful already.
Bob.