#!/usr/bin/luaweb
local http = require("socket.http")
local json = require("json")
local clock = os.clock

function usage()
    print("  USAGE: ./omghomematic open doorID 127.0.0.1 Admin ''")
    os.exit(1)
end
if(arg[1] == nil or arg[2] == nil or arg[3] == nil or arg[4] == nil or arg[5] == nil)then
    usage()
end 

--  cellarLockHandler(arg[1],arg[2],arg[3],arg[4], arg[5])
--  cellarLockHandler(action, myDoor, host,login,password)

local action=arg[1]
local doorID=arg[2]
local host=arg[3]
local loginName=arg[4]
local password=arg[5]
--[[
local action = arg[1]
local loginName = arg[2]
local password = arg[3]
local host = arg[4]
local doorID = arg[5]
--]]

local Url = "http://"..host.."/api/homematic.cgi"
local loginPost='{"method": "Session.login", "params": { "username": "'..loginName..'", "password": "'..password..'" }}'
local retval=0
priNT = print
function print(msg)
	if(type(msg)=="string")then
	    priNT("HOMEMATIC: "..msg)
	end
	if( type(msg)=="boolean")then
	    priNT("HOMEMATIC: "..tostring(msg))
	end
end

function httpPost( Url, content )
    local Response = {}
	local JSretval
    local response, httpCode, header = http.request{
		method = "POST",
        url = Url,
		headers = {
          	["content-length"] = #content,
        	["Content-Type"] =  "application/json; charset=utf-8",
        },
		source = ltn12.source.string(content),
    	sink = ltn12.sink.table(Response)
    }
    if( httpCode ~= 200 )then
        print("  Server Error")
        print("  HTTP Response: "..httpCode)
	priNT(":homaticErrorOutOfResources")
	retval=retval+1
    end

	if(type(Response[1]) == "string")then
	    JSretval,ResponseTable  = pcall(json.decode,Response[1])
	end
	
	if(JSretval == false or type(ResponseTable) ~= "table")then
		errorRet,errorTable= pcall(json.decode,table.concat(Response))
		print("ERORRTABLE: "..json.encode(errorTable))
		for k,v in pairs(errorTable)do
			if(k == "error")then
				for a,b in pairs(v)do
					if(	a == "message")then
						print("ERROR:"..string.upper(b))
						if(b == "TCL ERROR")then
							print("unknown Door ID")
						end
					end
				end
			end
		end
		retval = retval+1
		priNT(":homaticErrorOutOfResources")
	end
    return ResponseTable
end
function sleep(n)  -- seconds
  local t0 = clock()
  while clock() - t0 <= n do end
end




function main()
    local sessionID=login(loginPost)
    local returnString
    if(action == "open")then
        cmd='{"method": "Interface.setValue", "params": { "_session_id_": "'..sessionID..'", "interface": "BidCos-RF", "address": "'..doorID..'", "valueKey": "STATE", "type": "string", "value": "1" }}'
    elseif(action == "execute") then
		cmd= '{"method": "Program.execute", "params": { "_session_id_": "'..sessionID..'", "id": "'..doorID..'" }}'
	else    
        cmd= '{"method": "Interface.setValue", "params": { "_session_id_": "'..sessionID..'", "interface": "BidCos-RF", "address": "'..doorID..'", "valueKey": "STATE", "type": "string", "value": "0" }}'
    end
    
    if(action ~= '')then
        local actionResult = doAction(cmd,sessionID)
        if(actionResult ~= true)then
            retval=retval+1
	    priNT(":homaticErrorOutOfResources")
            print(" action '"..action.."' FAILED!")
        end
    end
    
   if(action ~= "execute")then
	   os.execute("sleep 5")
	   local statusPost='{"method": "Interface.getParamset", "params": { "_session_id_": "'..sessionID..'", "interface": "BidCos-RF", "address": "'..doorID..'", "paramsetKey": "VALUES" }}'
	   local state,state_uncertain = getParamset(Url,statusPost)
       --print (type(state))
	    if(state == "1" )then
    	    print(" Door '"..doorID.."' is open")
		priNT(":homaticOpened")
	    elseif(state == "0")then
	        print(" Door '"..doorID.."' is closed")
		priNT(":homaticClosed")
	    else
	        print(" Door '"..doorID.."''s state is UNKNOWN")
	        retval=retval+1
		priNT(":homaticErrorOutOfResources")
    	end
	end

   local logoutPost='{"method": "Session.logout", "params": { "_session_id_": "'..sessionID..'" }}'
   logout(logoutPost)
   os.exit(retval)
end



function doAction(cmd,sessionID)
    print(" Sending action: "..action)
    local Url = "http://"..host.."/api/homematic.cgi"   --- faking reply
    local actionResponse=httpPost(Url, cmd)
    local actionResult
	if(retval ~= 0)then 
	 	local logoutPost='{"method": "Session.logout", "params": { "_session_id_": "'..sessionID..'" }}'
		logout(logoutPost)
		os.exit(retval)
		return false
	end
    for k,v in pairs(actionResponse) do
        if(k == "result")then
            if(type(v) ~= boolean) then
                actionResult=v
            end
        end
    end
    if(actionResult == nil)then
         print(" Failed to '"..action.."' command returned: "..actionResult)
    end
    return actionResult
end

function getParamset(statusURL, post)
    print(" requesting status...")
    local status = httpPost(statusURL,post)
    local results 
    local state
    local state_uncertain
	if(type(status) == "table")then
	    for k,v in pairs(status)do
	        if(k == "result")then
	            if(type(v)=="table")then
	                results = v
	            end
	        end
	    end
	    if(results == nil)then
	        print(" invalid data from server")
	    end
 		if(type(results) == "table")then
		    for k,v in pairs(results)do
		        if(k=="STATE" and type(v) == "string")then
	    	        state=v
	        	end
		        if(k=="STATE_UNCERTAIN" and type(v) == "string")then
		            state_uncertain=v
	    	    end
		    end
		end
	end
    return state,state_uncertain
end


function logout(logoutPost)
    print(" logging out...")
    local sessionID
    local loginResponse = httpPost(Url, logoutPost)
    local cmd
    for k,v in pairs(loginResponse) do
 --       print(k,v)
    end
end









function login()
    print(" logging in...")
    local sessionID
    local loginResponse = httpPost(Url, loginPost)
    local cmd

	if(retval ~= 0)then os.exit(1) end
    for k,v in pairs(loginResponse) do
        if(k == "result")then
            if(type(v) == "string")then
                sessionID=v
            end
        end
    end
    if(sessionID == nil)then
        print(" No SessionID found!")
        --os.exit(1)
		retval=retval+1
    else
         print(" login successfull  SessionID: "..sessionID)
    end

    return sessionID
end


main()
