remoteOutput.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. const net = require('net');
  2. var clients = {};
  3. function Client(sock) {
  4. var _this = this;
  5. this.id = sock.remoteAddress;
  6. this.name = this.id;
  7. this.sock = sock;
  8. this.active = true;
  9. this.volumeControl = true;
  10. this.status = {
  11. battery: undefined,
  12. plugged: undefined,
  13. volume: undefined,
  14. lastUpdate: 0
  15. };
  16. this.ping = {
  17. duration: 0,
  18. lastUpdate: 0,
  19. pending: 0
  20. };
  21. this.sock.on('data', (data) => {
  22. var dataStr = data.toString("utf-8");
  23. dataStr.split(/[\r\n]/).forEach(i => i.length ? _this.onData(i) : i);
  24. });
  25. this.sock.on('close', () => {
  26. if (this.active) {
  27. delete clients[this.id];
  28. require("./outputs.js").unregisterOutput(this.id);
  29. }
  30. });
  31. this.radios = {};
  32. var allRadios = require("./config.js").RADIOS;
  33. for (var i in allRadios)
  34. this.radios[i] = {
  35. address: allRadios[i],
  36. state: false
  37. };
  38. this.sendInputStates();
  39. }
  40. Client.prototype.onData = function(data) {
  41. if (data.startsWith("HELO"))
  42. this.name = data.replace(/^HELO\s+/, "") +" (" +this.sock.remoteAddress +")";
  43. else if (data.startsWith("STATUS")) {
  44. data = JSON.parse(data.substr("STATUS".length));
  45. if (data) {
  46. this.status.battery = data.battery || this.status.battery;
  47. this.status.plugged = data.plugged !== undefined ? data.plugged :this.status.battery;
  48. this.status.plugged = data.volume !== undefined ? data.volume :this.status.volume;
  49. this.status.lastUpdate = Date.now();
  50. }
  51. } else if (data.startsWith("PONG")) {
  52. if (this.ping.pending) {
  53. const now = Date.now();
  54. this.ping = {
  55. lastUpdate: now,
  56. duration: now -this.ping.pending,
  57. pending: 0
  58. };
  59. }
  60. }
  61. }
  62. Client.prototype.requestPing = function() {
  63. this.ping.pending = Date.now();
  64. this.sock.write("PING");
  65. }
  66. Client.prototype.getName = function() {
  67. return this.name;
  68. }
  69. Client.prototype.kill = function() {
  70. this.sock.destroy();
  71. this.active = false;
  72. }
  73. Client.prototype.getInputs = function() {
  74. var result = {};
  75. for (var i in this.radios)
  76. result[i] = this.radios[i].state;
  77. return result;
  78. }
  79. Client.prototype.sendInputStates = function() {
  80. this.sock.write(JSON.stringify(this.radios) +"\n");
  81. }
  82. Client.prototype.setState = function(inputId, state) {
  83. if (!this.radios[inputId])
  84. return false;
  85. if (this.radios[inputId].state !== !!state) {
  86. this.radios[inputId].state = !!state;
  87. this.sendInputStates();
  88. }
  89. return true;
  90. }
  91. Client.prototype.getStatus = function() {
  92. return {
  93. status: this.status.lastUpdate ? this.status : undefined,
  94. ping: this.ping.lastUpdate ? this.ping : undefined
  95. };
  96. }
  97. function onClientConnection(sock) {
  98. var cli = new Client(sock);
  99. if (clients[cli.id])
  100. clients[cli.id].kill();
  101. clients[cli.id] = cli;
  102. require("./outputs.js").registerOutput(cli.id, cli);
  103. }
  104. module.exports.init = function() {
  105. net.createServer(onClientConnection).listen(require('./config.js').TCP_PORT, require('./config.js').TCP_LISTEN);
  106. }