Timestamp firebase in python - argument in firebase.put() - python

Im new to python and trying to insert the date/time into my firebase.put Im unsure of what this should be and would appreciate some help. Ive tried this, strip() and a couple other unsuccessful things. Please help! Thank you
from firebase import firebase
import time
import datetime
whattime = datetime.datetime.now()
firebase = firebase.FirebaseApplication('my_firebase_link',None)
result = firebase.put('/user',str(whattime),'testing')

There are 2 approaches for timestamps in Firebase, the local machine one and Firebase's own timestamp, the following examples demonstrate each one.
Both examples will require to import the following modules:
import urllib.request
import urllib.error
import json
import time #For the first example only
In this example we use the built in time module from Python (the datetime module works the same). The value from time.time() will be stored as a float and you should convert it back into a date object when you read it back from Firebase.
def send_message(message, username):
my_data = dict()
my_data["message"] = message
my_data["username"] = username
my_data["timestamp"] = time.time()
json_data = json.dumps(my_data).encode()
try:
loader = urllib.request.urlopen("https://<YOUR-PROJECT-ID>.firebaseio.com/messages.json", data=json_data)
except urllib.error.URLError as e:
message = json.loads(e.read())
print(message["error"])
else:
print(loader.read())
This example will use Firebase internal timestamp. The value {".sv": "timestamp"} is interpreted by Firebase and it's converted into a timestamp when the request is processed.
def send_message(message, username):
my_data = dict()
my_data["message"] = message
my_data["username"] = username
my_data["timestamp"] = {".sv": "timestamp"}
json_data = json.dumps(my_data).encode()
try:
loader = urllib.request.urlopen("https://<YOUR-PROJECT-ID>.firebaseio.com/messages.json", data=json_data)
except urllib.error.URLError as e:
message = json.loads(e.read())
print(message["error"])
else:
print(loader.read())

This code solved the problem for me:
import firebase_admin
from firebase_admin import credentials
cred = credentials.Certificate("/home/pi/Documents/gpioZero/iot-maison-firebase- adminsdk-a0c7t-666fdeb9bd.json")
firebase_admin.initialize_app(cred)
db = firestore.client()
pir = MotionSensor(4)
led = LED(16)
def motionOn():
doc_ref = db.collection(u'motion').document(u'test1')
dateNow = datetime.datetime.now()
doc_ref.set({u'started': True,u'date': dateNow })
led.on()
print("On")
pir.when_activated=motionOn

Related

python JSON format invalid

I'm trying to get date and time flowing into Azure IoT hub to enable me to analyze using Azure DX as time series. I can get the temperature and humidity (humidity at the moment is just a random number). If I use this code, all works well and the JSON is well formatted and flows into IoT hub and onto Azure DX:
The basis for the code is taken from the Microsoft examples here - https://github.com/Azure-Samples/azure-iot-samples-python/blob/master/iot-hub/Quickstarts/simulated-device/SimulatedDeviceSync.py
import asyncio
import random
from azure.iot.device import Message
from azure.iot.device.aio import IoTHubDeviceClient
import time
from datetime import datetime
from w1thermsensor import W1ThermSensor
sensor = W1ThermSensor()
import json
CONNECTION_STRING = "xxxxx"
HUMIDITY = 60
MSG_TXT = '{{"temperature": {temperature},"humidity": {humidity}}}'
async def main():
try:
# Create instance of the device client
client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING)
print("Simulated device started. Press Ctrl-C to exit")
while True:
humidity = round(HUMIDITY + (random.random() * 20), 2)
temperature = sensor.get_temperature()
msg_txt_formatted = MSG_TXT.format(temperature=temperature, humidity=humidity)
message = Message(msg_txt_formatted)
# Send a message to the IoT hub
print(f"Sending message: {message}")
await client.send_message(message)
await asyncio.sleep(1)
except KeyboardInterrupt:
print("Simulated device stopped")
if __name__ == '__main__':
asyncio.run(main())
The JSON format is valid and works well -
{ "temperature": 7, "humidity": 66.09 }
If I try to add a date/time field like this:
import asyncio
import random
from azure.iot.device import Message
from azure.iot.device.aio import IoTHubDeviceClient
import time
from datetime import datetime
from w1thermsensor import W1ThermSensor
sensor = W1ThermSensor()
import json
CONNECTION_STRING = "xxxxx"
HUMIDITY = 60
x = datetime.now()
timesent = str(x)
MSG_TXT = '{{"temperature": {temperature},"humidity": {humidity},"timesent": {timesent}}}'
async def main():
try:
# Create instance of the device client
client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING)
print("Simulated device started. Press Ctrl-C to exit")
while True:
humidity = round(HUMIDITY + (random.random() * 20), 2)
temperature = sensor.get_temperature()
msg_txt_formatted = MSG_TXT.format(temperature=temperature, humidity=humidity, timesent=timesent)
message = Message(msg_txt_formatted)
# Send a message to the IoT hub
print(f"Sending message: {message}")
await client.send_message(message)
await asyncio.sleep(1)
except KeyboardInterrupt:
print("Simulated device stopped")
if __name__ == '__main__':
asyncio.run(main())
The output from the JSON is no longer valid and Azure DX will not map. The invalid JSON I get is:
"{\"temperature\": 7,\"humidity\": 72.88, \"timesent\": 2022-11-08 14:21:04.021812}"
I suspect this is something to do with the date/time being formatted as a string, but I'm totally lost.
Would anyone have any ideas how I can send this data?
#JoeHo, thank you for pointing the sources that helped you resolve the issue. I am posting the solution here so that other community members facing similar issue would benefit. Making the below modifications to the code helped me resolve the issue.
def json_serial(obj):
if isinstance(obj, (datetime, date)):
return obj.isoformat()
raise TypeError ("Type %s not serializable" % type(obj))
x = datetime.now().isoformat();
timesent = dumps(datetime.now(), default=json_serial);
MSG_TXT = '{{"temperature": {temperature},"humidity": {humidity}, "timesent": {timesent}}}'
My table on the Azure data explorer has the following filed definitions defined.
.create table jsondata (temperature: real, humidity: real, timesent: datetime)
My data mapping query is as below
.create table jsondata ingestion json mapping 'jsonMapping' '[{"column":"humidity","path":"$.humidity","datatype":"real"},{"column":"temperature","path":"$.temperature","datatype":"real"}, {"column":"timesent","path":"$.timesent","datatype":"datetime"}]'
I then connected the Azure Data Explorer table to IoT Hub using the steps outlined in the following resource Connect Azure Data Explorer table to IoT hub
When I execute the program, I could see the Azure IoT Hub telemetry data flow getting bound to the Azure Data explorer table without any issues.

Azure tranlation api don't deliver results while handover data from arangoDB

I struggle a little with getting an return on my azure translation api call.
My code is based on this code https://github.com/MicrosoftTranslator/PythonConsole and it work perfectly.
I furthermore have a arangoDB with some test data. Which does it work and give me this:Result on db test
However, if i combine both as follow:
from xml.etree import ElementTree
from auth import AzureAuthClient
from arango import ArangoClient
import requests
client = ArangoClient(
protocol='http',
host='localhost',
port=32768,
username='root',
password='password',
enable_logging=True
)
db = client.database('testdb')
test = db.collection('testcol')
def GetTextAndTranslate(finalToken):
fromLangCode = "en"
toLangCode = "de"
textToTranslate = " "
for t in test:
#text to translate
textToTranslate = t['name']
# Call to Microsoft Translator Service
headers = {"Authorization ": finalToken}
translateUrl = "http://api.microsofttranslator.com/v2/Http.svc/Translate?text={}&to={}".format(textToTranslate, toLangCode)
translationData = requests.get(translateUrl, headers = headers)
# parse xml return values
translation = ElementTree.fromstring(translationData.text.encode('utf-8'))
# display translation if needed
print (translation.text)
if __name__ == "__main__":
#Add your client secret in the next line
client_secret = 'azurepassword'
auth_client = AzureAuthClient(client_secret)
bearer_token = 'Bearer ' + auth_client.get_access_token()
I just get nothing. The console needs less then a second and then I can enter new command on the terminal. But no result displayed, also tried to put it into a file. Azure tell me that I called the API, but I can't see what was processed there.
Thanks for your help!
I tried to test your code for calling Azure Translator API, but I discovered the translator part of your code works fine and the Arango part also works fine. Under your code is not complete for me, the only issue I guess is that the function GetTextAndTranslate(finalToken) shoud be defined as GetTextAndTranslate(test, finalToken) which can be passed the argument test collection like below.
def GetTextAndTranslate(test, finalToken):
# Your code
........
if __name__ == "__main__":
client = ArangoClient(
protocol='http',
host='localhost',
port=32768,
username='root',
password='password',
enable_logging=True
)
db = client.database('testdb')
test = db.collection('testcol')
#Add your client secret in the next line
client_secret = 'azurepassword'
auth_client = AzureAuthClient(client_secret)
bearer_token = 'Bearer ' + auth_client.get_access_token()
GetTextAndTranslate(test, bearer_token)
Hope it helps. Any update, please feel free to let me know.

insert timestamp to json response in python

I am trying to insert timestamp to the json curl get request and publish to pubnub and failing to serialize to right format
#!/usr/bin/python
import requests
import json
import sys
import datetime
from pubnub import Pubnub
now = datetime.datetime.now()
pubnub = Pubnub(
publish_key = "key",
subscribe_key = "my_key")
channel = "my_channel"
payload = {'Postman-Token': 'sometoken', 'title': "pythontest"}
message = requests.get("http://localhost:8080/", data=json.dumps(payload))
print.message.text gives {"code":"200","message":"Success","itemCount":0,"items":[]}
I would like to add time stamp to the above message and would like the result to be like this: {"code":"200","message":"Success",date:"2016-07-31 15:26"}
print now.strftime("%Y-%m-%d %H:%M")
timestamp=str(now.strftime("%Y-%m-%d %H:%M"))
print message.text,now.strftime("%Y-%m-%d %H:%M")
Hello = str(message.text)
pubnub.publish(
channel = channel,
message = (Hello,timestamp))
But, when I publish it to pubnub, the result looks like this.
[u'{"code":"200","message":"Success","itemCount":0,"items":[]}', u'2016-07-31 15:26']
Please help
You get this result because you are sending a tuple containing a dictionary and the timestamp, so obviously it will return the tuple as the response. Try to inserting the timestamp in the message you will send.
See if the below works:
message = json.loads(requests.get("http://localhost:8080/", data=json.dumps(payload)))
message["date"] = timestamp
It seems to fit for what you want.

