Data storage, visualization and analysis of sensor values of Raspberry Pi can be easily done by utilizing kintone in the cloud. I have implemented the process for uploading data to this kintone with my own library, but I implemented the process with the kintone API SDK for Python introduced on the official website. (Data uploaded from Rasberry Pi below) As a result, I was able to easily implement the process with short code without any problems, so I decided to stop the maintenance of my own library and use the kintone API SDK for Python from now on.
__ kintone API SDK for Python __ https://developer.cybozu.io/hc/ja/articles/205382194-kintone-API-SDK-for-Python
GitHub icoxfog417/pykintone https://github.com/icoxfog417/pykintone
The main body of Raspberry Pi is 3B, and the OS is the latest one at the moment.
Raspbian Buster with desktop ・ Version: September 2019 ・ Release date: 2019-09-26 -Kernel version: 4.19
I will omit the setup method. If you want to know more, please refer to the following.
__Raspberry Pi Initial setting Windows (@ sigma7641) __ https://qiita.com/sigma7641/items/995c7bb07eab408b9d0e __Raspberry Pi Initial setting Mac (@skkojiko) __ https://qiita.com/skkojiko/items/a7e342a8ab53b409fe6a
The OS image used this time, Raspbian Buster with desktop 2019-09-26, can be used with Python2, Python3, pip, and pip3 from the beginning, so these settings are not required. You can easily install the kintone API SDK for Python with the following pip.
$ pip install pykintone
$ pip3 install pykintone
Set the fields as follows:
Field name | type | Feed coat / element ID |
---|---|---|
Date and time | Date and time | datetime |
title | Character string (1 line) | title |
Attachment | Attachment | file |
Creation date and time | Date and time (system) | Creation date and time |
From the application setting screen, the API token setting screen opens in the order of Settings-> Customize / Service Linkage API Token. When you press the "Generate" button, the API token will be added, so check all the access rights except the application management and "Save".
Prepare the following initial data.
Use the kintone API SDK for Python to implement additions and deletions, including data acquisition, addition, update, and file upload.
pykintoneTest.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import codecs
import sys
import time
import pykintone
from pykintone import model
import pykintone.structure_field as sf
#Kintone API settings (common to all processes)
subdomein = "kintone subdomain"
appId = "kintone application ID"
token = "kintone API token"
app = pykintone.app(subdomein, appId, token)
Create an instance app of pykintone.app () with the kintone subdomain, app ID, and API token. This instance is used for all processing.
pykintoneTest.py
(Omitting the description up to the setting of kintone API)
#Data acquisition
select = "Creation date and time< NOW() order by dateTime asc"
res = app.select(select)
if res.ok:
records = res.records
if len(records) < 1 :
print("0 records")
for record in records:
print(record[u"Creation date and time"]["value"] + ", " + record["dateTime"]["value"] + ", " + record["title"]["value"])
else:
print(res.error.id.encode('utf-8'))
print(res.error.message.encode('utf-8'))
print(res.error.code)
Executes the record acquisition process of the conditions specified in the instance app created in "Kintone API settings". The record acquisition condition is passed as an argument of app.select () and the processing result is received.
The arguments passed as the processing result are as follows.
argument | Contents |
---|---|
.ok | true :Processing completed normally, false:Processing error |
.records | Acquired record information (array) |
.error.id | Error ID |
.error.message | Error message |
.error.code | Error code |
When the process completes successfully, the data is stored in the .records (array).
pykintoneTest.py
(Omitting the description up to the setting of kintone API)
#Add data
class recordLayout(model.kintoneModel):
def __init__(self):
super(recordLayout, self).__init__()
self.datetime = "" #Kintone "date and time" field code
self.title = "" #Kintone "Title" field code
record = recordLayout()
record.datetime = time.strftime('%Y-%m-%dT%H:%M:%S+09:00')
record.title = u"Add test data from Raspi"
res = app.create(record)
if res.ok:
print("Record addition id=" + str(res.record_id) + " revision=" + str(res.revision))
else:
print(res.error.id.encode('utf-8'))
print(res.error.message.encode('utf-8'))
print(res.error.code)
Execute 1 record addition process with the instance app created in "Kintone API settings".
To store the record to be added, create a model of class that inherits kintoneModel of SDK. Set the field code of kintone form to the variable name in the model and set each data. Set this model as an argument of app.create () and receive the processing result.
The arguments passed as the processing result are as follows.
argument | Contents |
---|---|
.ok | true :Processing completed normally, false:Processing error |
.record_id | ID of the added record |
.revision | Revision number of the added record |
.error.id | Error ID |
.error.message | Error message |
.error.code | Error code |
When the process is completed normally, you will receive the record ID and revision number of the added record. If you want to add multiple records, pass the model array as an argument to app.batch_create ().
pykintoneTest.py
(Omitting the description up to the setting of kintone API)
#Data update
select = "Creation date and time< NOW() order by dateTime asc"
records = app.select(select).models(recordLayout)
record = records[0]
record.title = u"Update test data from Raspi"
res = app.update(record)
if res.ok:
print("Record update revision=" + str(res.revision))
else:
print(res.error.id.encode('utf-8'))
print(res.error.message.encode('utf-8'))
print(res.error.code)
Execute 1 record update process with the instance app created in "Kintone API settings".
First of all, get the corresponding record from kintone. The updated value is reflected in the corresponding field code of the acquired 1 record. Set this record as an argument of app.update () and receive the processing result.
The arguments passed as the processing result are the same as the data addition processing. If you want to update multiple records, pass a record array as an argument to app.batch_update ().
pykintoneTest.py
(Omitting the description up to the setting of kintone API)
#Add data
class recordLayout2(model.kintoneModel):
def __init__(self):
super(recordLayout2, self).__init__()
self.datetime = ""
self.title = ""
self.file = [sf.File()]
file = ["test.jpg "] #Set the path of the file to be stored in kintone in the array
record = recordLayout2()
record.datetime = time.strftime('%Y-%m-%dT%H:%M:%S+09:00')
record.title = u"Add test data from Raspi with file"
record.file = [sf.File.upload(f, app) for f in file]
res = app.create(record)
if res.ok:
print("Add record(File UP) id=" + str(res.record_id) + " revision=" + str(res.revision))
else:
print(res.error.id.encode('utf-8'))
print(res.error.message.encode('utf-8'))
print(res.error.code)
The kintone API SDK for Python makes it easy to implement adding data that involves uploading files.
Add a variable with the field code name of the attachment in the model. Initialize with sf.File () so that you can store the file upload configuration information in an additional variable.
Upload the file to kintone in advance with sf.File.upload () and set the resulting file key layout to the model variable. Others are the same as the data addition process.
pykintoneTest.py
(Omitting the description up to the setting of kintone API)
select = "Record number> \"3\""
records = app.select(select).models(recordLayout)
for record in records:
res = app.delete(record.record_id)
if res.ok:
print("Record deletion id=" + str(record.record_id))
else:
print(res.error.id.encode('utf-8'))
print(res.error.message.encode('utf-8'))
print(res.error.code)
Execute 1 record deletion process with the instance app created in "Kintone API settings".
First of all, get the corresponding record from kintone. Set record_id of this record as an argument of app.delete () and receive the processing result.
The arguments passed as the processing result are the same as the contents excluding the revision number of the data addition processing. If you want to delete multiple records, pass a record array as an argument to app.batch_delete ().
Below is the result of running pykintoneTest.py with all the code in the last "reference". -Record number 34 has been added. -The title has been updated for record number 1. -Record number 35 has been added and the attached file has been saved.
I also checked the source code of the kintone API SDK for Python, but it seems to be easy to use. It is a pity that there are few documents, so in the future I will summarize usage examples such as adding, updating, and deleting multiple records.
kintone API SDK for Python https://developer.cybozu.io/hc/ja/articles/205382194-kintone-API-SDK-for-Python
icoxfog417/pykintone https://github.com/icoxfog417/pykintone
__ [pykintone] Summary of how to operate records from Python to kintone __ https://trialanderror.jp/python-kintone-records/
__PykintoneTest.py created this time All code __
pykintoneTest.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import codecs
import sys
import time
import pykintone
from pykintone import model
import pykintone.structure_field as sf
#-------------------------------------------------
#Kintone API settings (common to all processes)
#-------------------------------------------------
subdomein = "kintone subdomain"
appId = "kintone application ID"
token = "kintone API token"
app = pykintone.app(subdomein, appId, token)
#-------------------------------------------------
#Data acquisition
#-------------------------------------------------
select = "Creation date and time< NOW() order by dateTime asc"
res = app.select(select)
if res.ok:
records = res.records
if len(records) < 1 :
print("0 records")
for record in records:
print(record[u"Creation date and time"]["value"] + ", " + record["dateTime"]["value"] + ", " + record["title"]["value"])
else:
print(res.error.id.encode('utf-8'))
print(res.error.message.encode('utf-8'))
print(res.error.code)
#-------------------------------------------------
#Add / update data
#-------------------------------------------------
#Add data
class recordLayout(model.kintoneModel):
def __init__(self):
super(recordLayout, self).__init__()
self.datetime = ""
self.title = ""
record = recordLayout()
record.datetime = time.strftime('%Y-%m-%dT%H:%M:%S+09:00')
record.title = u"Add test data from Raspi"
res = app.create(record)
if res.ok:
print("Record addition id=" + str(res.record_id) + " revision=" + str(res.revision))
else:
print(res.error.id.encode('utf-8'))
print(res.error.message.encode('utf-8'))
print(res.error.code)
#Data update
select = "Creation date and time< NOW() order by dateTime asc"
records = app.select(select).models(recordLayout)
record = records[0]
record.title = u"Update test data from Raspi"
res = app.update(record)
if res.ok:
print("Record update revision=" + str(res.revision))
else:
print(res.error.id.encode('utf-8'))
print(res.error.message.encode('utf-8'))
print(res.error.code)
#-------------------------------------------------
#Add data (upload file)
#-------------------------------------------------
class recordLayout2(model.kintoneModel):
def __init__(self):
super(recordLayout2, self).__init__()
self.datetime = ""
self.title = ""
self.file = [sf.File()]
file = ["test.jpg "]
record = recordLayout2()
record.datetime = time.strftime('%Y-%m-%dT%H:%M:%S+09:00')
record.title = u"Add test data from Raspi with file"
record.file = [sf.File.upload(f, app) for f in file]
res = app.create(record)
if res.ok:
print("Add record(File UP) id=" + str(res.record_id) + " revision=" + str(res.revision))
else:
print(res.error.id.encode('utf-8'))
print(res.error.message.encode('utf-8'))
print(res.error.code)
#-------------------------------------------------
#Delete data
#-------------------------------------------------
#select = "Record number> \"3\""
#records = app.select(select).models(recordLayout)
#for record in records:
# res = app.delete(record.record_id)
# if res.ok:
# print("Record deletion id=" + str(record.record_id))
# else:
# print(res.error.id.encode('utf-8'))
# print(res.error.message.encode('utf-8'))
# print(res.error.code)
Recommended Posts