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

function usage()
    print("  USAGE: ./actor.lua 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))
		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" }}'
    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
    
   
   os.execute("sleep 5")
--   statusURL="http://"..host.."/api/homematic-status.cgi"
   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


   local logoutPost='{"method": "Session.logout", "params": { "_session_id_": "'..sessionID..'", "password": "" }}'
   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..'", "password": "" }}'
		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
    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
 
    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

    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()
