Page 1 of 3 123 LastLast
Results 1 to 10 of 28

Thread: custom DM devices?

  1. #1
    Join Date
    Mar 2005
    Posts
    724

    Default custom DM devices?

    I am slowly in the process of moving my HA system from G5 to G6 however I have a lot of custom dm objects that are simply triggering scripting actions storing the results for easy access.

    Thanks,
    yonu

  2. #2
    Join Date
    Jan 1998
    Location
    Jupiter, FL
    Posts
    13,553

    Default

    You can do custom DM devices from a Lua plugin. It's a bit involved and not yet documented but possible by inspecting the global cache plugin for example.
    Ron
    No support through PM

  3. #3
    Join Date
    Mar 2005
    Posts
    724

    Default

    Great thanks I will have a look at it.

  4. #4
    Join Date
    Mar 2005
    Posts
    724

    Default

    Yikes I hadn't looked at any of the plugin code for G6 yet any tips on what part to look at first as you are right it is a bit involved

    Thanks,
    Yonu

  5. #5
    Join Date
    Mar 2005
    Posts
    724

    Default

    Ok here is what I have come up with from digging through the Globalcache plugin and I have came up with the code below however I am at a loss of how to pass the information to it I see that gc is equal to the globalcache in the require but I can't figure out what is being passed to it inorder to see if this will work.

    Code:
    local base = require("plugin.device")
    --local gc = require('globalcache')
    local print = print
    local Promixis = Promixis
    local bit = require('bit')
    local json = require('json')
    local string = require('string')
    local gir = gir
    local tonumber = tonumber
    local tostring = tostring
    local table = require('table')
    local ipairs = ipairs
    local unpack = unpack
    
    
    
    
    function onControlValueChangeRequest(self, control, value, sender)
    
    	if not self.gc then
    		return
    	end
    	
    	
    	local _,_, name, connector = string.find(control.ccontrol.internalId, "([^_]+)_(%d:%d)")
    	
    	if name == "RELAY" then
    		self.gc:setState( connector, value, function ( status, connector, value )
    		
    			if status then			
    				if value ~= 0 then
    					control.ccontrol.hardwareValue = 1
    				else
    					control.ccontrol.hardwareValue = 0					
    				end
    			end
    			
    		end)
    	end
    	
    	if name == "SENSOR" then
    	
    		-- really?
    		
    	end
    	
    	
    	if name == "IR" then
    	
    		local repeats = 1
    		local ccf
    		
    		local c = json.decode( value )		
    		
    		if c then
    			
    			if not c.odd or c.odd == '' then
    				c.odd = c.even
    			end
    			if not c.even or c.even == '' then
    				c.even = c.odd
    			end
    			
    			repeats = c.repeats
    			
    			if self.evenCCF then
    				ccf = c.even
    				self.evenCCF = false
    			else
    				ccf = c.odd
    				self.evenCCF = true
    			end
    			
    		else
    			ccf = value
    		end		
    		
    		self.gc:sendCCF( connector, repeats, ccf, function(status)
    		
    		end)
    	
    	end
    	
    end
    
    local updateState = function (self, internalId, state)
    
    	local controls = self.cdevice:controls(internalId)
    	
    	for i, control in ipairs( controls ) do	
    		control.hardwareValue = state		
    	end
    	
    end
    
    function start(self)	
    	
    	base.start(self)
    	self.gc:connect( function ( connected )
    		
    		if not self.cdevice then
    			return
    		end
    		
    		if connected then
    					
    			self.cdevice.hardwareStatus = Promixis.Device.Status.STATUS_OK	
    			
    			
    			self:forEachControl( function (internalId, control) 
    				
    				local _,_,name, connector = string.find(internalId, "([^_]+)_(%d:%d)")
    				
    				if name == "RELAY" or name == "SENSOR" then
    					
    					self.gc:getState( connector, function( status, connector, state )
    						
    						if status then
    							updateState(self, internalId, state)
    						end						
    					end)
    				end
    				
    			end)
    			
    			
    			
    		else
    			self.cdevice.hardwareStatus = Promixis.Device.Status.STATUS_UNKNOWN			
    		end
    		
    		if self.cdevice then
    			self.cdevice:hardwareStatusChanged( self.cdevice.id, self.cdevice.hardwareStatus)
    		end
    		
    	end)
    	
    end
    
    function stop(self)	
    	base.stop(self)
    		
    	if self.gc then
    		self.gc:disconnect()
    	end	
    	
    end
    
    local addGeneric = function(self, internalId, name, t,v  )
    
    	
    	local component = {}
    	component.id = self.component.ccomponent.id
    	component.pluginId = self.component.ccomponent.pluginId
    	local device = {}
    	device.id = self.cdevice.id
    	component.devices = {
    		device
    	}
    	
    	local control = {}
    	control.internalId = internalId
    	control.name = name
    	control.dtype = t
    	if v then
    		control.value = tostring(v)
    	end
    	
    	device.controls = {
    		control
    	}
    
    	local j = json.encode(component)
    	self.component.componentManager.cComponentManager:createDevs(j)		
    end
    
    local addRelay = function ( self, connector, state )	
    	local internalId = "RELAY_" .. connector
    	local name = "Relay " .. connector
    	local t = Promixis.Control.DType.TOGGLE
    	addGeneric(self, internalId, name, t, state)
    end
    
    local addIR = function ( self, connector )
    	local internalId = "IR_" .. connector
    	local name = "IR " .. connector
    	local t = Promixis.Control.DType.CCF
    	addGeneric(self, internalId, name, t )
    end
    
    local addSensor = function ( self, connector, state )
    	local internalId = "SENSOR_" .. connector
    	local name = "Sensor " .. connector
    	local t = Promixis.Control.DType.LABEL
    	addGeneric(self, internalId, name, t, state)
    end
    
    local handleDEVICEEvent = function( self, event, port, id, name )
    
    	if ( event == "STATECHANGE" ) then		
    	
    		self:forEachControl( function( internalId, control )
    			
    			local _,_, name, connector = string.find(internalId, "([^_]+)_(%d:%d)")
    			
    			if connector then
    				
    				if connector == port then
    							
    					if control.ccontrol then
    						control.ccontrol.hardwareValue = id
    					end
    				
    				end
    			
    			end
    		
    		end)
    		
    	
    		return
    	end
    	
    	
    	
    
    	if event ~= "DEVICE" then
    		return
    	end
    	
    	local connector = tostring(port) .. ":" .. tostring(id)
    	
    	if name == "IR" then
    
    		local internalId = "IR_" .. connector
    		local control = self:findControl(  internalId )
    		if not control then
    			internalId = "SENSOR_" .. connector
    			control = self:findControl(  internalId )
    		end
    		
    		if not control then
    			
    			-- let's figure out if this is a ir out or sensor.
    			
    			self.gc:getState( connector, function ( status, _connector, state )
    			
    				if status then
    					addSensor( self, connector, state )
    				else
    					addIR( self, connector )
    				
    				end
    						
    			end)
    			
    		end
    	
    	end
    	
    	if name == "RELAY" then
    	
    		local internalId = "RELAY_"..connector
    	
    		local control = self:findControl(  internalId )
    		if not control then			
    			self.gc:getState( connector, function(status, _connector, state )				
    				
    				addRelay(self, connector,state)			
    			end)
    		end	
    		
    	end
    	
    end
    
    local gcInit = function(self)
    	self.gc = gc.new( self.cdevice.internalId )
    	self.gc:subscribe( function( ... )
    		handleDEVICEEvent(self, unpack(arg))
    	end)
    end
    
    local gcDeinit = function(self)
    	if self.gc then
    		self.gc:deinit()
    		self.gc = nil
    	end
    end
    
    
    function onInternalIdChanged(self)	
    	
    	gcDeinit(self)
    	base.onInternalIdChanged(self)	
    	gcInit(self)	
    end
    
    
    --[[
    	cdevice is c-based device object
    	component is the lua based parent component.
    
    --]]
    function init ( self, cdevice, component )
    	base.init(self, cdevice, component)
    	self.evenCCF = true	
    	gcInit(self)	
    end
    
    function deinit( self )
    	gcDeinit(self)
    	base.deinit(self)
    end
    Thanks,
    Yonu

  6. #6
    Join Date
    Jan 1998
    Location
    Jupiter, FL
    Posts
    13,553

    Default

    Yeah that is the code you could start with. Let's ask this what is the goal you are trying to achieve and maybe we can get there together.
    Ron
    No support through PM

  7. #7
    Join Date
    Mar 2005
    Posts
    724

    Default

    Ok What I am trying to do is basically duplicate what I have in G5 or at least come close and I am using custom devices to store states and values across reboots and such for devices controlled by telnet, http, and so on.

    Thanks,
    Yonu

  8. #8
    Join Date
    Jan 1998
    Location
    Jupiter, FL
    Posts
    13,553

    Default

    So no actual hardware driver the value changes, just Lua directly, from action or other sources.
    Ron
    No support through PM

  9. #9
    Join Date
    Jan 1998
    Location
    Jupiter, FL
    Posts
    13,553

    Default

    Will you interface the value updates from the device manager ( e.g. read/write controls ) or will the device manager controls be read-only and all updates are done through custom functions into your plugin?
    Ron
    No support through PM

  10. #10
    Join Date
    Mar 2005
    Posts
    724

    Default

    I have been running all updates through Lua using control.UpdateValue so not sure what you would consider that.

    Thanks,
    Yonu

Page 1 of 3 123 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •