2023,江端さんの技術メモ

moove=# select place from records where id = 2; place ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- [{"lat": 34.7325, "lng": 135.4986}, {"lat": 34.7326, "lng": 135.4989}, {"lat": 34.7326, "lng": 135.4989}, {"lat": 34.7327, "lng": 135.4995}, {"lat": 34.7327, "lng": 135.5}, {"lat": 34.7328, "lng": 135.5002}, {"lat": 34.733, "lng": 135.5006}, {"lat": 34.7331, "lng": 135.501}, {"lat": 34.7334, "lng": 135.5015}, {"lat": 34.7336, "lng": 135.5018}, {"lat": 34.7336, "lng": 135.5018}, {"lat": 34.7336, "lng": 135.5019}, {"lat": 34.7337, "lng": 135.5021}, {"lat": 34.734, "lng": 135.5024}, {"lat": 34.7343, "lng": 135.5026}, {"lat": 34.7346, "lng": 135.5024}, {"lat": 34.7347, "lng": 135.5024}, {"lat": 34.7346, "lng": 135.5024}, {"lat": 34.7345, "lng": 135.5025}, {"lat": 34.7343, "lng": 135.5027}, {"lat": 34.7343, "lng": 135.5029}, {"lat": 34.7342, "lng": 135.5031}, {"lat": 34.7344, "lng": 135.5035}, {"lat": 34.7344, "lng": 135.5035}, {"lat": 34.7344, "lng": 135.5035}] (1 row) で登場する、最初の{"lat": 34.7325, "lng": 135.4986}と、最後の {"lat": 34.7344, "lng": 135.5035}だけを取り出すSQL文を書いて下さい

ただし、placeは、以下の通り、jsonb形式です。

moove=# \d records;
Table "public.records"
Column | Type | Collation | Nullable | Default
-----------------+-----------------------------+-----------+----------+-------------------------------------
id | integer | | not null | nextval('records_id_seq'::regclass)
user_id | integer | | |
distance | double precision | | |
place | jsonb | | |
speed | jsonb | | |
prediction_type | integer | | |
start_at | timestamp without time zone | | |
end_at | timestamp without time zone | | |
Indexes:
"records_pkey" PRIMARY KEY, btree (id)
moove=# \d records;
Table "public.records"
Column | Type | Collation | Nullable | Default
-----------------+-----------------------------+-----------+----------+-------------------------------------
id | integer | | not null | nextval('records_id_seq'::regclass)
user_id | integer | | |
distance | double precision | | |
place | jsonb | | |
speed | jsonb | | |
prediction_type | integer | | |
start_at | timestamp without time zone | | |
end_at | timestamp without time zone | | |
Indexes:
"records_pkey" PRIMARY KEY, btree (id)


WITH places AS (
SELECT jsonb_array_elements(place) AS place_elements
FROM records
WHERE id = 2
)
SELECT
(SELECT place_elements FROM places LIMIT 1) AS first_place,
(SELECT place_elements FROM places ORDER BY jsonb_array_length(place) DESC LIMIT 1) AS last_place
FROM records
WHERE id = 2;

出力結果
first_place | last_place
-----------------------------------+-----------------------------------
{"lat": 34.7325, "lng": 135.4986} | {"lat": 34.7325, "lng": 135.4986}
(1 row)

2023,江端さんの技術メモ

moove=# SELECT id, user_id, start_at, end_at, end_at - start_at, distance, prediction_type FROM records WHERE user_id = 7 ORDER BY start_at ASC;

