evcharger
Version:
Cost clearing and balancing in energy blockchain for KEBA based electric vehicle charging devices (Wallbox). Payment framework for distributed ledger in e-mobility scenarios.
200 lines (184 loc) • 7.48 kB
JavaScript
/* StromDAO Business Object: EV Charger
* =========================================
* Connect to Business Object ( https://github.com/energychain/StromDAO-BusinessObject )
*
* @author Thorsten Zoerner thorsten.zoerner@stromdao.com
*
* If used in StromDAO-BO's MAIN BRANCH this will be defaulted to the testnet environment.
*
*/
const vorpal = require('vorpal')();
var com = require("./keba.js");
var StromDAOBO = require("stromdao-businessobject");
const vm = require('vm');
module.exports = {
update:function(args,callback) {
args.num="3";
com.report(args,function(report) {
var extid=report.Serial;
var reading =Math.floor(report["E total"]/10);
if(reading>0) {
var node = new StromDAOBO.Node({external_id:extid,testMode:true,rpc:global.rpcprovider});
vorpal.log("BC Twin",node.wallet.address);
node.mpr().then(function(mpo) {
mpo.storeReading(reading).then(function(tx) {
vorpal.log("Updated Serial",extid,reading);
vorpal.log("Tx",tx);
callback();
});
});
} else {
callback();
}
});
},
lastReading:function(args,callback) {
args.num="3";
com.report(args,function(report) {
var extid=report.Serial;
var node = new StromDAOBO.Node({external_id:extid,testMode:true,rpc:global.rpcprovider});
node.mpr().then(function(mpo) {
mpo.readings(node.wallet.address).then(function(reading) {
if(reading.power.toString()*1<Math.floor(report["E total"]/10)) {
mpo.storeReading(Math.floor(report["E total"]/10)).then(function(tx) {
vorpal.log("Updated Serial",extid,reading);
vorpal.log("Tx",tx);
vorpal.log("Reading",reading.time.toString(),reading.power.toString());
callback(reading);
});
} else {
vorpal.log("Reading",reading.time.toString(),reading.power.toString());
callback(reading);
}
});
});
});
},
start:function(args,callback) {
bo.lastReading(args,function(reading) {
var extid=args.customerid;
var node = new StromDAOBO.Node({external_id:extid+"_input",testMode:true,rpc:global.rpcprovider});
node.mpr().then(function(mpo) {
mpo.storeReading(reading.power.toString()).then(function(tx) {
vorpal.log("Updated Customer",extid,reading.power.toString());
vorpal.log("Tx",tx);
callback();
});
});
});
},
stop:function(args,callback) {
bo.lastReading(args,function(reading) {
var extid=args.customerid;
var node = new StromDAOBO.Node({external_id:extid+"_input",testMode:true,rpc:global.rpcprovider});
var input = node.wallet.address;
var node = new StromDAOBO.Node({external_id:extid,testMode:true,rpc:global.rpcprovider});
node.mpr().then(function(mpo) {
mpo.readings(input).then(function(tx) {
var delta = reading.power.toString()*1-tx.power.toString()*1;
if(delta>0) {
mpo.readings(node.wallet.address).then(function(rx) {
delta+=rx.power.toString()*1;
mpo.storeReading(delta).then(function(yx) {
vorpal.log("Tx",yx);
callback();
});
});
} else {
vorpal.log("No Consumption");
callback();
}
});
});
});
},
retrieve:function(args,callback) {
var extid=args.customerid;
var node = new StromDAOBO.Node({external_id:extid,testMode:true,rpc:global.rpcprovider});
node.mpr().then(function(mpo) {
mpo.readings(node.wallet.address).then(function(tx) {
vorpal.log("Last Charge",new Date(tx.time.toString()*1000).toLocaleString());
vorpal.log("Total Energy",tx.power.toString());
});
});
},
clearing:function(args,callback) {
var node = new StromDAOBO.Node({external_id:"stromdao-mp",rpc:global.rpcprovider,testMode:true})
global.blk_address=node.wallet.address;
node.roleLookup().then(function(rl) {
rl.relations(node.wallet.address,42).then(function(tx) {
if(tx=="0x0000000000000000000000000000000000000000") {
vorpal.log("ERROR: Consensus failed - no Meter Point Operation in place");
callback();
} else {
global.smart_contract_stromkonto=tx;
var extid=args.customerid;
var report=args.reportid;
args.num=report;
bo._ensureAllowedTx(extid).then(function(d) {
com.report(args,function(rep) {
var node = new StromDAOBO.Node({external_id:extid,testMode:true,rpc:global.rpcprovider});
global.settlement={};
global.node=node;
settlement.account=node.wallet.address;
var node = new StromDAOBO.Node({external_id:"stromdao-mp",testMode:true,rpc:global.rpcprovider});
settlement.node_account=global.blk_address; // Require Retrieve!
settlement.node_wallet=node.nodeWallet.address;
settlement.base = Math.floor(rep["E pres"]/10);
var to=settlement.node_account;
var from=settlement.account;
settlement.cost=0;
if(typeof args.options.workprice != "undefined") {
if(args.options.workprice<0) { from=settlement.node_account; to=settlement.account; }
settlement.cost=Math.abs(Math.round(args.options.workprice*(settlement.base/1000)));
}
if(typeof args.options.sessionprice != "undefined") {
settlement.cost+=args.options.sessionprice*1;
}
var settlement_js="global.promise = new Promise(function(resolve2,reject2) { node.stromkontoproxy(global.smart_contract_stromkonto).then(function(sko) { sko.addTx(settlement.from,settlement.to,settlement.cost,settlement.base).then(function(tx) { console.log('AddTx',settlement.from,settlement.to,settlement.cost,settlement.base,tx); resolve2(tx);});});});";
settlement.from=from;
settlement.to=to;
var script = new vm.Script(settlement_js);
var result=script.runInThisContext();
if(typeof global.promise!="undefined") {
global.promise.then(function(tx) {
callback();
});
} else {
callback();
}
});
});
}
});
});
},
_ensureAllowedTx:function(extid) {
var p1 = new Promise(function(resolve, reject) {
var node = new StromDAOBO.Node({external_id:extid,testMode:true,rpc:global.rpcprovider});
var sender=node.wallet.address;
var node = new StromDAOBO.Node({external_id:"stromdao-mp",testMode:true,rpc:global.rpcprovider});
var managed_meters= node.storage.getItemSync("managed_meters");
if(managed_meters==null) managed_meters=[]; else managed_meters=JSON.parse(managed_meters);
if(node.storage.getItemSync("managed_"+extid)==null) {
managed_meters.push(extid);
node.storage.setItemSync("managed_meters",JSON.stringify(managed_meters));
node.storage.setItemSync("managed_"+extid,sender);
node.stromkontoproxy().then(function(skop) {
skop.modifySender(sender,true).then(function(tx) {
vorpal.log("Mandated ",extid,tx);
resolve("mandated");
});
});
} else {
resolve("mandated");
}
});
return p1;
},
storage:function() {
var node = new StromDAOBO.Node({external_id:"stromdao-mp",testMode:true,rpc:global.rpcprovider});
return node.storage;
}
};
var bo = module.exports;