Display Temperature Node-Red Raspberry Pi Sensehat Using Exec Node - raspberry-pi

I am trying to display the current temperature every 5 seconds from a raspberry pi sensehat using the exec node with the function 'vcgencmd measure_temp'.
I want the output to display as {d: temp: 50} and display as a graph on the Watson IoT output node.
My current flow is shown in the photo attached below and my current code in the function node is as follows:
msg.payload = {'d' : {'temp' : msg.payload}};
return msg;
It is currently returning
{ d: object }
Any ideas? I have tried with a JSON node and it has not worked.

You basically returning the object instead of a string. So as soon as you stringify your object it should be displayed correctly. Insert in the function node the following code:
msg.payload = {'d' : {'temp' : JSON.stringify(msg.payload)}}; return msg;
transform object into String:
JSON.stringify(obj);

Related

Sending String command to BLE in Ionic

im new in ionic, right now i'm trying to send a "code" in string.
which the string consist of a few packets data in HEX.
eg. V1-FC03-2ED1-FE01
V1 is the sequence, then after the first - is the first packet "FC03"
the code successfully send to my arduino using serial monitor on pc.
arduino serial monitor
now i want to send it trough BLE using ionic.
i follow the example on github on doing the BLE.
it works if send 1 or 0.
here is the function in ionic codes that going to send to arduino after button pressed
onPowerSwitchChange(event) {
console.log('onPowerSwitchChange');
let value = this.power ? 1 : 0;
let buffer = new Uint8Array([value]).buffer;
console.log('Power Switch Property ' + this.power);
this.ble.write(this.peripheral.id, LIGHTBULB_SERVICE, SWITCH_CHARACTERISTIC, buffer).then(
() => this.setStatus('Light is ' + (this.power ? 'on' : 'off')),
e => this.showAlert('Unexpected Error', 'Error updating power switch')
);
}
here i tried to change
let value = this.power ? 1 : 0;
to
let value = "V1-FC03-2ED1-FE01";
but when compile, got error
Argument of type 'string[]' is not assignable to parameter of type 'ArrayBuffer'. Property 'byteLength' is
missing in type 'string[]'.
L68: let value = "V1-FC03-2ED1-FE01";
L69: let buffer = new Uint8Array([value]).buffer;
L70: console.log('Power Switch Property ' + this.power);
hopefully someone can help me on this problem
Not sure if this will help you as I'm not a programmer by trade... but I wanted to send a "2" as string and it turned out that I had to do it like this:
var data = new Uint8Array(1);
data[0] = 50;
With 50 being the Uint8Array equivalent of 2
Currently I'm trying to read from the BLE in the opposite direction to no effect so please keep us posted as to your progress.

Can't get CoffeeScript to recognize a function in a js file

I am writing a simple app in Coffeescript to control a Philips Hue light. I have included this module into my project. The below code seems to work fine up until I try to set the color of the lights using setLightState. The compiler says the function isn't a function. I don't quite understand why it doesn't recognize the function.
# Connect with Philips Hue bridge
jsHue = require 'jshue'
hue = jsHue()
# Get the IP address of any bridges on the network
hueBridgeIPAddress = hue.discover().then((bridges) =>
if bridges.length is 0
console.log 'No bridges found. :('
else
(b.internalipaddress for b in bridges)
).catch((e) => console.log 'Error finding bridges', e)
if hueBridgeIPAddress.length isnt 0 # if there is at least 1 bridge
bridge = hue.bridge(hueBridgeIPAddress[0]) #get the first bridge in the list
# Create a user on that bridge (may need to press the reset button on the bridge before starting the tech buck)
user = bridge.createUser('myApp#testdevice').then((data) =>
username = data[0].success.username
console.log 'New username:', username
bridge.user(username)
)
if user?
#assuming a user was sucessfully created set the lighting to white
user.setLightState(1, {on:true, sat:0, bri:100, hue:65280}).then((data) =>
# process response data, do other things
)
As you can see on the github page of the jshue lib, bridge.createUser does not directly return a user object.
Instead the example code sets the user variable inside the then function of the returned promise:
bridge.createUser('myApp#testdevice').then(data => {
// extract bridge-generated username from returned data
var username = data[0].success.username;
// instantiate user object with username
var user = bridge.user(username);
user.setLightState( .... )
});
It can be expected that - using this approach - the user variable will be set correctly and user.setLightState will be defined.
A self-contained example:
Take this Codepen for example:
url = "https://api.ipify.org?format=json"
outside = axios.get(url).then (response) =>
inside = response.data.ip
console.log "inside: #{inside}"
inside
console.log "outside: #{outside}"
The console output is
outside: [object Promise]
inside: 178.19.212.102
You can see that:
the outside log is first and is a Promise object
the inside log comes last and contains the actual object from the Ajax call (in this case your IP)
the then function implicitly returning inside does not change anything

Core WLAN MCS Index?