How to log into a file for a python & bottle web server?

Following is my code for server. I need to add logging to it . This is a very basic rest api server. I have deployed it on Amazon EC2 . Sometimes due to errors or some other reason the http server shuts down. If I am logged on to EC2 i can see the erros while they happen . But if I am not monitoring it realtime i don't know what error occurred. Therefore I want to add logging which would log the erros in a log file which I can look at later. Please suggest how do i do that.
import json
import uuid # this is for generating unique id
import datetime
import bottle
from bottle import route, run, request, abort
from pymongo import Connection
connection = Connection('localhost', 27017)
db = connection.mydatabase
#route('/documents', method='PUT')
def put_document():
data = request.body.readline()
if not data:
abort(400, 'No data received')
entity = json.loads(data)
if not entity.has_key('_id'):
abort(400, 'No _id specified')
try:
db['documents'].save(entity)
except ValidationError as ve:
abort(400, str(ve))
#route('/documents/:id', method='GET')
def get_document(id):
entity = db['documents'].find_one({'_id':id})
if not entity:
abort(404, 'No document with id %s' % id)
return entity
#route('/startSession', method = 'GET')
def startSession():
#here we need to create a unique id and store it in the database.
date = str(datetime.datetime.utcnow());
id = str(uuid.uuid4())
reply = {'date' : date,
'user_id': id
}
response = {'date' : date,
'user_id': id
}
return_id = db['users'].save(reply)
#print 'the id returned is', return_id
#print 'the changed reply is',reply
#print 'the NON changed respponse is ',response
return json.dumps(response)
#route('/set_bus_location', method = 'PUT')
def set_bus_location():
data = request.body.readline()
print 'data is ',data
if not data:
abort(400, 'No data received')
entity = json.loads(data)
db['bus_locations'].save(entity)
run(host='0.0.0.0', port=8080)
Use the python Logging library. To log exceptions, you'll need to use try and except blocks.
import logging
logging.basicConfig(filename='log.txt', format=logging.BASIC_FORMAT)
logging.error('OH NO!')
try:
raise Exception('Foo')
except:
logging.exception("Oops:")
Contents of log.txt:
ERROR:root:OH NO!
You can add many different loggers that go to different places, have different names, or use different formats. However, the Python logging library is what you want.

Displaying stackOverflow API JSON data using Flask

I've been trying to display my username and reputation from the JSON data retrieved from the StackOverflow API.
Im using the python module Requests to retrieve the data.
Here is the code
from flask import Flask,jsonify
import requests
import simplejson
import json
app = Flask(__name__)
#app.route("/")
def home():
uri = "https://api.stackexchange.com/2.0/users? order=desc&sort=reputation&inname=fuchida&site=stackoverflow"
try:
uResponse = requests.get(uri)
except requests.ConnectionError:
return "Connection Error"
Jresponse = uResponse.text
return Jresponse
if __name__ == "__main__":
app.run(debug = True)
The unused imports is what I need to get this done but cant seem to know how to get it done.
Below is what is returned to the browser, I want to just display the username [display_name] and the reputation. what options do I have to get this done ?
{"items":[{"user_id":540028,"user_type":"registered","creation_date":1292207782,"display_name":"Fuchida","profile_image":"http://www.gravatar.com/avatar/6842025a595825e2de75dfc3058f0bee?d=identicon&r=PG","reputation":13,"reputation_change_day":0,"reputation_change_week":0,"reputation_change_month":0,"reputation_change_quarter":0,"reputation_change_year":0,"age":24,"last_access_date":1332905685,"last_modified_date":1332302766,"is_employee":false,"link":"http://stackoverflow.com/users/540028/fuchida","website_url":"http://blog.Fuchida.me","location":"Minneapolis
MN","account_id":258084,"badge_counts":{"gold":0,"silver":0,"bronze":3}}],"quota_remaining":282,"quota_max":300,"has_more":false}
Use json.loads() to read and decode the data.
from flask import Flask,jsonify
import requests
import simplejson
import json
app = Flask(__name__)
#app.route("/")
def home():
uri = "https://api.stackexchange.com/2.0/users? order=desc&sort=reputation&inname=fuchida&site=stackoverflow"
try:
uResponse = requests.get(uri)
except requests.ConnectionError:
return "Connection Error"
Jresponse = uResponse.text
data = json.loads(Jresponse)
displayName = data['items'][0]['display_name']# <-- The display name
reputation = data['items'][0]['reputation']# <-- The reputation
return Jresponse
if __name__ == "__main__":
app.run(debug = True)

Categories

Resources