Receiving data by JS sent by WebSocket

I'm having a problem receiving data via JS sent by WebSocket. Data is being received by the client but it is not correctly updating a gauge.

This is the JS:

let ws; // Variável para armazenar a conexão WebSocket

// Função para conectar ao servidor via WebSocket
function connectWebSocket() {
  ws = new WebSocket('ws://192.168.68.107/ws');

  // Evento disparado quando a conexão é aberta
  ws.onopen = function(event) {
    console.log('Conexão WebSocket estabelecida.');
  };

  // Evento disparado quando a conexão é fechada
  ws.onclose = function(event) {
    console.log('Conexão WebSocket fechada.');
  };

  // Evento disparado quando uma mensagem é recebida do servidor
  ws.onmessage = function(event) {
    console.log('Mensagem recebida:', event.data);
    let data = JSON.parse(event.data);

    // Verifica se o campo "sensor" existe no JSON
    if ("sensor" in data) {
      let sensorValue = parseFloat(data.sensor);

      // Atualiza o valor do Gauge com o valor numérico
      gauge2.setValueAnimated(sensorValue);
    } else {
      console.error('Campo "sensor" não encontrado no JSON:', event.data);
    }
  };

  // Evento disparado em caso de erro na conexão WebSocket
  ws.onerror = function(event) {
    console.error('Erro na conexão WebSocket:', event);
  };
}

No console, esse é o erro:

Mensagem recebida: {"sensor":"19.88"}
script.js:31 Uncaught TypeError: Cannot read properties of undefined (reading 'setValueAnimated')
    at ws.onmessage (script.js:31:14)

What could be causing this error?

what's gauge2 ?

JavaScript

// INÍCIO FUNÇAO GAUGE
!function(e){var t,o,F,S,n=(o=(t=e).document,F=Array.prototype.slice,S=t.requestAnimationFrame||t.mozRequestAnimationFrame||t.webkitRequestAnimationFrame||t.msRequestAnimationFrame||function(e){return setTimeout(e,1e3/60)},function(){var r="http://www.w3.org/2000/svg",M={centerX:50,centerY:50},k={dialRadius:40,dialStartAngle:135,dialEndAngle:45,value:0,max:100,min:0,valueDialClass:"value",valueClass:"value-text",dialClass:"dial",gaugeClass:"gauge",showValue:!0,gaugeColor:null,label:function(e){return Math.round(e)}};function V(e,t,n){var a=o.createElementNS(r,e);for(var i in t)a.setAttribute(i,t[i]);return n&&n.forEach(function(e){a.appendChild(e)}),a}function R(e,t){return e*t/100}function E(e,t,n){var a=Number(e);return n<a?n:a<t?t:a}function q(e,t,n,a){var i=a*Math.PI/180;return{x:Math.round(1e3*(e+n*Math.cos(i)))/1e3,y:Math.round(1e3*(t+n*Math.sin(i)))/1e3}}return function(e,r){r=function(){var n=arguments[0];return F.call(arguments,1).forEach(function(e){for(var t in e)e.hasOwnProperty(t)&&(n[t]=e[t])}),n}({},k,r);var o,l,t,n=e,s=r.max,u=r.min,a=E(r.value,u,s),c=r.dialRadius,d=r.showValue,f=r.dialStartAngle,v=r.dialEndAngle,i=r.valueDialClass,m=r.valueClass,g=(r.valueLabelClass,r.dialClass),h=r.gaugeClass,p=r.color,w=r.label,x=r.viewBox;if(f<v){console.log("WARN! startAngle < endAngle, Swapping");var A=f;f=v,v=A}function y(e,t,n,a){var i=function(e,t,n){var a=M.centerX,i=M.centerY;return{end:q(a,i,e,n),start:q(a,i,e,t)}}(e,t,n),r=i.start,o=i.end,l=void 0===a?1:a;return["M",r.x,r.y,"A",e,e,0,l,1,o.x,o.y].join(" ")}function b(e,t){var n=function(e,t,n){return 100*(e-t)/(n-t)}(e,u,s),a=R(n,360-Math.abs(f-v)),i=a<=180?0:1;d&&(o.textContent=w.call(r,e)),l.setAttribute("d",y(c,f,a+f,i))}function C(e,t){var n=p.call(r,e),a=1e3*t,i="stroke "+a+"ms ease";l.style.stroke=n,l.style["-webkit-transition"]=i,l.style["-moz-transition"]=i,l.style.transition=i}return t={setMaxValue:function(e){s=e},setValue:function(e){a=E(e,u,s),p&&C(a,0),b(a)},setValueAnimated:function(e,t){var n=a;a=E(e,u,s),n!==a&&(p&&C(a,t),function(e){var t=e.duration,a=1,i=60*t,r=e.start||0,o=e.end-r,l=e.step,s=e.easing||function(e){return(e/=.5)<1?.5*Math.pow(e,3):.5*(Math.pow(e-2,3)+2)};S(function e(){var t=a/i,n=o*s(t)+r;l(n,a),a+=1,t<1&&S(e)})}({start:n||0,end:a,duration:t||1,step:function(e,t){b(e,t)}}))},getValue:function(){return a}},function(e){o=V("text",{x:50,y:50,fill:"#999",class:m,"font-size":"100%","font-family":"sans-serif","font-weight":"normal","text-anchor":"middle","alignment-baseline":"middle","dominant-baseline":"central"}),l=V("path",{class:i,fill:"none",stroke:"#666","stroke-width":2.5,d:y(c,f,f)});var t=R(100,360-Math.abs(f-v)),n=V("svg",{viewBox:x||"0 0 100 100",class:h},[V("path",{class:g,fill:"none",stroke:"#eee","stroke-width":2,d:y(c,f,v,t<=180?0:1)}),V("g",{class:"text-container"},[o]),l]);e.appendChild(n)}(n),t.setValue(a),t}}());"function"==typeof define&&define.amd?define(function(){return n}):"object"==typeof module&&module.exports?module.exports=n:e.Gauge=n}("undefined"==typeof window?this:window);
// FIM FUNÇAO GAUGE

