Closed damirj79 closed 7 years ago
I'll have a proper look as soon as I can and make some notes and we can take it from there. Thanks for posting 😄
The /temperature
endpoint is the bit that does averaging. Changing TemperatureEndpoint.scala
L17 to
"measurements" := measurements.values
will send back a list of temperatures rather than a single average.
The UI should just deal with it (in theory) although you'll see multiple "hosts" shown; it's show each sensor labelled as "lounge", "garage" etc rather than "sensor-1" and "sensor-2".
The JSON will look like this
{
"measurements" : [
{
"host" : "lounge",
"seconds" : 100,
"sensors" : [
{
"celsius" : 31.1
},
{
"celsius" : 32.8
}
]
},
{
"host" : "bedroom",
"seconds" : 200,
"sensors" : [
{
"celsius" : 21.1
},
{
"celsius" : 22.8
}
]
}
]
}
rather than this
"measurements" : [
{
"host" : "lounge",
"seconds" : 100,
"sensors" : [
{
"celsius" : 31.95
}
]
},
{
"host" : "bedroom",
"seconds" : 200,
"sensors" : [
{
"celsius" : 21.950000000000003
}
]
}
]
}
So we'd need to modify the JSON to include the sensor name.
The sensor names as stored in the RRD
are based on the host name. For example, I name each Pi's hostname to reflect it's location, say lounge
or study
. Each sensor is postfixed with sensor-n
where n
is 1 to 5 (MaxSensors
).
We could encode the same number in the JSON above, something like this.
{
"measurements": [
{
"host": "lounge",
"seconds": 100,
"sensors": [
{
"name": "sensor-1",
"celsius": 31.95
}
]
}
]
}
but it might be nicer to base it on perhaps a mapping to a user friendly name? or the actual sensor ID (ie 28-xxxxxxx
)
So threading through a change in TemperatureReader
from
trait TemperatureReader {
def read: Error \/ List[Temperature]
}
to
trait TemperatureReader {
def read: Error \/ List[(String, Temperature)]
}
and then in SensorReader
, a change to reflect the filename
val toReading: SensorFile => Error \/ SensorTemperature = file => {
for {
source <- fromTryCatchNonFatal(Source.fromFile(file)).leftMap(FileError)
data <- source.getLines().toList.headOption.toRightDisjunction(UnexpectedError("Problem reading file, is it empty?"))
temperature <- Parser.parse(data)
} yield (file.getName, temperature)
}
We could then create JSON that look like this.
{
"host": "localhost",
"seconds": 1000,
"sensors": [
{
"name": "28-000005e2fdc2",
"temperature": {
"celsius": 32.1
}
},
{
"name": "28-000005eef3a4",
"temperature": {
"celsius": 32.8
}
}
]
}
Tnx, i will try to perform changes over the weekend and hope it will be showing values as intended.
Looks like i did something wrong, I receive the errors below:
[info] + Bad json when writing sensor data [error] x Get multiple sensors, averaging the temperatures [error] '{ [error] "measurements" : [ [error] { [error] "host" : "lounge", [error] "seconds" : 100, [error] "sensors" : [ [error] { [error] "celsius" : 31.1 [error] }, [error] { [error] "celsius" : 32.8 [error] } [error] ] [error] }, [error] { [error] "host" : "bedroom", [error] "seconds" : 200, [error] "sensors" : [ [error] { [error] "celsius" : 21.1 [error] }, [error] { [error] "celsius" : 22.8 [error] } [error] ] [error] } [error] ] [error] }' [error] [error] is not equal to [error] [error] '{ [error] "measurements" : [ [error] { [error] "host" : "lounge", [error] "seconds" : 100, [error] "sensors" : [ [error] { [error] "celsius" : 31.95 [error] } [error] ] [error] }, [error] { [error] "host" : "bedroom", [error] "seconds" : 200, [error] "sensors" : [ [error] { [error] "celsius" : 21.950000000000003 [error] } [error] ] [error] } [error] ] [error] }' (TemperatureEndpointTest.scala:90) [error] Actual: { [error] ..." : [ [error] { [error] ...nge", [error] ... 100, [error] ..." : [ [error] ... { [error] ...: 31.[1] [error] ... }[,] [error] ... [ {] [error] [ "celsius" : 32.8] [error] [ }] [error] ... [] [error] [}], [error] [{] [error] ... ["host"] [:] ["bedroom",] [error] ... []"[s]e[cond]s"... 2[]00[,] [error] ... ["sensors"] [:] [] [error] ... [ {] [error] [ "celsius" : 21.1] [error] [ },] [error] [ {] [error] Expected: { [error] ..." : [ [error] { [error] ...nge", [error] ... 100, [error] ..." : [ [error] ... { [error] ...: 31.[95] [error] ... }[] [error] ... [] [error] [},] [error] [{] [error] ... ["host" : "bedroom",] [error] [ "seconds" : 200], [error] ...: [] [error] ... [] [] [{] [error] ... [ ]"[c]e[lsiu]s"... 2[1.95]00[00000000003] [error] ... [] [] [}] [error] ... [] [error] [}] [error] [] [error] [}] [info]
I'm working on a patch atm that may be what you want. In the mean time, if you want me to take a look at your error above, you can fork the repo and push.
Tnx
Renaming issue to 'Display Individual Temperatures', will track the 'More Sensors' requirements in #3
The above should give you back individual temperatures (from /temperatures
) and averaged from /temperatures/average
.
The temperatures.js
and index.html
still use the averaged values so the next step is to change the UI to show individual temperatures. It'd be nice if you could switch between the two and if we render the sensor name taken directly from the JSON.
A bit like this (showing average temperature).
or this, showing individual temperatures.
0b1cd6f will display the sensor name like the above screen shot but requires you to change the url
of the ajax call to get individual temperatures rather than averages.
Change L4 of temperature.js
to temperatures
from temperatures/average
and restart the server to experiment.
Let me know your thoughts and if you have any ideas how to toggle it in the UI.
I'm also interested how we can present it in a nice way when you have a lot of sensors attached. I think it'll look a bit rubbish if the current temperatures display as a long list on the left, taller than the chart. Perhaps display them horizontally?
Maybe you are right, in case there are x number of sensors, the vertical list can be very long and not nice to look at. In this case I agree that horizontal alignment is better looking.
Regarding the averaging function, maybe it would be good to put an option to enable it and then let the user to choose from which sensor to calculate average value and display it as an average value. The other unselected sensors are displayed individually.
Merged what we have so far (#4) into Master.
Spun up another project (https://github.com/tobyweston/temperature-machine-ui) to play with a more dynamic site. The JavaScript / static HTML site in this project are a bit... 💩. The new site will let you toggle average and individual temperatures.
FYI This is what I'm thinking / have spiked over on the UI project. Comments welcome.
Marking as fixed (ccd8dd1), the new UI can switch between all sensors and averaged as above. It also updates the temperatures automatically.
Had some failing tests, if you're having problems with sbt assembly
or sbt test
, update and try again. There may be some platform specific problems with Windows however...
@damirj79 let me if it fixes your problem
Hi,
the assembly is now OK and also the service starts up correctly as it is visible in temperature-machine.log file, web page also loads, but all temperature gadgets shows Error: Network Error and image graphs for 24 hours, 7 days and 1 month shows message "image unavailble".
@damirj79 I may have been a bit eager. I'll check but it might be a port configuration thing. If youre running Chrome can you open the developer tools and see which the end points are being called for *.png etc. I'll have a look myself and report back...
It looks like the gadgets and graphs are pointing to http://localhost:11900 instead of https://hostname:11900 or http://IPaddress:11900
GET http://localhost:11900/temperature-1-days.png net::ERR_CONNECTION_REFUSED localhost:11900/temperature-7-days.png:1 GET http://localhost:11900/temperature-7-days.png net::ERR_CONNECTION_REFUSED localhost:11900/temperature-30-days.png:1 GET http://localhost:11900/temperature-30-days.png net::ERR_CONNECTION_REFUSED xhr.js:175 GET http://localhost:11900/temperature.json net::ERR_CONNECTION_REFUSED (anonymous) @ xhr.js:175 e.exports @ xhr.js:12 e.exports @ dispatchRequest.js:52 xhr.js:175 GET http://localhost:11900/temperatures/average net::ERR_CONNECTION_REFUSED (anonymous) @ xhr.js:175 e.exports @ xhr.js:12 e.exports @ dispatchRequest.js:52 xhr.js:175 GET http://localhost:11900/temperatures/average net::ERR_CONNECTION_REFUSED
If I change http://localhost:11900/temperature-1-days.png to http://raspberrypi:11900/temperature-1-days.png the graph shows up correctly.
yup, makes sense, thanks. I hardcoded the hostname (full qualifying) it to test. I need to switch it to a relative URL. Will fix up and report back...
@damirj79 ok, should be fixed (no promises!) try that it you like (93ef93a) 👍
Looks good indeed, thanks. 👍 Just one question though, Last 24 hours graph is showing 12hour format. Is there a simple way to convert it to 24 hour format?
Good stuff. I'll have a look, it's chartjs format so I'm sure they support 24h format. I'm going to tweak it a bit anyway with tool tips etc
Should be in 24h format now
Hello,
would it be possible to deal for custom development of few features:
Everything else is more or less perfect, thank you for sharing the project with DIY.
Regards, Damir