id | user_id | start_at | end_at | ?column? | distance | prediction_type
-------+---------+---------------------+---------------------+----------+--------------------+-----------------
20132 | 43 | 2023-04-08 05:35:00 | 2023-04-08 06:20:00 | 00:45:00 | 348821.9097841587 | 4
20133 | 43 | 2023-04-08 06:20:30 | 2023-04-08 06:30:00 | 00:09:30 | 153.88780282790526 | 2
20134 | 43 | 2023-04-08 06:30:30 | 2023-04-08 06:49:30 | 00:19:00 | 180.2412488153271 | 1
20135 | 43 | 2023-04-08 06:50:00 | 2023-04-08 06:53:30 | 00:03:30 | 65.08472909159703 | 2
20136 | 43 | 2023-04-08 06:54:00 | 2023-04-08 08:06:00 | 01:12:00 | 522.2898726850697 | 1
20137 | 43 | 2023-04-08 08:06:30 | 2023-04-08 08:15:00 | 00:08:30 | 144.15400138235145 | 2
20138 | 43 | 2023-04-08 08:15:30 | 2023-04-08 08:23:00 | 00:07:30 | 359.73505399604153 | 1
20139 | 43 | 2023-04-08 08:23:30 | 2023-04-08 08:54:30 | 00:31:00 | 13516.406121323496 | 4
20140 | 43 | 2023-04-08 08:55:00 | 2023-04-08 09:00:30 | 00:05:30 | 30.045448973873317 | 1
20141 | 43 | 2023-04-08 09:01:00 | 2023-04-08 09:05:00 | 00:04:00 | 39.96401615517626 | 2

2023,江端さんの技術メモ

SELECT * FROM records WHERE start_at = '2023-03-20 05:03:00'; を"2023-03-20"が含まれているものだけを条件にするには、どのようなSQL文になりますか

SELECT * FROM records WHERE start_at = '2023-03-20 05:03:00'; を"2023-03-20"が含まれているものだけを条件にして、時間順に表示するSQLを教えて下さい。

moove=# SELECT user_id, start_at, end_at FROM records WHERE user_id = 7 ORDER BY start_at ASC;
user_id | start_at | end_at
---------+---------------------+---------------------
7 | 2023-03-01 03:38:00 | 2023-03-01 03:58:30
7 | 2023-03-01 03:59:00 | 2023-03-01 04:03:00
7 | 2023-03-01 04:03:30 | 2023-03-01 04:09:30
7 | 2023-03-01 04:10:00 | 2023-03-01 04:15:30
7 | 2023-03-01 04:16:00 | 2023-03-01 05:22:30

中略
7 | 2023-05-17 10:48:00 | 2023-05-17 10:54:30
7 | 2023-05-17 10:55:00 | 2023-05-17 11:09:00
7 | 2023-05-17 11:09:30 | 2023-05-17 11:38:30
7 | 2023-05-17 11:39:00 | 2023-05-17 11:53:00
7 | 2023-05-17 11:53:30 | 2023-05-17 11:54:30
7 | 2023-05-17 11:55:00 | 2023-05-17 12:04:00
7 | 2023-05-17 12:04:30 | 2023-05-17 12:30:00
(1514 rows)

2023,江端さんの技術メモ

SELECT * FROM records WHERE start_at = '2023-03-20 05:03:00'; を"2023-03-20"が含まれているものだけを条件にするには、どのようなSQL文になりますか

SELECT * FROM records WHERE start_at = '2023-03-20 05:03:00'; を"2023-03-20"が含まれているものだけを条件にして、時間順に表示するSQLを教えて下さい。

moove=# SELECT user_id, start_at,end_at FROM records WHERE user_id = 7 and DATE(start_at) = '2023-03-21' order by start_at;
user_id | start_at | end_at
---------+---------------------+---------------------
7 | 2023-03-21 00:03:00 | 2023-03-21 00:07:30
7 | 2023-03-21 00:08:00 | 2023-03-21 00:11:00
7 | 2023-03-21 00:11:30 | 2023-03-21 00:18:00
7 | 2023-03-21 00:18:30 | 2023-03-21 00:27:30
(中略)
7 | 2023-03-21 23:22:00 | 2023-03-21 23:30:30
7 | 2023-03-21 23:31:00 | 2023-03-21 23:53:30
7 | 2023-03-21 23:54:00 | 2023-03-22 00:00:30
(35 rows)

2023,江端さんの技術メモ

答えは、\d records; でした
moove=# \dt
          List of relations
 Schema |  Name   | Type  |  Owner