I'm trying to recreate the information displayed for the current Wi-Fi network when option-clicking on the Wi-Fi status bar item. One of the parameters shown is the MCS Index, but I can't find any way to query this value using the CWInterface class, which is where I am getting most of the other data:
if let interface = CWWiFiClient.shared().interface() {
rssi = interface.rssiValue()
noise = interface.noiseMeasurement()
// etc.
}
Since both the Wi-Fi status bar item and the airport command line tool display the MCS Index, it seems like there should be some way to query it:
MacBook:~ mark$ /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I
agrCtlRSSI: -46
agrExtRSSI: 0
agrCtlNoise: -90
agrExtNoise: 0
state: running
op mode: station
lastTxRate: 878
maxRate: 1300
lastAssocStatus: 0
802.11 auth: open
link auth: wpa2-psk
BSSID: xx:xx:xx:xx:xx:xx
SSID: MyWiFi
MCS: 7
channel: 149,80
I've also seem some Python sample code that seems to indicate that the MCS Index should be available, but I don't see it in the docs or code completion.
Is there some way to get this value through Core WLAN or some other framework, or is this something I need to calculate based on other values?
I found another Python script wifi_status.py
which reports the WiFi status. From the lines
def wifi_status(properties=('bssid', 'channel', 'txRate', 'mcsIndex', 'rssi', 'noise')):
xface = CWWiFiClient.sharedWiFiClient().interface()
while True:
yield({name: getattr(xface, name)() for name in properties})
one can conclude that these attributes can be retrieved with
Key-Value Coding.
And that really works:
if let iface = CWWiFiClient.shared().interface() {
if let mcsIndex = iface.value(forKey: "mcsIndex") as? Int {
print(mcsIndex)
}
}
But I have now idea if that approach is officially supported,
or will work in the future, so use at your own risk.

MongoEngine not saving embedded doc second time around

When I use MongoEngine to add an embedded doc to a doc, it works the first time when the list is empty but fails with subsequent tries saying: mongoengine.errors.OperationError: Could not save document (Cannot update 'sensorlist.1.alert_list.0._cls' and 'sensorlist.1.alert_list' at the same time)
The following test code demonstrates the issue: If you run it once you will see a new collection/document in foo that has an S2 embedded Sensor with qty 2 embedded Alerts. If you run it again it blows up - Any ideas?
Thx Bill
import mongoengine as ME
ME.connect('foo')
class Sensor(ME.EmbeddedDocument):
name = ME.StringField()
alert_list = ME.ListField()
class Alert(ME.EmbeddedDocument):
name = ME.StringField(default = 'new alert')
class SiteConfig(ME.Document):
siteid = ME.StringField()
sensorlist = ME.ListField(ME.EmbeddedDocumentField(Sensor))
if not SiteConfig.objects(siteid = '123456'):
newsite = SiteConfig(siteid = '123456')
newsite.save()
print("saved new site")
site = SiteConfig.objects(siteid = '123456').first()
newsensor = Sensor(name='S1')
site.sensorlist.append(newsensor)
site.save()
print("added sensor S1")
newsensor = Sensor(name='S2')
site.sensorlist.append(newsensor)
site.save()
print("added sensor S2")
for sensor in site.sensorlist:
if sensor.name =='S2':
alert = Alert()
sensor.alert_list.append(alert)
site.save()
print('added first alert to S2')
for sensor in site.sensorlist:
if sensor.name =='S2':
alert = Alert()
sensor.alert_list.append(alert)
site.save()
print('added second alert to S1')
I solved this by reproducing the code in MongoAlchemy which is very similar. That also failed but actually gave me useful exception info that pointed me to the problem which was that my Sensor class Alert_list definition needed to specify the class it contains.
So the fix is to define Sensor like this:
class Sensor(ME.DynamicEmbeddedDocument):
name = ME.StringField()
alert_list = ME.ListField(ME.EmbeddedDocumentField(Alert))
After all that pain over such a small issue I will probably stick with MongoAlchemy!

How to initialize the model using Window.dimensions in Elm?

In a sliding puzzle game, I'd like set the initial tile size based on the initial window dimensions (to maximize the screen real estate).
In other words, I'd like to set initialModel based on the the initial value of Window.dimensions.
I couldn't find how to do this, and ended up using ports to get the initial window dimensions:
index.html
Elm.fullscreen(Elm.App, {
windowSize: [
document.documentElement.clientWidth,
document.documentElement.clientHeight
]
});
App.elm
port windowSize : (Int, Int)
initialModel =
-- some function of windowSize
model =
Signal.foldp update initialModel input
type Action
= WindowResize (Int, Int)
| ...
windowResize =
Signal.map WindowResize Window.dimensions
update action model =
case action of
WindowResize dimensions ->
{ model | some change based on dimensions }
...
Is there a way to achieve the same result without using ports?
You can use Signal.Extra.foldp' from the Apanatshka/elm-signal-extra package to inspect base the initial value of the model on the initial value of the input signal.
Full disclosure: I'm the author of that package.