Answered! Go to the Best Answer.
Best Answer
Fitbit Product Experts Alumni are retired members of the Fitbit Product Expert Program. Learn more
Hello,
I know very well your feeling as the weather module on Guthub is way too complex.
I've made another sample but much more simple. It works well with the simulator but it seems I can't get the GPS fix when deployed to the actual device (ionic).
Here it is
App
// Import the messaging module
import * as messaging from "messaging";
import document from "document";
// Request weather data from the companion
function fetchWeather() {
if (messaging.peerSocket.readyState === messaging.peerSocket.OPEN) {
// Send a command to the companion
messaging.peerSocket.send({
command: 'weather'
});
}
}
// Display the weather data received from the companion
function processWeatherData(data) {
console.log("The temperature is: " + data.temperature);
console.log("The location is : " + data.location);
}
// Listen for the onopen event
messaging.peerSocket.onopen = function() {
// Fetch weather when the connection opens
fetchWeather();
}
// Listen for messages from the companion
messaging.peerSocket.onmessage = function(evt) {
if (evt.data) {
processWeatherData(evt.data);
}
}
// Listen for the onerror event
messaging.peerSocket.onerror = function(err) {
// Handle any errors
console.log("Connection error: " + err.code + " - " + err.message);
}Companion
// Import the messaging module
import * as messaging from "messaging";
import { geolocation } from "geolocation";
var API_KEY = "YOUR KEY HERE";
// Fetch the weather from OpenWeather
function queryOpenWeather() {
geolocation.getCurrentPosition(locationSuccess, locationError);
function locationSuccess(position) {
var lat = position.coords.latitude;
var long = position.coords.longitude;
console.log("latitude: " + lat);
console.log("langitude: " + long);
var linkApi = "https://api.openweathermap.org/data/2.5/weather?lat=" + lat + "&lon=" + long + "&units=metric" + "&APPID=" + API_KEY;
fetch(linkApi)
.then(function (response) {
response.json()
.then(function(data) {
// We just want some data
var weather = {
temperature: data["main"]["temp"], humidity: data["main"]["humidity"], location: data["name"]
}
// Send the weather data to the device
returnWeatherData(weather);
});
})
.catch(function (err) {
console.log("Error fetching weather: " + err);
});
};
function locationError(error) {
console.log("Error: " + error.code,
"Message: " + error.message);
}
}
// Send the weather data to the device
function returnWeatherData(data) {
if (messaging.peerSocket.readyState === messaging.peerSocket.OPEN) {
// Send a command to the device
messaging.peerSocket.send(data);
} else {
console.log("Error: Connection is not open");
}
}
// Listen for messages from the device
messaging.peerSocket.onmessage = function(evt) {
if (evt.data && evt.data.command == "weather") {
// The device requested weather data
queryOpenWeather();
}
}
// Listen for the onerror event
messaging.peerSocket.onerror = function(err) {
// Handle any errors
console.log("Connection error: " + err.code + " - " + err.message);
}
Fitbit Product Experts Alumni are retired members of the Fitbit Product Expert Program. Learn more
Hello,
I know very well your feeling as the weather module on Guthub is way too complex.
I've made another sample but much more simple. It works well with the simulator but it seems I can't get the GPS fix when deployed to the actual device (ionic).
Here it is
App
// Import the messaging module
import * as messaging from "messaging";
import document from "document";
// Request weather data from the companion
function fetchWeather() {
if (messaging.peerSocket.readyState === messaging.peerSocket.OPEN) {
// Send a command to the companion
messaging.peerSocket.send({
command: 'weather'
});
}
}
// Display the weather data received from the companion
function processWeatherData(data) {
console.log("The temperature is: " + data.temperature);
console.log("The location is : " + data.location);
}
// Listen for the onopen event
messaging.peerSocket.onopen = function() {
// Fetch weather when the connection opens
fetchWeather();
}
// Listen for messages from the companion
messaging.peerSocket.onmessage = function(evt) {
if (evt.data) {
processWeatherData(evt.data);
}
}
// Listen for the onerror event
messaging.peerSocket.onerror = function(err) {
// Handle any errors
console.log("Connection error: " + err.code + " - " + err.message);
}Companion
// Import the messaging module
import * as messaging from "messaging";
import { geolocation } from "geolocation";
var API_KEY = "YOUR KEY HERE";
// Fetch the weather from OpenWeather
function queryOpenWeather() {
geolocation.getCurrentPosition(locationSuccess, locationError);
function locationSuccess(position) {
var lat = position.coords.latitude;
var long = position.coords.longitude;
console.log("latitude: " + lat);
console.log("langitude: " + long);
var linkApi = "https://api.openweathermap.org/data/2.5/weather?lat=" + lat + "&lon=" + long + "&units=metric" + "&APPID=" + API_KEY;
fetch(linkApi)
.then(function (response) {
response.json()
.then(function(data) {
// We just want some data
var weather = {
temperature: data["main"]["temp"], humidity: data["main"]["humidity"], location: data["name"]
}
// Send the weather data to the device
returnWeatherData(weather);
});
})
.catch(function (err) {
console.log("Error fetching weather: " + err);
});
};
function locationError(error) {
console.log("Error: " + error.code,
"Message: " + error.message);
}
}
// Send the weather data to the device
function returnWeatherData(data) {
if (messaging.peerSocket.readyState === messaging.peerSocket.OPEN) {
// Send a command to the device
messaging.peerSocket.send(data);
} else {
console.log("Error: Connection is not open");
}
}
// Listen for messages from the device
messaging.peerSocket.onmessage = function(evt) {
if (evt.data && evt.data.command == "weather") {
// The device requested weather data
queryOpenWeather();
}
}
// Listen for the onerror event
messaging.peerSocket.onerror = function(err) {
// Handle any errors
console.log("Connection error: " + err.code + " - " + err.message);
}
Fitbit Product Experts Alumni are retired members of the Fitbit Product Expert Program. Learn more
Last update: I was finally able to have it working on the device. Remember to give the authorization to connect to internet and location in the package.json file.
Let me know is something is not clear.
Best AnswerBrilliant, this worked a treat. have unfortunately caused a conflict and wonder whether you could help. I also have this code running in the companion
let key = "theme";
let val = localStorage.getItem(key);
if (val) {
try {
val = JSON.parse(val);
} catch(ex) {
val = null;
}
}
function sendVal(val) {
if (messaging.peerSocket.readyState === messaging.peerSocket.OPEN) {
messaging.peerSocket.send(val);
}
}
messaging.peerSocket.onopen = function() {
if (val) {
sendVal(val);
}
}
settingsStorage.onchange = function(evt) {
let data = JSON.parse(evt.newValue);
val = data["values"][0].value;
localStorage.setItem(key, JSON.stringify(val));
sendVal(val);
}and this code running in the app
const SETTINGS_FILE = "settings.json";
let settings = loadSettings();
applyTheme(settings.foreground, settings.background);
function loadSettings() {
let obj;
try {
obj = fs.readFileSync(SETTINGS_FILE, "json");
} catch(ex) {
obj = {
foreground: "#ffffff",
background: "#000000"
}
}
return obj;
}
function applyTheme(foreground, background) {
let items = document.getElementsByClassName("foreground");
items.forEach(function(item) {
item.style.fill = foreground;
});
settings.foreground = foreground;
let items = document.getElementsByClassName("background");
items.forEach(function(item) {
item.style.fill = background;
});
settings.background = background;
}
messaging.peerSocket.onmessage = function(evt) {
// console.log("device got: " + evt.data.background);
applyTheme(evt.data.foreground, evt.data.background);
}
me.onunload = () => {
fs.writeFileSync(SETTINGS_FILE, settings, "json");
}When I run the watchface, not only does the theme not change but I also get NaN on the weather. Now I assume it has to do with a conflict from both messages being sent back to the app but as I am a relative noob, so to speak, i'm not quite advanced enough to figure the conflict out. Any pointers on this would be appreciated.
Best Answer
Fitbit Product Experts Alumni are retired members of the Fitbit Product Expert Program. Learn more
First of all I'm happy my little simple code works for you. I built it just to make sure to understand what and how it does.
Second, I'm sorry but I'm now way an expert to understand what you are going to achieve and why it doesn't work. Hopefully somebody else is going to help you. Sorry again.
Best AnswerNo problem, your goes does work. I did add this at the end in the app section to force an update every 30 mins, which works for getting regular updates. I'm sure I will find the solution to the other issue
setInterval(fetchWeather, 30 * 1000 * 60);
Hey! How do you show the weather data that you fetched on the watch face?
Do you use something like :
const Temperature = document.getElementById("Temperature");
Temperature.text = (I don't know what goes in here, since I don't really understand the full fetching code... data.temperature or something like that maybe?);
Best Answer
Fitbit Product Experts Alumni are retired members of the Fitbit Product Expert Program. Learn more
Hello @innak,
I really understand how you feel as I learnt from scratch as well.
So, on your index.js file
// Get handle on text fields
let tempText = document.getElementById("tempText");
// Inside the processWeatherData block
tempText.text = "Temp: " + Math.round(data.temperature) + " °C";
Don't hesitate to ask more if you need.
I have no idea what I am doing wrong.
I used the dev.fitbit.com guides weather fetching example and then I tried your code. I am not even getting anything in the console. No temperature and no errors. Console does not log anything.
And ofcourse in this case nothing is displayed on the watch face also.
Best Answer
Fitbit Product Experts Alumni are retired members of the Fitbit Product Expert Program. Learn more
Is your json file correct? in particular internet and location permission
Yes. Package.json is correct.
Everything else works fine. Even the payment on my watch face works (which also need Internet)
Best AnswerExcellent code - works 100%
But ... it will not provide rainfall - Keeps giving an erros sayiong "3h" is not recognised
Extract from Companion :
var linkApi = "https://api.openweathermap.org/data/2.5/weather?lat=" + lat + "&lon=" + long + "&units=metric" + "&APPID=" + API_KEY;
fetch(linkApi)
.then(function (response) {
response.json()
.then(function(data) {
// We just want some data
var weather = {
temperature: data["main"]["temp"],
humidity: data["main"]["humidity"],
location: data["name"],
WindSpeed: data["wind"]["speed"],
WindDeg: data["wind"]["deg"],
Apressure: data["main"]["pressure"],
MaxTemp: data["main"]["temp_max"],
MinTemp: data["main"]["temp_min"],
MaxExpect: data["main"]["max"],
SunRise: data["sys"]["sunrise"],
SunSet: data["sys"]["sunset"],
rainfall: data["rain"]["3h"],
}
Extract from App
myWind.text= "Wind "+Math.floor(data.WindSpeed);
myHumid.text= "Humidity "+data.humidity+" %";
myRain.text= "Rainfall "+data.rainfall+" mm";
I get the Wind and Humidity - bit not the rain
I have tried setting a number of locations - London / NY / Chicago etc -making sure it is actually raining there at the time - but no joy
Any suggestions ?
Best Answer
Fitbit Product Experts Alumni are retired members of the Fitbit Product Expert Program. Learn more
@Lawson77 I've checked the API documentation at https://openweathermap.org/current and while indeed it mentions we should get rains data calling "3h" an actual call to the sample api doesn't show any rain "3h". I think therefore the API documentation is wrong.
You might want to try other weather providers.
@Giampi71I've used your code in my clock face and it works in the simulator on my computer but whenever I load it onto my watch it never loads the temp. The console logs just show it reading the latitude and longitude with no errors. On a Versa.
Best AnswerYour instruction and information is very well explained and easy to follow - many thanks.
I am finding the atmospheric pressure received from the provider very unreliable.
Is it possible to use the data from the cell phone barometer directly into code / app ?
I have a Samsung S7 - and reliable and instantaneous barometer. Would be great to use that data instead of the downloaded data
Best Answer
Fitbit Product Experts Alumni are retired members of the Fitbit Product Expert Program. Learn more
@Lawson77 It is an interesting idea but I don't think it is possible. I will try to play around.
Best AnswerMy update on this code is that it did work but not for me 😄 I tried it but as I wrote before, it did not work. So I decided to leave the code in just in case I want to try it later again. And published the clock face. And people started complaining that they are seeing weather (it was overlapping with the date, obviously I did not set css right, and did not position it because I did not see it on my watch). So I am thinking, can there be some kind of a region issue? I had no weather on my watch and other people did.
Best Answer
Fitbit Product Experts Alumni are retired members of the Fitbit Product Expert Program. Learn more
Definitely no regional lock. Could you please share the name of your app?
Thanks
Best Answer