let ws; // Variável para armazenar a conexão WebSocket

// Função para conectar ao servidor via WebSocket
function connectWebSocket() {
  ws = new WebSocket('ws://192.168.68.107/ws');

  // Evento disparado quando a conexão é aberta
  ws.onopen = function(event) {
    console.log('Conexão WebSocket estabelecida.');
  };

  // Evento disparado quando a conexão é fechada
  ws.onclose = function(event) {
    console.log('Conexão WebSocket fechada.');
  };

  // Evento disparado quando uma mensagem é recebida do servidor
  ws.onmessage = function(event) {
    console.log('Mensagem recebida:', event.data);
    let data = JSON.parse(event.data);

    // Verifica se o campo "sensor" existe no JSON
    if ("sensor" in data) {
      let sensorValue = parseFloat(data.sensor);

      // Atualiza o valor do Gauge com o valor numérico
      gauge2.setValueAnimated(sensorValue);
    } else {
      console.error('Campo "sensor" não encontrado no JSON:', event.data);
    }
  };

  // Evento disparado em caso de erro na conexão WebSocket
  ws.onerror = function(event) {
    console.error('Erro na conexão WebSocket:', event);
  };
}

// Função para desconectar do servidor via WebSocket
function disconnectWebSocket() {
  if (ws) {
    ws.close();
  }
}

// Conectar ao WebSocket quando a página é carregada
window.addEventListener('load', function() {
  connectWebSocket();
});

// Reconectar ao WebSocket em caso de falha na conexão
function reconnectWebSocket() {
  setTimeout(function() {
    console.log('Tentando reconectar...');
    connectWebSocket();
  }, 5000); // Tentar reconectar após 5 segundos
}

// Reconectar automaticamente em caso de falha na conexão
ws.addEventListener('close', function() {
  reconnectWebSocket();
});

var gauge2 = Gauge(
  document.getElementById("gauge2"), {
    min: -2,
    max: 30,
    dialStartAngle: 130,
    dialEndAngle: 50,
    value: 50,
    color: function(value) {
      if (value < 8) {
        return "#5ee432";
      } else if (value < 12) {
        return "#fffa50";
      } else if (value < 20) {
        return "#f7aa38";
      } else {
        return "#ef4655";
      }
    },
    label: function(value) {
      return value.toFixed(2) + " ºC"; // Adiciona a unidade de graus Celsius ao texto
    }
  }
);

CSS

/* ------ Definições do Gauge ---------- */
.gauge-container {
  width: 150px;
  height: 150px;
  display: block;
  float: left;
  padding: 10px;
  background-color: #222;
  margin: 7px;
  border-radius: 3px;
  position: relative;
}
.gauge-container > .label {
  position: absolute;
  right: 0;
  top: 0;
  display: inline-block;
  background: rgba(0, 0, 0, 0.5);
  font-family: monospace;
  font-size: 0.8em;
  padding: 5px 10px;
}