--------+---------+-------+----------
 public | records | table | postgres
(1 row)
moove=# \d records;
                                           Table "public.records"
     Column      |            Type             | Collation | Nullable |               Default
-----------------+-----------------------------+-----------+----------+-------------------------------------
 id              | integer                     |           | not null | nextval('records_id_seq'::regclass)
 user_id         | integer                     |           |          |
 distance        | double precision            |           |          |
 place           | jsonb                       |           |          |
 speed           | jsonb                       |           |          |
 prediction_type | integer                     |           |          |
 start_at        | timestamp without time zone |           |          |
 end_at          | timestamp without time zone |           |          |
Indexes:
    "records_pkey" PRIMARY KEY, btree (id)

2023,江端さんの技術メモ

「Mobile Agent」と「Mobility Agent」は異なる概念を指しますが、どちらも「正しい」といえます。これらは用途や文脈に応じて使われます。

  1. Mobile Agent:
    • 一般的に、ネットワーク上で自律的に移動し、タスクを実行するソフトウェアのことを指します。
    • この用語は、特に分散コンピューティングや情報処理の分野で使用されます。
  2. Mobility Agent:
    • この用語は、モビリティや交通の文脈で使用されることが多く、移動や交通に関するシステムやサービスを指す場合があります。
    • 例えば、交通管理システムやスマートシティのプロジェクトにおける移動の管理や分析を行うエージェントを指すことがあります。

どちらの用語も、その分野や文脈に応じて適切に使用されます。


なるほど

『つまりMobile Agent:は、コンピュータで使われるソフトウェアであって、マルチエージェントシミュレーションのエージェントのことではない。マルチエージェントシミュレーション上で、移動するエージェントのことをMobility Agent:という』

と解釈した(江端)。

Mobile Agent:の例としては、ネットワーク管理エージェントデータマイニングエージェント、Eコマース取引エージェント、負荷分散エージェントのようなもので、マルチエージェントシミュレーション上で移動させるエージェントとは全く違う概念

以上

2023,江端さんの技術メモ

Webサーバに繋っているブラウザが、全部いなくなったことを確認する為に、ブラウザのJavaScriptからハートビートを飛ばして、ハートビートがこなくなったことを確認する簡易プログラムを作成しました。

■ブラウザの生存監視サーバ

$ pip install Flask

をしてから、以下のプログラムをhearbeat.pyという名前でサーバを立ち上げるフォルダ(例 c:\users\ebata)に放り込んでおく。

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/heartbeat', methods=['POST'])
def receive_heartbeat():
    data = request.get_json()
    print(f"Received heartbeat: {data}")
    return jsonify({"status": "OK"})

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=3000)

■index.htmlの内容
これも、サーバを立ち上げるフォルダ(例 c:\users\ebata)に放り込んでおく。

<!DOCTYPE html>
<html>
<head>
    <title>Heartbeat Example</title>
</head>
<body>
    <h1>Heartbeat Sender</h1>
    <script>
        function sendHeartbeat() {
            fetch('http://localhost:3000/heartbeat', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ timestamp: new Date() })
            })
            .then(response => response.json())
            .then(data => console.log('Heartbeat sent:', data))
            .catch(error => console.error('Error sending heartbeat:', error));
        }

        // 10秒ごとにハートビートを送信
        setInterval(sendHeartbeat, 10000);
    </script>
</body>
</html>

■起動方法
(Step 1)サーバを立ち上げるフォルダ(例 c:\users\ebata)で、

C:\Users\ebata>python heartbeat.py

で、「ブラウザの生存監視するサーバ」を起動
(Step 2)次に、以下のコマンドで、1行Webサーバを起動

C:\Users\ebata>python -m http.server 8000

(Step 3) ブラウザに、

http://localhost:8000/

を投入。複数のブラウザを立ち上げて、ブラウザの生存監視サーバから、

の表示が出てくれば成功 → ウソです。
ブラウザを全部落せば、動かなくなるはずです。→ これは本当ですが、def receive_heartbeat()の処理は全くされていません


