I have updated my script.
- Installation instructions added
- error handling when no data is being retrieved
- comment --- replaced by --
- repetition of code placed in functions
- all comments and improvement posted here picked up and applied
Hopefully this is clearer and there are fewer problems than my first post
Tips, improvements and comments let me know, if necessary I will update my code and on request I will place the new code.
Code: Select all
-- Created by Raymond Wiertz
-- DateTime: 2019-05-03
--
-- How to install this script:
--
-- Before you can use this script you must first create a virtual sensor.
--
-- Create dummy hardware and device
-- Go to Setup -> Hardware
-- Name: anything, e.g. "Ele_Consumption" (this name is only used internally)
-- Type: "Dummy (does nothing, use for virtual switches only)"
-- Click on 'Add'
-- Click on 'Create Virtual Sensors' from the table of hardware above
-- Name: solar panels (this name must be the same as in the variable sensorSolarPanels)
-- Sensor type: "Electric (Instant+Counter)"
-- Click 'Ok'
--
-- Now you are ready to install this script.
--
-- Go to Setup -> More Options -> events
-- Event name: anything (this name is only used internally)
-- Select LUA
-- Select Time
-- Select "Event active"
--
-- Copy this script to the left side
-- hit the "save" button
--
-- Your script is now active, to disable this script deselect "Event active" and
-- hit the "save" button again.
--
--
--
-- Tracking your token
-- To find out your token, you must execute the CURL command below from the command line.
-- curl -d 'account=[YOUR USERNAME]&pwd=[YOUR PASSWORD]&code=' https://www.semsportal.com/Home/Login;
-- EXAMPLE
-- curl -d '[email protected]&pwd=!QAZ1qaz&code=' https://www.semsportal.com/Home/Login;
--
-- EXAMPLE RESPONE:
-- { "code" : 0, "msg" : "","data":{"redirect":"/PowerStation/PowerStatusSnMin/295a07ac-745d-2f84-ad8c-81537fca2d94"} }%
-- YOUR TOKEN IS:
-- 295a07ac-745d-2f84-ad8c-81537fca2d94
--
local UserName = "YOUR USERNAME"
local Password = "YOUR PASSWORD"
local token = "YOUR TOKEN"
local sensorSolarPanels = "solar panels"
commandArray = {}
i=1
function stripchars(str, chrs)
local s = str:gsub("["..chrs:gsub("%W","%%%1").."]", '')
return s
end
function split(s, delimiter)
result = {};
for match in (s..delimiter):gmatch("(.-)"..delimiter) do
table.insert(result, match);
end
return result;
end
function printToFile(s)
file = io.open("myoutput.txt", "w")
io.output(file)
io.write(s)
io.close(file)
end
function printAllValues(s)
for key, value in pairs(splitString) do
print(string.format("Key = [%s] Value = [%s]",split(value, ":")[1],split(value, ":")[2]))
end
end
function isempty(s)
return s == nil or s == ''
end
function getValue(s, name)
for key, value in pairs(splitString) do
key = split(value, ":")[1]
value = split(value, ":")[2]
if (name == key) then
return value
end
end
return ""
end
function extractJSonFromResponse(responseData)
response = ""
searchResult = string.find(responseData,"var pw_info = ")
if (isempty(searchResult)== false) then
-- extract the JSON-data from the response
dummy, startPos = string.find(s, "var pw_info = ")
dummy, endPos = string.find(s, "}};")
response = string.sub(s, startPos, endPos-1)
end
return response
end
function getExecuteCommand(command)
local f = assert(io.popen(command, 'r'))
s = assert(f:read('*a'))
f:close()
return s
end
function getSessionID()
-- The curl command below retrieves the get session ID named "ASP.NET_SessionId", the session ID is used to request the final data
command = string.format("curl --silent --output /dev/null --cookie-jar - -d 'account=%s&pwd=%s&code=' https://www.semsportal.com/Home/Login",UserName,Password)
result = getExecuteCommand(command)
-- extract the ASP.NET_SessionId from the curl response
sessionId = string.sub(result, -26)
sessionId = string.gsub(sessionId,"[\r\n]", "" )
sessionId = string.gsub(sessionId, "%s+", "")
return sessionId
end
function timedifference(s)
year = string.sub(s, 1, 4)
month = string.sub(s, 6, 7)
day = string.sub(s, 9, 10)
hour = string.sub(s, 12, 13)
minutes = string.sub(s, 15, 16)
seconds = string.sub(s, 18, 19)
t1 = os.time()
t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes,sec=seconds}
difference = os.difftime (t1, t2)
return difference
end
function UpdateDevice(device, data)
idx = otherdevices_idx[device]
if (idx == nil) then
print('** Unknown device'..device)
else
commandArray[i] = {['UpdateDevice'] = idx..'|0|'..data}
i = i+1
end
end
difference = timedifference(otherdevices_lastupdate[sensorSolarPanels])
-- The sensor will update every 180 seconds
if (difference > 180) then
sessionId = getSessionID()
-- update curl command with the session id.
getData = string.format("%s%s%s%s" , "curl -v --cookie 'ASP.NET_SessionId=", sessionId, "' https://www.semsportal.com/PowerStation/PowerStatusSnMin/",token )
response = getExecuteCommand(getData)
-- extract the JSON-data from the response
jsonResult = extractJSonFromResponse(response)
if (isempty(jsonResult) == false) then
-- remove excess brackets and split the records
valueString = stripchars(jsonResult, "[]{}\"")
splitString = split(valueString, ",")
-- Show al variable
-- printAllValues(splitString)
-- printToFile(splitString)
output_power = getValue(splitString, "output_power")
last_refresh_time = getValue(splitString, "last_refresh_time")
eDay = getValue(splitString, "eDay")
print("last_refresh_time :" .. last_refresh_time)
print("output_power :" .. output_power)
print("eDay :" .. eDay)
current = tonumber(stripchars(output_power, "kwhKWH"))
dayTotal = tonumber(eDay)*1000
UpdateDevice(sensorSolarPanels, current..";"..dayTotal)
end
end
return commandArray