.wrapper {
  height: 100px;
  float: left;
  margin: 7px;
  overflow: hidden;
}
.wrapper > .gauge-container {
  margin: 0;
}
.gauge-container.two > .gauge .dial {
  stroke: #334455;
  stroke-width: 5;
  stroke-linecap: round;
}
.gauge-container.two > .gauge .value {
  stroke: orange;
  stroke-dasharray: none;
  stroke-width: 6;
  stroke-linecap: round;
}
.gauge-container.two > .gauge .value-text {
  fill: #ccc;
  font-weight: 100;
  font-size: 0.8em;
}

html

  <div id="gauge2" class="gauge-container two">
    <span class="label"></span>
</div>

It worked out

// INÍCIO FUNÇAO GAUGE
!function(e){var t,o,F,S,n=(o=(t=e).document,F=Array.prototype.slice,S=t.requestAnimationFrame||t.mozRequestAnimationFrame||t.webkitRequestAnimationFrame||t.msRequestAnimationFrame||function(e){return setTimeout(e,1e3/60)},function(){var r="http://www.w3.org/2000/svg",M={centerX:50,centerY:50},k={dialRadius:40,dialStartAngle:135,dialEndAngle:45,value:0,max:100,min:0,valueDialClass:"value",valueClass:"value-text",dialClass:"dial",gaugeClass:"gauge",showValue:!0,gaugeColor:null,label:function(e){return Math.round(e)}};function V(e,t,n){var a=o.createElementNS(r,e);for(var i in t)a.setAttribute(i,t[i]);return n&&n.forEach(function(e){a.appendChild(e)}),a}function R(e,t){return e*t/100}function E(e,t,n){var a=Number(e);return n<a?n:a<t?t:a}function q(e,t,n,a){var i=a*Math.PI/180;return{x:Math.round(1e3*(e+n*Math.cos(i)))/1e3,y:Math.round(1e3*(t+n*Math.sin(i)))/1e3}}return function(e,r){r=function(){var n=arguments[0];return F.call(arguments,1).forEach(function(e){for(var t in e)e.hasOwnProperty(t)&&(n[t]=e[t])}),n}({},k,r);var o,l,t,n=e,s=r.max,u=r.min,a=E(r.value,u,s),c=r.dialRadius,d=r.showValue,f=r.dialStartAngle,v=r.dialEndAngle,i=r.valueDialClass,m=r.valueClass,g=(r.valueLabelClass,r.dialClass),h=r.gaugeClass,p=r.color,w=r.label,x=r.viewBox;if(f<v){console.log("WARN! startAngle < endAngle, Swapping");var A=f;f=v,v=A}function y(e,t,n,a){var i=function(e,t,n){var a=M.centerX,i=M.centerY;return{end:q(a,i,e,n),start:q(a,i,e,t)}}(e,t,n),r=i.start,o=i.end,l=void 0===a?1:a;return["M",r.x,r.y,"A",e,e,0,l,1,o.x,o.y].join(" ")}function b(e,t){var n=function(e,t,n){return 100*(e-t)/(n-t)}(e,u,s),a=R(n,360-Math.abs(f-v)),i=a<=180?0:1;d&&(o.textContent=w.call(r,e)),l.setAttribute("d",y(c,f,a+f,i))}function C(e,t){var n=p.call(r,e),a=1e3*t,i="stroke "+a+"ms ease";l.style.stroke=n,l.style["-webkit-transition"]=i,l.style["-moz-transition"]=i,l.style.transition=i}return t={setMaxValue:function(e){s=e},setValue:function(e){a=E(e,u,s),p&&C(a,0),b(a)},setValueAnimated:function(e,t){var n=a;a=E(e,u,s),n!==a&&(p&&C(a,t),function(e){var t=e.duration,a=1,i=60*t,r=e.start||0,o=e.end-r,l=e.step,s=e.easing||function(e){return(e/=.5)<1?.5*Math.pow(e,3):.5*(Math.pow(e-2,3)+2)};S(function e(){var t=a/i,n=o*s(t)+r;l(n,a),a+=1,t<1&&S(e)})}({start:n||0,end:a,duration:t||1,step:function(e,t){b(e,t)}}))},getValue:function(){return a}},function(e){o=V("text",{x:50,y:50,fill:"#999",class:m,"font-size":"100%","font-family":"sans-serif","font-weight":"normal","text-anchor":"middle","alignment-baseline":"middle","dominant-baseline":"central"}),l=V("path",{class:i,fill:"none",stroke:"#666","stroke-width":2.5,d:y(c,f,f)});var t=R(100,360-Math.abs(f-v)),n=V("svg",{viewBox:x||"0 0 100 100",class:h},[V("path",{class:g,fill:"none",stroke:"#eee","stroke-width":2,d:y(c,f,v,t<=180?0:1)}),V("g",{class:"text-container"},[o]),l]);e.appendChild(n)}(n),t.setValue(a),t}}());"function"==typeof define&&define.amd?define(function(){return n}):"object"==typeof module&&module.exports?module.exports=n:e.Gauge=n}("undefined"==typeof window?this:window);
// FIM FUNÇAO GAUGE