Choromeの開発者の表示は、こんなのが出ていました。

Access to fetch at 'http://localhost:3000/heartbeat' from origin 'http://localhost:8000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. (index):19 Error sending heartbeat: TypeError: Failed to fetch at sendHeartbeat ((index):10:13)

で、
このエラーメッセージは、CORS(Cross-Origin Resource Sharing)ポリシーに違反していることを示していて、これは、異なるオリジン(localhost:8000とlocalhost:3000)間でのリクエストがブラウザによってブロックされていることを意味します。

この問題を解決するために、FlaskアプリケーションでCORSポリシーを設定する必要があり、Flask-CORSという拡張機能を使用してこれを行うことができます。

pip install flask-cors

で、

from flask import Flask, request, jsonify
from flask_cors import CORS

app = Flask(__name__)
CORS(app) # すべてのリクエストに対してCORSを有効にする

を処理すれば、receive_heartbeat():が実施されます。

で、修正後のコードは以下の通りです。

from flask import Flask, request, jsonify
from flask_cors import CORS

app = Flask(__name__)
CORS(app)  # すべてのリクエストに対してCORSを有効にする

@app.route('/heartbeat', methods=['POST'])
def receive_heartbeat():
    data = request.get_json()
    print(f"Received heartbeat: {data}")
    return jsonify({"status": "OK"})

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=3000)

出力結果

ちょっとまだ疑問はあるけど、とりあえず、メソッドの中には入ったようです。

 

 

2023,江端さんの技術メモ

SELECT * FROM records WHERE start_at = '2023-03-20 05:03:00'; を"2023-03-20"が含まれているものだけを条件にするには、どのようなSQL文になりますか

SELECT * FROM records WHERE start_at::date = '2023-03-20';

プログラムはこちら

// f:\しゅらばしゅう\有吉先生データ\Moove\2023-07/test5.go

package main

import (
    "database/sql"
    "fmt"
    "log"

	_ "github.com/lib/pq"
)

type Location struct {
	Lat float64 `json:"lat"`
	Lng float64 `json:"lng"`
}

type Record struct {
	ID         int        `json:"id"`
	UserID     int        `json:"user_id"`
	Distance   float64    `json:"distance"`
	Place      []Location `json:"place"`
	Speed      []float64  `json:"speed"`
	Prediction int        `json:"prediction_type"`
	StartAt    string     `json:"start_at"`
	EndAt      string     `json:"end_at"`
}

func main() {
	// PostgreSQL データベースへの接続情報
	const (
		host     = "192.168.0.23"
		port     = 15432
		user     = "postgres"
		password = "password"
		dbname   = "moove"
	)

	// PostgreSQL データベースへの接続
	dbinfo := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", host, port, user, password, dbname)
	db, err := sql.Open("postgres", dbinfo)
	if err != nil {
		panic(err)
	}
	defer db.Close()

    fmt.Println("Successfully connected!")

    // 検索したい日付
    var targetDate string = "2023-03-03"

    // 特定の日付を含むレコードを取得するクエリ
    query := fmt.Sprintf("SELECT id, user_id FROM records WHERE start_at::date = '%s'", targetDate)

	fmt.Println("pass1")

    rows, err := db.Query(query)
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()

	fmt.Println("pass2")

    // 各行を繰り返し処理
    for rows.Next() {
        // ここには、取得したいカラムに応じた変数を定義します
        var column1, column2 int // これは、idとuser_idのことです
        // 必要に応じて他のカラムも追加
        err := rows.Scan(&column1,&column2) 
        if err != nil {
            log.Fatal(err)
        }

        fmt.Println(column1, column2) // 取得したデータを出力
        // 他のカラムも出力する場合は、ここに追加
    }

    // 繰り返し処理後のエラーをチェック
    err = rows.Err()
    if err != nil {
        log.Fatal(err)
    }
}

2023,江端さんの技術メモ

UDP12345をポートフォワードするだけで、SRTストリームが通るか?、を自宅のルータで試してみました。