mongodb connector for business intelligence
って、mongodbをODBCぽいSQL-DBに見せかけるラッパーかな。
https://www.mongodb.com/products/bi-connector
https://docs.mongodb.com/bi-connector/master/
mongodb connector for business intelligence
って、mongodbをODBCぽいSQL-DBに見せかけるラッパーかな。
https://www.mongodb.com/products/bi-connector
https://docs.mongodb.com/bi-connector/master/
絶不調のでお蔵入りにしていたRaspberry Pi 3B+だが、捨てるには惜しいので、不安定なμSDカードをできるだけ使わない方法で安定するかどうかを検証すべく、以下を行なった。
【USB経由でSDカードを使う】
何も設定しなくても、RP3B+は標準でUSBブートするようで、上記はあっさり動いた。
上記でも以前より安定して動いたような気がする。
しかし、もう一歩進めて、下記のようにした。
【USB経由で/bootさせ、/パーティションはnfsでマウントする】
次にやるかもしれないのは、下記。
【PXEブートを使い、tftpで/bootをマウントさせ、/はnfsでマウント】
これができたら、不安定なSDから完全におさらばできる。
それらしい情報は下記にあるので、不安定さが解決しな時には試してみよう。
Raspberry Pi 3 でSDカードなしのネットワークブートをする
以上(^^;
{ key: value }
{ key: value }{ key: value }
[{ key: value }{ key: value }]
{
logfile: "/GPSlog.jsn",
buf: 2048,
ssid: "secret-SSID-home2.4",
pass: "secret-password-home",
url: "http://192.168.0.112:3000/log"
}
logfile: ログファイル名buf: 1レコードのJSON文字列用のバッファ長ssid: 接続するWiFiのSSIDpass: WiFiのパスワードurl: httpでPOSTするURL
[code]
// M5Stack ----------------------------------------------------------------
#include <M5Stack.h>
#include "M5StackUpdater.h"
// HTTP -------------------------------------------------------------------
#include <HTTPClient.h>
// JSON -------------------------------------------------------------------
#include <ArduinoJson.h>
// SD ---------------------------------------------------------------------
#include <SPI.h>
#include <SD.h>
// WiFi -------------------------------------------------------------------
#include <WiFi.h>
// CONFIG -----------------------------------------------------------------
struct Config {
char logfile[12];
int buf;
char ssid[64];
char pass[64];
char url[256];
};
Config config;
const char *cnfFileName = "/GPSlog.cnf"; //環境毎に設定
File logFile;
void loadConfiguration(const char *filename, Config &config) {
File file = SD.open(cnfFileName);
StaticJsonDocument<512> doc;
// Deserialize the JSON document
DeserializationError error = deserializeJson(doc, file);
if (error)
Serial.println(F("ERROR while reading config file. using default conf"));
// Copy values from the JsonDocument to the Config
strlcpy(config.logfile,
doc["logfile"] | "/GPSlog.jsn", //環境毎に設定
sizeof(config.logfile));
Serial.println("log file name: " + String(config.logfile));
config.buf = doc["buf"] | 1024; //環境毎に設定
Serial.println("JSON line buffer size: " + String(config.buf));
strlcpy(config.ssid,
doc["ssid"] | "SSID-open", //環境毎に設定
sizeof(config.ssid));
Serial.println("SSID: " + String(config.ssid));
strlcpy(config.pass,
doc["pass"] | "passowrd", //環境毎に設定
sizeof(config.pass));
Serial.println("pass: " + String(config.pass));
strlcpy(config.url,
doc["url"] | "http://example.com:3000/postjson", //環境毎に設定
sizeof(config.url));
Serial.println("http POST url: " + String(config.url));
// Close the file (Curiously, File's destructor doesn't close the file)
file.close();
}
// HTTP -------------------------------------------------------------------
bool dohttpPOST(String logstring)
{
bool b = false;
HTTPClient http;
http.begin(config.url);
http.addHeader("Content-Type", "application/json");
int status_code = http.POST(logstring);
Serial.printf("status_code=%d\r\n", status_code);
if (status_code == 200) {
String json_response = http.getString();
Serial.println("respose->"); Serial.println(json_response);
b = true;
}
http.end();
return b;
}
// WiFi -------------------------------------------------------------------
void connectWiFi() {
WiFi.mode(WIFI_STA); //STAモード(子機)として使用
WiFi.disconnect(); //Wi-Fi切断
WiFi.begin(config.ssid , config.pass); //環境毎に設定
while (WiFi.status() != WL_CONNECTED) {
Serial.println("trying WiFi Connection...");
delay(1000);
}
Serial.println("WiFi Connected.");
}
// Inside -----------------------------------------------------------------
void setup() {
M5.begin();
M5.Power.begin();
M5.Lcd.println("Hello!, JSON http.post");
Serial.begin(115200);
loadConfiguration(cnfFileName, config);
//SD -------------------------------------------
logFile = SD.open(String(config.logfile));
if (logFile) {
Serial.println("log file found");
} else {
Serial.println("error: opening " + String(config.logfile));
}
//WiFI -------------------------------------------
connectWiFi();
//HTTP -------------------------------------------
int pt = 0;
char readbuf[config.buf] = "";
while (logFile.available()) {
readbuf[pt] = logFile.read();
if (readbuf[pt] == 0x0A) {
readbuf[pt + 1] = 0;
String s = readbuf;
Serial.println("String length=" + String(s.length()));
Serial.println(s);
if (dohttpPOST(s)) {
Serial.println("post OK");
} else {
Serial.println("post ERROR");
}
pt = 0;
char readbuf[config.buf] = "";
delay(50);
} else {
pt++;
}
}
}
void loop() {
M5.update();
M5.Lcd.setTextSize(3);
M5.Lcd.println();
M5.Lcd.setTextColor(BLUE, WHITE);
M5.Lcd.println("log file http.POST done.");
M5.Lcd.println("A: SDUpdater");
while (1) {
if (M5.BtnA.wasReleased()) { //AボタンでSDUpdater
updateFromFS(SD);
ESP.restart();
}
delay(100);
M5.update(); // update button state
}
}
// Arranged and written by 柴田(ひ)
[/code]
{ "class": "TPV" ,"mode": 3 ,"time": "2020-07-30T06:41:13Z" ,"lat": 35.123456 ,"lon": 139.123456 ,"alt": 26.5 ,"track": 185.950000 ,"speed": 0.0 ,"ble": 15 ,"cocoa": 4 ,"temp": 27.4 ,"humidity": 70.0 ,"pressure": 1015.5 }
{ "class": "TPV" ,"mode": 3 ,"time": "2020-07-30T06:41:24Z" ,"lat": 35.123456 ,"lon": 139.123456 ,"alt": 25.2 ,"track": 185.950000 ,"speed": 0.0 ,"ble": 16 ,"cocoa": 5 ,"temp": 27.4 ,"humidity": 70.0 ,"pressure": 1015.5 }
{ "class": "TPV" ,"mode": 3 ,"time": "2020-07-30T06:41:34Z" ,"lat": 35.123456 ,"lon": 139.123456 ,"alt": 25.3 ,"track": 185.950000 ,"speed": 0.0 ,"ble": 15 ,"cocoa": 6 ,"temp": 27.4 ,"humidity": 70.0 ,"pressure": 1015.5 }
[code]
// M5Stack ----------------------------------------------------------------
#include <M5Stack.h>
#include "M5StackUpdater.h"
// BLE & Cocoa ------------------------------------------------------------
#include <BLEDevice.h>
// ENV2 -------------------------------------------------------------------
/* add library Adafruit_BMP280 & Adafruit_SHT31 from library manage */
#include <Adafruit_Sensor.h>
#include <Adafruit_SHT31.h>
#include <Wire.h> //The SHT31 uses I2C comunication.
#include <Adafruit_BMP280.h>
// GPS --------------------------------------------------------------------
#include <TinyGPS++.h>
// SD ---------------------------------------------------------------------
#include <SPI.h>
#include <SD.h>
// BLE & Cocoa ------------------------------------------------------------
int scanTime = 5;
BLEScan* pBLEScan;
const int chipSelect = 4;
bool onBeep = true;
//接触確認アプリのUUID
const char* cocoaUUID = "0000fd6f-0000-1000-8000-00805f9b34fb";
int cocoaCnt = 0; //time out in seconds
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
if (advertisedDevice.haveServiceUUID()) {
if (strncmp(advertisedDevice.getServiceUUID().toString().c_str(), cocoaUUID, 36) == 0) {
cocoaCnt++;
if (onBeep) {
M5.Speaker.beep();
delay(10);
M5.Speaker.mute();
}
M5.Lcd.setCursor(0, 110);
M5.Lcd.setTextSize(2);
M5.Lcd.setTextColor(GREEN, BLACK);
M5.Lcd.printf("%d ", cocoaCnt);
M5.Lcd.setTextSize(1);
}
}
M5.Lcd.println(advertisedDevice.toString().c_str());
M5.Lcd.setTextSize(1);
M5.Lcd.setTextColor(WHITE, BLACK);
}
};
void setupBLE() {
BLEDevice::init("");
pBLEScan = BLEDevice::getScan(); //create new scan
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
pBLEScan->setInterval(100);
pBLEScan->setWindow(99); // less or equal setInterval value
}
// ENV2 -------------------------------------------------------------------
Adafruit_SHT31 sht31 = Adafruit_SHT31();
Adafruit_BMP280 bme;
bool hasSHT31 = false;
bool hasBMP280 = false;
float tmp = 100;
float hum = 0;
float pressure = 0;
void setupENV2() {
//ENV2 sensor on I2C setup
Wire.begin();
Serial.println(F("ENV.2 Chk"));
if (sht31.begin(0x44)) { // Set to 0x45 for alternate i2c addr
hasSHT31 = true;
Serial.println("SHT31 Ok");
Serial.print("Heater: ");
if (sht31.isHeaterEnabled())
Serial.println("Ena");
else
Serial.println("Dis");
}
if (bme.begin(0x76)) {
hasBMP280 = true;
Serial.println("BMP280 Ok");
}
}
// GPS --------------------------------------------------------------------
//bool hasRTC = false;
bool hasGPS = false;
TinyGPSPlus gps; // The TinyGPS++ object
HardwareSerial hsGps(2);// The serial connection to the GPS device
static const uint32_t GPSBaud = 9600;
void setupGPS() {
hsGps.begin(GPSBaud);
delay(500);
if (hsGps.available() > 0) {
hasGPS = true;
Serial.println("GPS Ok");
}
}
// SD ---------------------------------------------------------------------
// log file name
const char* logfile = "/GPSlog.jsn";
// Inside -----------------------------------------------------------------
unsigned char bright = 0x03;
unsigned char brightPitch = 0x10;
//文字列
const char* logJSON = "{ \"class\": \"TPV\" ,\
\"mode\": 3 ,\
\"time\": \"%d-%02d-%02dT%02d:%02d:%02dZ\" ,\
\"lat\": %lf ,\
\"lon\": %lf ,\
\"alt\": %.1f ,\
\"track\": %lf ,\
\"speed\": %.1f ,\
\"ble\": %d ,\
\"cocoa\": %d ,\
\"temp\": %.1f ,\
\"humidity\": %.1f ,\
\"pressure\": %.1f }";
// ------------------------------------------------------------------------
void setup() {
// Initialize the M5Stack
M5.begin();
M5.Power.begin();
M5.Lcd.setBrightness(bright);
M5.Lcd.setTextSize(1);
M5.Lcd.println("Hello!, COCOA Scan");
Serial.begin(115200);
setupBLE();
setupENV2();
setupGPS();
if (digitalRead(BUTTON_A_PIN) == 0) {
Serial.println("Will Load menu binary");
updateFromFS(SD);
ESP.restart();
}
}
void loop() {
// print all found BLE devices
M5.Lcd.setTextSize(1);
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
// print counts of BLE devices
int sumdev = foundDevices.getCount();
// print env2 data
if (hasSHT31) {
tmp = sht31.readTemperature();
hum = sht31.readHumidity();
}
if (hasBMP280) {
pressure = bme.readPressure() / 100;
// hPa = Pa / 100;
}
while (hsGps.available() > 0) {
gps.encode(hsGps.read());
}
Serial.printf(logJSON, gps.date.year(), gps.date.month(), gps.date.day(),
gps.time.hour(), gps.time.minute(), gps.time.second(),
gps.location.lat(), gps.location.lng(), gps.altitude.meters(), gps.course.deg(),
gps.speed.mps(), sumdev, cocoaCnt, tmp, hum, pressure);
Serial.println();
// SDカードへの書き込み処理(ファイル追加モード)
// SD.beginはM5.begin内で処理されているので不要
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dfile = SD.open(logfile, FILE_APPEND);
// if the file is available, write to it:
if (dfile) {
dfile.printf(logJSON, gps.date.year(), gps.date.month(), gps.date.day(),
gps.time.hour(), gps.time.minute(), gps.time.second(),
gps.location.lat(), gps.location.lng(), gps.altitude.meters(), gps.course.deg(),
gps.speed.mps(), sumdev, cocoaCnt, tmp, hum, pressure);
dfile.println();
}
// clear screen and set cursor to the top
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setCursor(0, 0);
M5.Lcd.setTextSize(2);
M5.Lcd.setTextColor(WHITE, BLACK);
M5.Lcd.printf(logJSON, gps.date.year(), gps.date.month(), gps.date.day(),
gps.time.hour(), gps.time.minute(), gps.time.second(),
gps.location.lat(), gps.location.lng(), gps.altitude.meters(), gps.course.deg(),
gps.speed.mps(), sumdev, cocoaCnt, tmp, hum, pressure);
M5.Lcd.println();
//Button controll
M5.Lcd.setTextSize(3);
M5.Lcd.println();
M5.Lcd.setTextColor(BLUE, WHITE);
M5.Lcd.println("A: SDUpdater");
M5.Lcd.println("B: Beep on/off");
M5.Lcd.println("C: Brightness");
int timer = 100;
while (timer--) {
if (M5.BtnA.wasReleased()) { //AボタンでSDUpdater
updateFromFS(SD);
ESP.restart();
} else if (M5.BtnB.wasReleased()) { //Bボタンでbeepをon/off切り替える
onBeep = !onBeep;
} else if (M5.BtnC.wasReleased()) { //Cボタンで輝度を変更
bright += brightPitch;
M5.Lcd.setBrightness(bright);
}
delay(50);
M5.update(); // update button state
}
//init for next loop
dfile.close();
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
cocoaCnt = 0;
M5.Lcd.setTextColor(WHITE, BLACK);
M5.Lcd.setCursor(0, 110);
M5.Lcd.setTextSize(1);
}
// Arranged and written by 柴田(ひ)
/* BLE
Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp
Ported to Arduino ESP32 by Evandro Copercini
*/
/* Cocoa
Thanks to https://gist.github.com/ksasao/0da6437d3eac9b2dbd675b6fee5d1117
by https://gist.github.com/ksasao
*/
/* GPS
This sample sketch demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object.
by Mikal Hart
*/
/* SD
SD card wrie routine
https://raspberrypi.mongonta.com/howto-write-csv-to-sdcard-on-m5stack/
*/
[/code]
const express = require('express');
const app = express();const mongoose = require('mongoose');
const userRouter = require('./routes/user');
app.use('/user', userRouter);
//app.use(express.json());
const port = 3000;
const options = {
useUnifiedTopology : true,
useNewUrlParser : true
}
mongoose.connect('mongodb://127.0.0.1/test_db',options);
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', () => console.log('Database connection successful'));
app.get('/', (req, res) =>
res.sendFile('/var/www/node/express_mongodb/test.html'))
app.listen(port,
() => console.log(`Example app listening on port ${port}!`));
const mongoose = require('mongoose');
const UserSchema = mongoose.Schema({
name: String,
age: Number
});
module.exports = mongoose.model('User',UserSchema);
M5StackのサンプルコードがENV. IIではなく、旧版のENVのものしかなく、
センサーの種類が違ったので、ちょいと手間取った。
/*
note: need add library Adafruit_BMP280 & Adafruit_SHT31 from library manage
*/
#include <M5Stack.h>
#include <Adafruit_SHT31.h>
#include <Wire.h> //The SHT31 uses I2C comunication.
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
Adafruit_SHT31 sht31 = Adafruit_SHT31();
//DHT12 dht12; //Preset scale CELSIUS and ID 0x5c.
Adafruit_BMP280 bme;
void setup() {
M5.begin();
M5.Power.begin();
Wire.begin();
M5.Lcd.setBrightness(10);
Serial.println(F("ENV2 Unit(SHT12 and BMP280) test..."));
if (! sht31.begin(0x44)) { // Set to 0x45 for alternate i2c addr
Serial.println("Couldn't find SHT31");
while (1) delay(1);
}
Serial.print("Heater Enabled State: ");
if (sht31.isHeaterEnabled())
Serial.println("ENABLED");
else
Serial.println("DISABLED");
if (! bme.begin(0x76)) {
Serial.println("Could not find a valid BMP280 sensor, check wiring!");
M5.Lcd.println("Could not find a valid BMP280 sensor, check wiring!");
while (1) delay(1);
}
M5.Lcd.clear(BLACK);
M5.Lcd.println("ENV Unit test...");
}
void loop() {
float tmp = sht31.readTemperature();
float hum = sht31.readHumidity();
float pressure = bme.readPressure() /100 ;
Serial.printf("Temperatura: %2.2f*C Humedad: %0.2f%% Pressure: %0.2fhPa\r\n", tmp, hum, pressure);
M5.Lcd.setCursor(0, 0);
M5.Lcd.setTextColor(WHITE, BLACK);
M5.Lcd.setTextSize(3);
M5.Lcd.printf("Temp: %2.1fC \r\nHumi: %2.0f%% \r\nPressure:%2.0fhPa\r\n", tmp, hum, pressure);
delay(1000);
}
RadioSHARK (app works but gets no sound from device).
Workaround: Use Audio Hijack 3.1.1 to round sound from RadioSHARK input to Line Out
PostTweet: Twitterへの投稿に失敗しました。(twitterから応答を得られません。(utf8 "\xA5" does not map to Unicode at /usr/lib/perl/5.10/Encode.pm line 162. ) )
<mt:setvar name="title_len" value="140" />
<mt:setvarblock name="title"><mtencodetext to="utf8"><mt:entrytitle remove_html="1" /></mtencodetext></mt:setvarblock>
<mt:setvarblock name="link"> - <mt:entryshortenedpermalink /></mt:setvarblock>
<mt:setvarblock name="link_len"><mt:var name="link" count_characters="1" /></mt:setvarblock>
<mt:setvar name="title_len" op="-" value="$link_len" />
<mt:var name="title" trim_to="$title_len" /><mt:var name="link" />