var gauge2 = Gauge(
  document.getElementById("gauge2"), {
    min: -2,
    max: 30,
    dialStartAngle: 130,
    dialEndAngle: 50,
    value: 50,
    color: function(value) {
      if (value < 8) {
        return "#5ee432";
      } else if (value < 12) {
        return "#fffa50";
      } else if (value < 20) {
        return "#f7aa38";
      } else {
        return "#ef4655";
      }
    },
    label: function(value) {
      return value.toFixed(2) + " ºC"; // Adiciona a unidade de graus Celsius ao texto
    }
  }
);

let ws; // Variável para armazenar a conexão WebSocket

// Função para conectar ao servidor via WebSocket
function connectWebSocket() {
  ws = new WebSocket('ws://192.168.68.107/ws');

  // Evento disparado quando a conexão é aberta
  ws.onopen = function(event) {
    console.log('Conexão WebSocket estabelecida.');
  };

  // Evento disparado quando a conexão é fechada
  ws.onclose = function(event) {
    console.log('Conexão WebSocket fechada.');
  };

  // Evento disparado quando uma mensagem é recebida do servidor
  ws.onmessage = function(event) {
    console.log('Mensagem recebida:', event.data);
    let data = JSON.parse(event.data);

    // Verifica se o campo "sensor" existe no JSON
    if ("sensor" in data) {
      let sensorValue = parseFloat(data.sensor);

      // Atualiza o valor do Gauge com o valor numérico
      gauge2.setValueAnimated(sensorValue);
    } else {
      console.error('Campo "sensor" não encontrado no JSON:', event.data);
    }
  };

  // Evento disparado em caso de erro na conexão WebSocket
  ws.onerror = function(event) {
    console.error('Erro na conexão WebSocket:', event);
  };
}

// Função para desconectar do servidor via WebSocket
function disconnectWebSocket() {
  if (ws) {
    ws.close();
  }
}

// Conectar ao WebSocket quando a página é carregada
window.addEventListener('load', function() {
  connectWebSocket();
});

// Reconectar ao WebSocket em caso de falha na conexão
function reconnectWebSocket() {
  setTimeout(function() {
    console.log('Tentando reconectar...');
    connectWebSocket();
  }, 5000); // Tentar reconectar após 5 segundos
}

// Reconectar automaticamente em caso de falha na conexão
ws.addEventListener('close', function() {
  reconnectWebSocket();
});

    // Função para iniciar o controle de temperatura
    function startTemperatureControl(event) {
      event.preventDefault();
      var xhr = new XMLHttpRequest();
      xhr.open('GET', '/start', true);
      xhr.send();
    }

 // Função para atualizar os valores dinâmicos (temperatura e Gauge 3)
  setInterval(function () {
    var currentTemp = document.getElementById('current-temp');
    var targetTemp = document.getElementById('target-temp');
    var formattedElapsedTime = document.getElementById('remaining-time');
    var formattedtargetTime = document.getElementById('formattedtargetTime');

    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4 && xhr.status === 200) {
        var data = JSON.parse(xhr.responseText);
			targetTemp.innerText = data.targetTemperature.toFixed(2);
			formattedElapsedTime.innerText = data.formattedElapsedTime;
			formattedtargetTime.innerText = data.formattedtargetTime;

      }
    };
    xhr.open('GET', '/temperatureData', true);
    xhr.send();
  }, 1000);

Glad you solved it

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.