Virtual parameters
Implemented support for user-defined parameters driven by Javascript code. Renamed scripts collection to provisions.
This commit is contained in:
1 parent
359ff44819
commit
7b18cb3bbf
6 files changed
+487
-252
No files matched your search
+312
-200
@@ -37,7 +37,9 @@ init = (deviceId, cwmpVersion, timeout) ->
|
||||
cwmpVersion : cwmpVersion
|
||||
timeout : timeout
|
||||
provisions: []
|
||||
counter : [0, 0, 0] # rpc, revision, batch
|
||||
revisions: [0]
|
||||
rpcCount: 0
|
||||
cycle: 0
|
||||
}
|
||||
|
||||
return sessionData
|
||||
@@ -67,12 +69,10 @@ loadParameters = (sessionData, toLoad, callback) ->
|
||||
|
||||
|
||||
generateRpcId = (sessionData) ->
|
||||
if sessionData.counter[0] > 255 or sessionData.counter[1] > 15 or sessionData.counter[2] > 15
|
||||
if sessionData.rpcCount > 255 or sessionData.cycle > 15 or sessionData.revisions.length > 15
|
||||
throw new Error('Too many RPCs')
|
||||
|
||||
return sessionData.counter[2].toString(16).slice(-1) +
|
||||
sessionData.counter[1].toString(16).slice(-1) +
|
||||
('0' + sessionData.counter[0].toString(16)).slice(-2)
|
||||
return sessionData.timestamp.toString(16) + "0#{sessionData.rpcCount.toString(16)}".slice(-2)
|
||||
|
||||
|
||||
inform = (sessionData, rpcReq, callback) ->
|
||||
@@ -95,205 +95,249 @@ inform = (sessionData, rpcReq, callback) ->
|
||||
|
||||
addProvisions = (sessionData, provisions) ->
|
||||
sessionData.provisions = sessionData.provisions.concat(provisions)
|
||||
if sessionData.counter[1] > 0
|
||||
sessionData.counter[2] += 1
|
||||
sessionData.counter[1] = 0
|
||||
sessionData.counter[0] = 0
|
||||
if sessionData.revisions.length > 1 or sessionData.revisions[0] > 0
|
||||
sessionData.cycle += 1
|
||||
sessionData.rpcCount = 0
|
||||
sessionData.revisions = [0]
|
||||
device.collapse(sessionData.deviceData, 1)
|
||||
|
||||
|
||||
clearProvisions = (sessionData) ->
|
||||
sessionData.provisions = []
|
||||
if sessionData.counter[1] > 0
|
||||
sessionData.counter[2] += 1
|
||||
sessionData.counter[1] = 0
|
||||
sessionData.counter[0] = 0
|
||||
if sessionData.revisions.length > 1 or sessionData.revisions[0] > 0
|
||||
sessionData.cycle += 1
|
||||
sessionData.rpcCount = 0
|
||||
sessionData.revisions = [0]
|
||||
device.collapse(sessionData.deviceData, 1)
|
||||
|
||||
|
||||
generateRpcRequest = (sessionData, declarations, callback) ->
|
||||
test = (cb) ->
|
||||
toLoad = []
|
||||
res = device.traverse(sessionData.deviceData, null, null, (path, declaration, base, current, descendantTimestamps, children) ->
|
||||
|
||||
if path[0] == 'Tags'
|
||||
if path.length == 2 and path[1]? and declaration[7]?
|
||||
if declaration[7][0] != current[7][0]
|
||||
device.set(sessionData.deviceData, path, 1, [sessionData.timestamp, 1, null, null, null, null, sessionData.timestamp, declaration[7]])
|
||||
return
|
||||
|
||||
r = {}
|
||||
gpn = false
|
||||
|
||||
descendantFlags = []
|
||||
for i in [0...descendantTimestamps.length] by 1
|
||||
if descendantTimestamps[i][2]?
|
||||
if not descendantTimestamps[i][4]?
|
||||
toLoad.push(descendantTimestamps[i][0])
|
||||
continue
|
||||
else if descendantTimestamps[i][2] > descendantTimestamps[i][4]
|
||||
descendantFlags[i] = 1
|
||||
descendantFlags[i] |= 2 if descendantTimestamps[i][0].length > path.length + 1
|
||||
else if not descendantTimestamps[i][4]?
|
||||
continue
|
||||
|
||||
for j in [0...i] by 1 when descendantTimestamps[j][4]? or descendantFlags[j]
|
||||
overlap = common.pathOverlap(descendantTimestamps[j][0], descendantTimestamps[i][0], path.length)
|
||||
|
||||
if overlap & 1 and descendantTimestamps[j][4]?
|
||||
if descendantFlags[i] & 2 and descendantTimestamps[j][0].length == path.length + 1
|
||||
descendantFlags[i] ^= 2
|
||||
if descendantFlags[i] & 1 and descendantTimestamps[j][4] > descendantTimestamps[i][2]
|
||||
descendantFlags[i] ^= 1
|
||||
|
||||
if overlap & 2 and descendantTimestamps[i][4]?
|
||||
if descendantFlags[j] & 2 and descendantTimestamps[i][0].length == path.length + 1
|
||||
descendantFlags[j] ^= 2
|
||||
if descendantFlags[j] & 1 and descendantTimestamps[i][4] > descendantTimestamps[j][2]
|
||||
descendantFlags[j] ^= 1
|
||||
|
||||
for d, j in descendantFlags
|
||||
if d & 1
|
||||
gpn = true
|
||||
if d & 2
|
||||
toLoad.push(path.concat(descendantTimestamps[j][0][path.length] ? null))
|
||||
|
||||
if declaration.length
|
||||
if declaration[0]?
|
||||
if not current[0]?
|
||||
toLoad.push(path)
|
||||
else if declaration[0] > current[0]
|
||||
r.exist = true
|
||||
|
||||
if declaration[2]?
|
||||
if not current[2]?
|
||||
toLoad.push(path)
|
||||
else if declaration[2] > current[2]
|
||||
r.writable = true
|
||||
r.exist = false
|
||||
|
||||
if declaration[4]?
|
||||
if not current[4]?
|
||||
toLoad.push(path)
|
||||
else if declaration[4] > current[4]
|
||||
r.object = true
|
||||
r.exist = false
|
||||
|
||||
if declaration[6]?
|
||||
|
||||
if not current[6]?
|
||||
toLoad.push(path) if not current[3]
|
||||
else if declaration[6] > current[6]
|
||||
if current[7]? or current[3] == 0
|
||||
r.gpv ?= []
|
||||
r.gpv.push(path)
|
||||
r.object = false
|
||||
r.exist = false
|
||||
gpn = false
|
||||
else if not current[3]?
|
||||
r.object = true
|
||||
|
||||
if declaration[7]? and current[7]?
|
||||
if not current[5]?
|
||||
toLoad.push(path)
|
||||
else if current[4] == 0
|
||||
r.writable = true
|
||||
else if current[5]
|
||||
if declaration[7][0] != current[7][0] or declaration[7][1] != current[7][1]
|
||||
r.spv = [[path, declaration[7][0], declaration[7][1]]]
|
||||
r.exist = false
|
||||
gpn = false
|
||||
|
||||
for k, v of children
|
||||
if v.writable or v.object or v.exist
|
||||
gpn = true
|
||||
|
||||
if v.gpn
|
||||
r.gpn = (r.gpn ? []).concat(v.gpn)
|
||||
r.exist = false
|
||||
|
||||
if v.gpv
|
||||
r.gpv = (r.gpv ? []).concat(v.gpv)
|
||||
r.exist = false
|
||||
|
||||
if v.spv
|
||||
r.spv = (r.spv ? []).concat(v.spv)
|
||||
r.exist = false
|
||||
|
||||
if gpn
|
||||
r.exist = false
|
||||
if r.gpn?
|
||||
r.gpn = [path].concat(r.gpn)
|
||||
else
|
||||
r.gpn = [path]
|
||||
|
||||
return r
|
||||
)
|
||||
|
||||
if toLoad.length
|
||||
loadParameters(sessionData, toLoad, (err) ->
|
||||
return callback(err) if err
|
||||
test(cb)
|
||||
)
|
||||
generateRpcRequest = (sessionData) ->
|
||||
res = device.traverse(sessionData.deviceData, null, null, (path, declaration, base, current, descendantTimestamps, children) ->
|
||||
if path[0] == 'Tags'
|
||||
if path.length == 2 and path[1]? and declaration[7]?
|
||||
if declaration[7][0] != current[7][0]
|
||||
device.set(sessionData.deviceData, path, 1, [sessionData.timestamp, 1, null, null, null, null, sessionData.timestamp, declaration[7]])
|
||||
return
|
||||
|
||||
if res.gpn?
|
||||
rpcReq = {
|
||||
type: 'GetParameterNames'
|
||||
parameterPath: res.gpn[0].join('.')
|
||||
nextLevel: true
|
||||
}
|
||||
return callback(null, rpcReq)
|
||||
r = {}
|
||||
gpn = false
|
||||
|
||||
if res.gpv?
|
||||
rpcReq = {
|
||||
type: 'GetParameterValues'
|
||||
parameterNames: (p.join('.') for p in res.gpv.slice(0, config.get('TASK_PARAMETERS_BATCH_SIZE', sessionData.deviceId)))
|
||||
}
|
||||
return callback(null, rpcReq)
|
||||
descendantRefresh = []
|
||||
for i in [0...descendantTimestamps.length] by 1 when descendantTimestamps[i][4]? or descendantTimestamps[i][2]?
|
||||
if descendantTimestamps[i][2] > descendantTimestamps[i][4]
|
||||
if current[3] == 1
|
||||
descendantRefresh[i] = true
|
||||
else
|
||||
r.object = true if current[2] < descendantTimestamps[i][2]
|
||||
|
||||
if res.spv?
|
||||
rpcReq = {
|
||||
type: 'SetParameterValues'
|
||||
parameterList: ([p[0].join('.'), p[1], p[2]] for p in res.spv.slice(0, config.get('TASK_PARAMETERS_BATCH_SIZE', sessionData.deviceId)))
|
||||
}
|
||||
return callback(null, rpcReq)
|
||||
for j in [0...i] by 1 when descendantTimestamps[j][4]? or descendantRefresh[j]
|
||||
overlap = common.pathOverlap(descendantTimestamps[j][0], descendantTimestamps[i][0], path.length)
|
||||
|
||||
return cb()
|
||||
if overlap & 1 and descendantTimestamps[j][4]?
|
||||
if descendantRefresh[i] and descendantTimestamps[j][4] > descendantTimestamps[i][2]
|
||||
descendantRefresh[i] = false
|
||||
|
||||
for declaration in declarations
|
||||
pre = device.getPrerequisiteDeclarations(declaration)
|
||||
for d in pre
|
||||
device.declare(sessionData.deviceData, d[0], d.slice(1), sessionData.timestamp)
|
||||
if overlap & 2 and descendantTimestamps[i][4]?
|
||||
if descendantRefresh[j] and descendantTimestamps[i][4] > descendantTimestamps[j][2]
|
||||
descendantRefresh[j] = false
|
||||
|
||||
test(() ->
|
||||
for declaration in declarations
|
||||
params = device.getAll(sessionData.deviceData, declaration[0], null)
|
||||
if declaration[0][0] == 'Tags' and declaration[0].length == 2
|
||||
if not declaration[0][1]?
|
||||
continue if declaration[8][0]
|
||||
else if params.length == 0
|
||||
device.set(sessionData.deviceData, declaration[0], 1, [sessionData.timestamp, 1, null, null, null, null, sessionData.timestamp, [false, 'xsd:boolean']])
|
||||
device.declare(sessionData.deviceData, declaration[0], declaration.slice(1), sessionData.timestamp)
|
||||
continue
|
||||
for d in descendantRefresh when d
|
||||
gpn = true
|
||||
break
|
||||
|
||||
for p in params
|
||||
device.declare(sessionData.deviceData, p[0], declaration.slice(1), sessionData.timestamp)
|
||||
if declaration.length
|
||||
if declaration[0] > current[0]
|
||||
r.exist = true
|
||||
|
||||
test(() ->
|
||||
return callback()
|
||||
)
|
||||
if declaration[2] > current[2]
|
||||
r.writable = true
|
||||
r.exist = false
|
||||
|
||||
if declaration[4] > current[4]
|
||||
r.object = true
|
||||
r.exist = false
|
||||
|
||||
if declaration[6] > current[6]
|
||||
if current[7]? or current[3] == 0
|
||||
r.gpv ?= []
|
||||
r.gpv.push(path)
|
||||
r.object = false
|
||||
r.exist = false
|
||||
gpn = false
|
||||
else if not current[3]?
|
||||
r.object = true
|
||||
|
||||
if declaration[7]? and current[7]?
|
||||
if current[4] == 0
|
||||
r.writable = true
|
||||
else if current[5]
|
||||
if declaration[7][0] != current[7][0] or declaration[7][1] != current[7][1]
|
||||
r.spv = [[path, declaration[7][0], declaration[7][1]]]
|
||||
r.exist = false
|
||||
gpn = false
|
||||
|
||||
for k, v of children
|
||||
if v.writable or v.object or v.exist
|
||||
gpn = true
|
||||
|
||||
if v.gpn
|
||||
r.gpn = (r.gpn ? []).concat(v.gpn)
|
||||
r.exist = false
|
||||
|
||||
if v.gpv
|
||||
r.gpv = (r.gpv ? []).concat(v.gpv)
|
||||
r.exist = false
|
||||
|
||||
if v.spv
|
||||
r.spv = (r.spv ? []).concat(v.spv)
|
||||
r.exist = false
|
||||
|
||||
if gpn
|
||||
r.exist = false
|
||||
if r.gpn?
|
||||
r.gpn = [path].concat(r.gpn)
|
||||
else
|
||||
r.gpn = [path]
|
||||
|
||||
return r
|
||||
)
|
||||
|
||||
if res.gpn?
|
||||
rpcReq = {
|
||||
type: 'GetParameterNames'
|
||||
parameterPath: res.gpn[0].join('.')
|
||||
nextLevel: true
|
||||
}
|
||||
return rpcReq
|
||||
|
||||
rpcRequest = (sessionData, allDeclarations, callback) ->
|
||||
allDeclarations = allDeclarations?.slice() ? []
|
||||
if res.gpv?
|
||||
rpcReq = {
|
||||
type: 'GetParameterValues'
|
||||
parameterNames: (p.join('.') for p in res.gpv.slice(0, config.get('TASK_PARAMETERS_BATCH_SIZE', sessionData.deviceId)))
|
||||
}
|
||||
return rpcReq
|
||||
|
||||
nextRevision = false
|
||||
if res.spv?
|
||||
rpcReq = {
|
||||
type: 'SetParameterValues'
|
||||
parameterList: ([p[0].join('.'), p[1], p[2]] for p in res.spv.slice(0, config.get('TASK_PARAMETERS_BATCH_SIZE', sessionData.deviceId)))
|
||||
}
|
||||
return rpcReq
|
||||
|
||||
cache.getScripts((err, presetsHash, scripts) ->
|
||||
return null
|
||||
|
||||
|
||||
loadDeclarations = (sessionData, virtualParameters, callback) ->
|
||||
toLoad = []
|
||||
device.traverse(sessionData.deviceData, null, null, (path, declaration, base, current, descendantTimestamps, children) ->
|
||||
descendantLoad = []
|
||||
for i in [0...descendantTimestamps.length] by 1
|
||||
if descendantTimestamps[i][2]?
|
||||
if not descendantTimestamps[i][4]?
|
||||
toLoad.push(descendantTimestamps[i][0])
|
||||
continue
|
||||
else if descendantTimestamps[i][2] > descendantTimestamps[i][4]
|
||||
descendantLoad[i] = true if descendantTimestamps[i][0].length > path.length + 1
|
||||
else if not descendantTimestamps[i][4]?
|
||||
continue
|
||||
|
||||
for j in [0...i] by 1 when descendantTimestamps[j][4]? or descendantFlags[j]
|
||||
overlap = common.pathOverlap(descendantTimestamps[j][0], descendantTimestamps[i][0], path.length)
|
||||
|
||||
if overlap & 1 and descendantTimestamps[j][4]?
|
||||
if descendantLoad[i] and descendantTimestamps[j][0].length == path.length + 1
|
||||
descendantLoad[i] = false
|
||||
|
||||
if overlap & 2 and descendantTimestamps[i][4]?
|
||||
if descendantLoad[j] and descendantTimestamps[i][0].length == path.length + 1
|
||||
descendantLoad[j] = false
|
||||
|
||||
for d, j in descendantLoad when d
|
||||
toLoad.push(path.concat(descendantTimestamps[j][0][path.length] ? null))
|
||||
|
||||
for i in [0...declaration.length] by 2
|
||||
if declaration[i]? and not current[i]?
|
||||
toLoad.push(path)
|
||||
break
|
||||
)
|
||||
|
||||
# Virtual parameters
|
||||
for p in toLoad
|
||||
if not p[0]? or p[0] == 'VirtualParameters'
|
||||
if p.length == 1
|
||||
device.set(sessionData.deviceData, ['VirtualParameters'], 1, [sessionData.timestamp, 1, sessionData.timestamp, 1, sessionData.timestamp, 0])
|
||||
else if p.length == 2
|
||||
if not p[1]?
|
||||
for k, v of virtualParameters
|
||||
device.set(sessionData.deviceData, ['VirtualParameters', k], 1, [sessionData.timestamp, 1, sessionData.timestamp, 0])
|
||||
else if virtualParameters[p[1]]?
|
||||
device.set(sessionData.deviceData, ['VirtualParameters', p[1]], 1, [sessionData.timestamp, 1, sessionData.timestamp, 0])
|
||||
|
||||
return loadParameters(sessionData, toLoad, callback)
|
||||
|
||||
|
||||
extractVirtualParameterDeclarations = (sessionData) ->
|
||||
virtualParameterDeclarations = []
|
||||
res = device.traverse(sessionData.deviceData, ['VirtualParameters', null], null, (path, declaration, base, current, descendantTimestamps, children) ->
|
||||
if path.length == 2 and declaration?.length
|
||||
d = [path]
|
||||
for i in [0...declaration.length] by 2
|
||||
if declaration[i]? and not (declaration[i] <= current[i])
|
||||
d[i + 1] = declaration[i]
|
||||
if declaration[i + 1]?
|
||||
if i != 6 or not current[i + 1]?
|
||||
d[i + 2] = declaration[i + 1]
|
||||
else if declaration[i + 1][0] != current[i + 1][0] and
|
||||
(declaration[i + 1][0] != current[i + 1][0] or not declaration[i + 1][1]?)
|
||||
d[i + 2] = declaration[i + 1]
|
||||
if d.length > 1
|
||||
virtualParameterDeclarations.push(d)
|
||||
)
|
||||
|
||||
device.clearDeclarations(sessionData.deviceData, ['VirtualParameters'])
|
||||
return virtualParameterDeclarations
|
||||
|
||||
|
||||
commitVirtualParameter = (sessionData, parameterDeclaration, revision, update) ->
|
||||
v = []
|
||||
if update.writable?
|
||||
if update.writable[0] <= 0
|
||||
v[4] = now + update.writable[0]
|
||||
else
|
||||
v[4] = Math.min(sessionData.timestamp, update.writable[0])
|
||||
|
||||
if parameterDeclaration[5]?
|
||||
v[4] = Math.max(parameterDeclaration[5], v[4])
|
||||
|
||||
v[5] = Boolean(JSON.parse(update.writable[1]))
|
||||
else if parameterDeclaration[5]? or parameterDeclaration[6]?
|
||||
throw new Error('Virtual parameter must provide declared attributes')
|
||||
|
||||
if update.value?
|
||||
if update.value[0] <= 0
|
||||
v[6] = sessionData.timestamp + update.value[0]
|
||||
else
|
||||
v[6] = Math.min(now, update.value[0])
|
||||
|
||||
if parameterDeclaration[7]?
|
||||
v[6] = Math.max(parameterDeclaration[7], v[6])
|
||||
|
||||
v[7] = device.sanitizeParameterValue(update.value[1])
|
||||
else if parameterDeclaration[7]? or parameterDeclaration[8]?
|
||||
throw new Error('Virtual parameter must provide declared attributes')
|
||||
|
||||
device.set(sessionData.deviceData, parameterDeclaration[0], revision, v)
|
||||
|
||||
|
||||
rpcRequest = (sessionData, declarations, callback) ->
|
||||
allDeclarations = declarations?.slice() ? []
|
||||
|
||||
cache.getProvisionsAndVirtualParameters((err, presetsHash, provisions, virtualParameters) ->
|
||||
return callback(err) if err or presetsHash != sessionData.presetsHash
|
||||
|
||||
done = true
|
||||
for provision in sessionData.provisions
|
||||
if not scripts[provision[0]]?
|
||||
if not provisions[provision[0]]?
|
||||
switch provision[0]
|
||||
when 'refresh'
|
||||
path = common.parsePath(provision[1])
|
||||
@@ -306,63 +350,131 @@ rpcRequest = (sessionData, allDeclarations, callback) ->
|
||||
allDeclarations.push([[['Tags', provision[1]], null, null, null, null, null, null, null, [provision[2], 'xsd:boolean']]])
|
||||
continue
|
||||
|
||||
nextRevision ||= sandbox.run(scripts[provision[0]].compiled, provision.slice(1), sessionData.deviceData, sessionData.counter[1], allDeclarations)
|
||||
ret = sandbox.run(provisions[provision[0]].script, provision.slice(1), sessionData.deviceData, 0, sessionData.revisions[0] >> 1)
|
||||
done &&= ret.done
|
||||
allDeclarations = allDeclarations.concat(ret.declarations)
|
||||
|
||||
generateRpcRequest(sessionData, allDeclarations, (err, rpcReq) ->
|
||||
sessionData.rpcRequest = rpcReq
|
||||
return callback(err) if err
|
||||
if done and (not allDeclarations?.length or sessionData.revisions[0] > 1)
|
||||
return callback()
|
||||
|
||||
if not rpcReq?
|
||||
if not nextRevision
|
||||
return callback()
|
||||
sessionData.counter[0] = 0
|
||||
sessionData.counter[1] += 1
|
||||
return rpcRequest(sessionData, null, callback)
|
||||
doVirtualParameters = (iter, virtualParameterDeclarations, cb) ->
|
||||
if not virtualParameterDeclarations?
|
||||
virtualParameterDeclarations = extractVirtualParameterDeclarations(sessionData)
|
||||
if not virtualParameterDeclarations?.length
|
||||
return cb(false)
|
||||
|
||||
callback(err, generateRpcId(sessionData), rpcReq)
|
||||
sessionData.revisions[iter] ?= 0
|
||||
decs = []
|
||||
virtualParameterUpdates = []
|
||||
for vpd, i in virtualParameterDeclarations
|
||||
vpName = vpd[0][1]
|
||||
continue if not virtualParameters[vpName]?
|
||||
lastRevision = sessionData.revisions.reduce((a, b) -> (a >> 1) + (b >> 1))
|
||||
firstRevision = lastRevision - (sessionData.revisions[sessionData.revisions.length - 1] >> 1)
|
||||
ret = sandbox.run(virtualParameters[vpName].script, [vpd.slice(1)], sessionData.deviceData, firstRevision, lastRevision)
|
||||
decs = decs.concat(ret.declarations)
|
||||
if ret.done
|
||||
virtualParameterUpdates.push(ret.returnValue)
|
||||
|
||||
if virtualParameterUpdates.length == virtualParameterDeclarations.length
|
||||
rev = sessionData.revisions.reduce((a, b) -> (a >> 1) + (b >> 1))
|
||||
for vpd, i in virtualParameterDeclarations
|
||||
commitVirtualParameter(sessionData, vpd, rev + 1, virtualParameterUpdates[i])
|
||||
|
||||
if sessionData.revisions[iter] == 0
|
||||
return cb(false)
|
||||
|
||||
sessionData.revisions.length = iter
|
||||
rev = sessionData.revisions.reduce((a, b) -> (a >> 1) + (b >> 1))
|
||||
device.collapse(sessionData.deviceData, rev + 1)
|
||||
return cb(true)
|
||||
|
||||
applyDeclarations(iter, decs, () ->
|
||||
return doVirtualParameters(iter, virtualParameterDeclarations, cb)
|
||||
)
|
||||
|
||||
applyDeclarations = (iter, decs, cb) ->
|
||||
if sessionData.revisions[iter] % 2 == 0
|
||||
for declaration in decs
|
||||
for d in device.getPrerequisiteDeclarations(declaration)
|
||||
device.declare(sessionData.deviceData, d[0], d.slice(1), sessionData.timestamp)
|
||||
else
|
||||
for declaration in decs
|
||||
params = device.getAll(sessionData.deviceData, declaration[0], sessionData.revisions[iter] >> 1)
|
||||
if declaration[0][0] == 'Tags' and declaration[0].length == 2
|
||||
if not declaration[0][1]?
|
||||
continue if declaration[8][0]
|
||||
else if params.length == 0
|
||||
device.set(sessionData.deviceData, declaration[0], 1, [sessionData.timestamp, 1, null, null, null, null, sessionData.timestamp, [false, 'xsd:boolean']])
|
||||
device.declare(sessionData.deviceData, declaration[0], declaration.slice(1), sessionData.timestamp)
|
||||
continue
|
||||
for p in params
|
||||
device.declare(sessionData.deviceData, p[0], declaration.slice(1), sessionData.timestamp)
|
||||
|
||||
nextRpc = (applied) ->
|
||||
if not applied
|
||||
if (rpcReq = generateRpcRequest(sessionData))?
|
||||
sessionData.rpcRequest = rpcReq
|
||||
return callback(null, generateRpcId(sessionData), rpcReq)
|
||||
|
||||
if ++ sessionData.revisions[iter] % 2 == 0
|
||||
return cb()
|
||||
else
|
||||
return applyDeclarations(iter, decs, cb)
|
||||
|
||||
if sessionData.revisions.length > iter + 1
|
||||
doVirtualParameters(iter + 1, null, nextRpc)
|
||||
else
|
||||
loadDeclarations(sessionData, virtualParameters, (err) ->
|
||||
return callback(err) if err
|
||||
doVirtualParameters(iter + 1, null, nextRpc)
|
||||
)
|
||||
|
||||
applyDeclarations(0, allDeclarations, () ->
|
||||
return rpcRequest(sessionData, declarations, callback)
|
||||
)
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
rpcResponse = (sessionData, id, rpcRes, callback) ->
|
||||
if id != generateRpcId(sessionData)
|
||||
return callback(new Error('Request ID not recognized'))
|
||||
|
||||
++ sessionData.counter[0]
|
||||
++ sessionData.rpcCount
|
||||
|
||||
rpcReq = sessionData.rpcRequest
|
||||
sessionData.rpcRequest = null
|
||||
|
||||
timestamp = sessionData.timestamp
|
||||
revision = sessionData.revisions.reduce((a, b) -> (a >> 1) + (b >> 1)) + 1
|
||||
|
||||
switch rpcRes.type
|
||||
when 'GetParameterValuesResponse'
|
||||
return callback(new Error('Response type does not match request type')) if rpcReq.type isnt 'GetParameterValues'
|
||||
|
||||
for p in rpcRes.parameterList
|
||||
device.set(sessionData.deviceData, common.parsePath(p[0]), 1, [timestamp, 1, timestamp, 0, null, null, timestamp, p.slice(1)])
|
||||
device.set(sessionData.deviceData, common.parsePath(p[0]), revision, [timestamp, 1, timestamp, 0, null, null, timestamp, p.slice(1)])
|
||||
|
||||
when 'GetParameterNamesResponse'
|
||||
return callback(new Error('Response type does not match request type')) if rpcReq.type isnt 'GetParameterNames'
|
||||
|
||||
device.set(sessionData.deviceData, common.parsePath(rpcReq.parameterPath).concat(null), 1, timestamp)
|
||||
device.set(sessionData.deviceData, common.parsePath(rpcReq.parameterPath).concat(null), revision, timestamp)
|
||||
|
||||
for p in rpcRes.parameterList
|
||||
if common.endsWith(p[0], '.')
|
||||
path = common.parsePath(p[0][0...-1])
|
||||
if not rpcReq.nextLevel
|
||||
device.set(sessionData.deviceData, path.conact(null), 1, timestamp)
|
||||
device.set(sessionData.deviceData, path.conact(null), revision, timestamp)
|
||||
|
||||
device.set(sessionData.deviceData, path, 1, [timestamp, 1, timestamp, 1, timestamp, if p[1] then 1 else 0])
|
||||
device.set(sessionData.deviceData, path, revision, [timestamp, 1, timestamp, 1, timestamp, if p[1] then 1 else 0])
|
||||
else
|
||||
device.set(sessionData.deviceData, common.parsePath(p[0]), 1, [timestamp, 1, timestamp, 0, timestamp, if p[1] then 1 else 0])
|
||||
device.set(sessionData.deviceData, common.parsePath(p[0]), revision, [timestamp, 1, timestamp, 0, timestamp, if p[1] then 1 else 0])
|
||||
|
||||
when 'SetParameterValuesResponse'
|
||||
return callback(new Error('Response type does not match request type')) if rpcReq.type isnt 'SetParameterValues'
|
||||
|
||||
for p in rpcReq.parameterList
|
||||
device.set(sessionData.deviceData, common.parsePath(p[0]), 1, [timestamp, 1, timestamp, 0, timestamp, 1, timestamp, p.slice(1)])
|
||||
device.set(sessionData.deviceData, common.parsePath(p[0]), revision, [timestamp, 1, timestamp, 0, timestamp, 1, timestamp, p.slice(1)])
|
||||
|
||||
else
|
||||
return callback(new Error('Response type not recognized'))
|
||||
|
||||
Reference in new issue
Block a user