2022年9月12日月曜日

magick packet

 


https://irukanobox.blogspot.com/2017/08/raspberry-pipython3pc.html  参照

Raspberry PiとPython3でPCを起動する

多くのPCにはWake On LAN(WOL)という機能があって、ネットワーク越しにマジックパケットという指定のパケットを送ると、PCの電源を入れることができる。Raspberry PiからPython3でマジックパケットを送り、Windows10 PCの電源を入れてみる。

Raspberry PiのOSはRaspbian Jessie、Python3のバージョンは以下の通り。


Windows機側でWOLを有効にするにはBIOS/UEFIとOSのLANコントローラドライバの設定が必要で、その方法についてはWake On LANでコンピュータを起動する を参照。

マジックパケットというのは、6個の0xFFとパケットを受信する側のMACアドレス16個からなる計102バイトのデータを含むパケット。MACアドレスがAA:BB:CC:11:22:33の場合、FFFFFFFFFFFFAABBCC11223344AABBCC...のようなイメージになるが、実際はバイナリデータなので、Python3のprintで出力すると、「b'\xff\xff\xff\xff\xff\xff\xaa\xbb\xcc\x11"3\xaa\xbb\xcc\x11"3\xaa\xbb\xcc...」のように、\x~とASCII文字が混在したものになる。

パケットの送り方は特に決まっていないが、UDPとブロードキャスト、ポート番号は7か9を使うのが一般的らしい。ブロードキャストアドレスには、255.255.255.255とIPアドレスのホスト部のビットがすべて1のアドレスがあるが、ルータを越える必要がなければ255.255.255.255で問題ないので、ここでは255.255.255.255を使う。

MACアドレスがAA:BB:CC:11:22:33の端末にマジックパケットを送るPython3のコード。
sample.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import socket
import binascii
 
# MACアドレス
MACADDR = 'AA:BB:CC:11:22:33'
# ブロードキャストアドレス
BCADDR = '255.255.255.255'
# 宛先ポート番号
PORT = 7
 
macstr = ''.join(MACADDR.split(':'))
mdata = 'FF' * 6 + macstr * 16
# 16進数表記の文字列を表すバイナリデータに変換
mdata = binascii.unhexlify(mdata)
 
# ソケットの作成
# 第一引数: アドレス (およびプロトコル) ファミリーを示す定数
# socket.AF_INETのときは(host, port)
# 第二引数: ソケットタイプ、UDPならSOCK_DGRAM、TCPならSOCK_STREAM
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 
# ブロードキャストを使用するための設定
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
 
# ソケットにデータを送信
s.sendto(mdata, (BCADDR, PORT))
 
s.close()

Windows PCをスリープ状態にして、Raspberry PiのPython3で上記スクリプトを実行すると、Windows PCがスリープからめでたく復帰。

LANコントローラによっては、シャットダウンした状態でもマジックパケットを受け取れるものもあるらしいが、残念ながら家のPCではできなかった。

MACアドレスを引数として渡せるようにして、MACアドレスチェックを追加したスクリプトを作成。(2017.9.30)
"""
Send magic(WOL) packet
"""
import socket
import binascii
import sys
import re
# Broadcast address
BCADDR = '255.255.255.255'
# Port
PORT = 7
def macstr(macaddr):
"""
Check the validity of the MAC address
"""
if len(macaddr) == 17:
maclist = macaddr.split(':')
if len(maclist) == 6:
if len(list(filter(lambda x: re.match('^[0-9a-fA-F]{2}', x), maclist))) == 6:
return ''.join(maclist)
print('Invalid MAC address: ' + macaddr)
exit()
def main():
params = sys.argv
if len(params) != 2:
print('Usage: python3 wol.py [MAC address]')
print('e.g.')
print('python3 wol.py AA:BB:CC:11:22:33')
exit()
mdata = 'FF' * 6 + macstr(params[1]) * 16
print('Sending a magic packet to ' + params[1])
# Convert into binary data represented by hexadecimal string
mdata = binascii.unhexlify(mdata)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.sendto(mdata, (BCADDR, PORT))
s.close()
if __name__ == '__main__':
main()
view rawwol.py hosted with ❤ by GitHub

2022年8月20日土曜日

 

https://qiita.com/botisle/items/87b39e7879d788c2e8d7  参照


SCPIによる測定器の自動化

ネットワーク自動化 Advent Calendar 2019 12/17分のエントリー

モチベーション

測定器を用いたネットワーク機器のパフォーマンス計測や状態計測(光量計測 など)は
決められた計測メニューを繰り返し実施する事が多く、その都度に設定するのは非効率となる。

また、一定のインターバルを設定した長期間計測やパラメーターを変えながらの繰り返し計測を実施する場合
測定器によっては、計測メニュー 等でフレキシブルに対応する事が出来ない。

上記の問題点を解消する為に測定器をプログラマブルに制御し、自動化したい。

SCPI

SCPI(Standard Commands for Programmable Instruments)は
測定器の統一的な制御を目的としたコマンド群となる。

SCPIはGPIB(※) 等で知られるIEEE 488規格の中で産まれたコマンド群である為
元々はGPIB通信 などで使用されてきたが
現在ではTCP/IP通信、シリアル通信、USB通信 等にも対応している。
※当時のHP(HP -> Agilent -> Keysight)が測定器とPC等を接続し制御する為に開発したHPIBという規格が
 他社でも広く採用されたもの(後にIEEE 488 として標準化された)

GPIBは測定器インターフェースのデファクトスタンダード的な役割を持っていたものの
GPIBケーブル、コネクタのサイズの大きさや接続数制限、ケーブル長制限といった問題を抱えていた。
様々なインターフェースに対応した事で
PCと測定器を接続する際にPC側にGPIBインターフェースを持つ必要は無くなった。

SCPIはIEEE 488.2で定義された共通コマンドと各測定器に固有なサブシステムコマンドの2種類に大別される。
どちらのコマンドも値を設定する場合はコマンドに続いてパラメーターを指定し
値を参照したい場合はコマンドの最後に?(クエスチョンマーク) を付与する。

■ 共通コマンド
 先頭が*(アスタリスク)でその後、3文字が続く

 *XXX

 例)製品名を確認する
  *IDN?
  → VIAVI Solutions,MTS 6000A V2,00001,ISU,18.00

■ サブシステムコマンド
 階層構造を持ち、階層間のキーワードを:(コロン)で区切る

 SYSTem:
      DATe
      TIMe
      SCReen

 例)システムの日付を設定する、日付を確認する
  SYSTem:DATe 2020,01,01
  SYSTem:DATe?
  → 2020,01,01

SCPIの利用形態としては様々あり、以下がその1部の例となる。

interface.png

VISA(Virtual Instrument Software Architecture)とはSCPI環境で使用されるライブラリであり
インターフェース(RJ45、RS-232、USB、GPIB)の違いを吸収し、統一的な環境を提供する。
 Python だとPyVISA という実装がある

ただ、今回はVISAライブラリを利用せずに最も汎用的に使える RAW SOCKETを利用する事とする。
 上図だと1番下の例

検証目的と環境

検証目的

光スペクトラムアナライザー(OSA)を用いて、WDM装置からの光信号を10分間隔で1日間計測する。
 OSAの種類によっては、インターバル時間と計測期間を指定できるものもあるが本検証対象は非対応

検証環境

端末:CentOS 7.2、Python 2.7.5
測定器:VIAVI Solutions MTS 6000A V2(本体) + I-PMD(OSAモジュール)

端末と測定器をUTPケーブルで接続し、測定器と計測対象である伝送装置を光ケーブルで接続する。

env1.png

伝送装置のコンポーネントであるMux/Demux や ROADMにはMonitor Portと呼ばれるポートがある事が多く
伝送装置が伝送している光信号をモニタリングする事が出来る。
これを利用する事でプロダクション環境であってもin-serviceで光信号の計測が可能となる。

検証コード

■ 実際に手動で計測する手順

前提
 計測には前もって設定してある計測メニューを使用

計測
 測定器のハードキー「START」を押下して計測を開始

計測結果のファイル保存
 測定器のハードキー「FILE」を押下
 その後、測定器のソフトキー「Store」→「Save」→「Enter」→「Exit」を押下

ハードキー
 測定器に搭載されている物理的なキー
hardkey_all.png

ソフトキー
 測定器の画面上に表示されるソフトウェア的に再現されたキー
 画面によりキーの内容が変わる
softkey_all.png

■ コード

上記のオペレーションを以下の通りにコードで表現

import socket
import time

ip = '192.168.0.100'
port = 8000
status = ''

# TCPソケットを生成し測定器に接続
s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s1.connect((ip, port))

# リモート制御をする場合は最初に*REMコマンドを実行し、Programmed Mode に変更
# コマンドの最後に改行コードを挿入(VISAライブラリを利用している場合は考慮不要)
s1.send('*REM\n')

# 測定器本体への接続(Port 8000)とは別にOSAモジュールへの接続が必要
# MOD:FUNC:PORT?コマンドでOSAモジュールへの接続Portを確認(default Port 8002)
# コマンドパラメーターとして、モジュール搭載位置(pwrside,slic1)とモジュール名(I-PMDモジュール="PIB") を指定
s1.send('MOD:FUNC:PORT?pwrside,slic1,"PIB"\n')
port = int(s1.recv(1024))

# OSAモジュールへ接続
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2.connect((ip, port))
s2.send('*REM\n')


# 計測を1日間(600秒 x 144回) 実行
for i in range(144):
    # ハードキー:START を押下
    s1.send('KEY START\n')
    time.sleep(5)

    # 計測に数秒を要する為、OSAモジュールの状態を監視
    while 'STOPPED' not in status:
        # OSAモジュールの現ステータスを確認
        s2.send('STATus:ACQ?\n')
        status = s2.recv(1024)
        time.sleep(1)

    # ハードキー:FILE を押下
    s1.send('KEY FILE\n')
    time.sleep(5)

    # ソフトキー:SK1 = Store を押下
    s2.send('KEY SK1\n')
    time.sleep(5)

    # ソフトキー:SK2 = Save を押下
    s2.send('KEY SK2\n')
    time.sleep(5)

    # ソフトキー:SK7 = Enter を押下
    s2.send('KEY SK7\n')
    time.sleep(5)

    # ソフトキー:SK7 = Exit を押下
    s2.send('KEY SK7\n')

    time.sleep(575)

s2.close()
s1.close()

■ 補足

SCPI用Port
 下記コマンドからも分かるように、IANAの割当はPort 5025 となっているが
 今回の対象測定器はPort 8000 となる。

# whatportis 5025
+----------+------+----------+-------------+
| Name     | Port | Protocol | Description |
+----------+------+----------+-------------+
| scpi-raw | 5025 | tcp, udp | SCPI-RAW    |
+----------+------+----------+-------------+

キー入力間のsleep処理
 本来であれば、共通コマンドの*WAIコマンドを使い
 実行コマンドの終了を確認後に次の処理へ移るが
 今回の対象測定器では実装が確認出来なかった為、time.sleepを利用した。
 計測のインターバルにそれ程の精度は求めていない為、許容する。

計測結果のファイル保存
 ファイル名は事前の設定により、任意の文字列+数字の連番 となっている為
 自動でユニークなファイル名となる。

以上、かなり原始的なプログラミングとはなるが
その分、手動オペレーションとのイメージの乖離がない自動計測を可能とした。

2022年7月19日火曜日

  PlaneAhead 落っこちる。32bit 起動 ISEから

参照:

https://www.haljion.net/index.php/2019-11-13-03-27-18/2019-11-13-11-33-14/120-fpga/2019-11-18-02-29-10/188-windows8-os-ise-webpack


ISE のLaunch (Plan AheadをISEからcall するプロセス)にオプションがついている。-m64 これが64bitを起動するオプション。

どこで変更するかわからないので、呼び出された側(batファイル)の分岐でどんなオプションが来てもwin32をcallするよう変更  


Xilinx社製のISE WebPACKは,Spartan6などの6シリーズより以前のFPGAに回路を構築するためのIDEです.2015年現在,Vertex7のように7シリーズに回路を構築するにはVivadoというIDEを使うことになり,おそらく今後,Vivadoで6シリーズ以前のFPGAには対応しないと思われます.つまり,6シリーズ以前のデバイスを使うには引き続きISE WebPACKを使用しなければならないということです.しかし困ったことに,ISE WebPACKはWindows8以降のOSではまともの動作しません.この文書ではこの問題の回避方法について述べています.


環境

まず,動作環境を示しておきます.

  • OS : Windows8以降(Windows8.1を含む), 64ビット
  • ISE WebPACK : 14.7(ISE WebPACKの最後のバージョン)

インストール

インストール方法についてはこちらで説明していますが,ライセンスの設定のみ行えませんので,後述の「Windows8以降で動作させるための設定」を行った後,ライセンスの設定を行ってください.ライセンスの設定方法はこちらに書いておきます.


 Windows8以降で動作させるための設定

Windows8以降のOSでISE WebPACKを動作させようとして問題となることは大きく分けて2種類あります.一つはファイルセレクタが動作しないこと,もう一つは64ビット版の外部アプリケーションであるPinAheadが起動しないことです.これらの問題を解決するため,2個の設定を行いましょう.

libPortability.dllの修正

libPortability.dllはファイルセレクタのためのダイナミックリンクライブラリです.これが悪さをしているため,ライセンスの設定やISE WebPACKのファイルを開くことができません.次に示す2個のディレクトリにあるlibPortability.dllをバックアップ(例えばファイル名に「_orig」を付ける)してください.

C:¥Xilinx¥14.7¥ISE_DS¥ISE¥lib¥nt64
C:¥Xilinx¥14.7¥ISE_DS¥common¥lib¥nt64

次に,C:¥Xilinx¥14.7¥ISE_DS¥ISE¥lib¥nt64にある「libPortabilityNOSH.dll」をコピーし,名前を「libPortability.dll」にしてください.同様に,C:¥Xilinx¥14.7¥ISE_DS¥common¥lib¥nt64へも「libPortabilityNOSH.dll」をコピーし,名前を「libPortability.dll」にしてください.

32ビット版PlanAheadを起動するように変更

PlanAheadは独立したアプリケーションで,64ビット版をWindows8以降のOSで動作させようとしても動きません.そこで,ISE WebPACKから32ビット版のPlanAheadを動作させるように変更します.ISE WebPACKからPlanAheadを呼び出すとき,下記のバッチファイルを用いています.

C:¥Xilinx¥14.7¥ISE_DS¥PlanAhead¥bin¥rdiArgs.bat

このバッチファイル内で,32ビット版PlanAheadを動作させるように変更します.このファイルをrdiArgs.bat.orig等のようなファイルとしてコピーしておいた上で,下記の変更をしてください.

  • 16,17,18,20行目の各行のはじめに「rem #」を付けてください.これにより,16~18と20行目はコメントアウトされます.
  • 32行目にある「win64」を「win32」に変更してください.

ライセンスの設定方法

通常,インストール時にライセンスを設定できるのですが,ファイルセレクタが動かないため,インストール時には設定できません.そこで,インストール時にはライセンスの設定をせずに終了したのち,ISE WebPACKを起動し,メニュー[Help]⇒[Manage License...]を選んでください.この手順ではライセンスを設定できない場合があります.具体的にはライセンスを設定するアプリケーション(xlcm.exe)が立ち上がってこない現象が見られました.その場合にはこちらにある方法で対応してください.

2022年6月21日火曜日

Ras Piカメラ RTSPほか

 


https://qiita.com/lis-hanzomon/items/cc1f7f316fbeb9579b28  参照


https://www.blogger.com/blog/post/edit/7435233686980675536/1874155317581794248

MJPEGは古いんだろうか。。


【プログラミング】

2022年2月19日土曜日

Raspberyy Pi rtsp server

 


Raspberyy Pi  rtsp

Raspberry Pi と USB接続のWebカメラ で


1 はじめに

手軽に利用できるRTSPサーバ:Raspberry Pi 

使用:v412rtspserver

https://github.com/mpromonet/v4l2rtspserver


Linux OSのディストリとバージョン

$ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description: Raspbian GNU/Linux 9.4 (stretch)
Release: 9.4
Codename: stretch

カーネル

$ uname -a
Linux raspberrypi 4.14.79-v7+ #1159 SMP Sun Nov 4 17:50:20 GMT 2018 armv7l GNU/Linux

(3) Webカメラ

http://buffalo.jp/product/multimedia/web-camera/bsw32km01h/


3 コンパイル等


(1) カメラの認識

カメラが /dev/video0 で認識できていることの確認

$ v4l2-ctl --list-devices
USB Camera: USB Camera (usb-3f980000.usb-1.1.3):
/dev/video0

/etc/modulesにbcm2835-v4l2を追加して再起動する

# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.

i2c-dev
bcm2835-v4l2

(2) 必要モジュールのインストール

$ sudo apt-get install cmake
$ sudo apt-get install subversion
$ sudo apt-get install liblivemedia-dev

(3) コンパイル及び、インストール

$ git clone https://github.com/mpromonet/h264_v4l2_rtspserver.git
$ cd h264_v4l2_rtspserver
$ sudo cmake .
$ sudo make install

コンパイル及び、インストールが完了すると、/usr/local/bin/v4l2rtspserverが利用可能になります。

Install the project...
-- Install configuration: ""
-- Installing: /lib/systemd/system/v4l2rtspserver.service
-- Installing: /usr/local/bin/v4l2rtspserver
-- Installing: /usr/local/share/v4l2rtspserver/index.html
-- Installing: /usr/local/share/v4l2rtspserver/hls.js/dist/hls.light.min.js

4 配信

v4l2rtspserverを実行するだけで、デフォルト値でRTSPサーバとして動作します。(採用されたデフォルト値は、コンソールに表示されます。)

$ sudo v4l2rtspserver
Create V4L2 Source.../dev/video0
driver:uvcvideo capabilities:84200001 mandatory:4000001
/dev/video0 support capture
/dev/video0 support streaming
/dev/video0:YUYV size:640x480
Cannot set pixelformat to:H264 format is:YUYV
/dev/video0:MJPG size:640x480 bufferSize:614400
fps:1/30
nbBuffer:0
Device /dev/video0 nb buffer:10
Create Source .../dev/video0
begin thread

デフォルトで起動した場合、rtsp://<RaspberryPiのアドレス>:8554/unicastでアクセス出来ます。(デフォルトでポート8554、パスは/unicastとなっています)

パラメータでデフォルト値以外の指定も可能です。

./v4l2rtspserver [-v[v]] [-Q queueSize] [-O file] \
[-I interface] [-P RTSP port] [-p RTSP/HTTP port] [-m multicast url] [-u unicast url] [-M multicast addr] [-c] [-t timeout] \
[-r] [-s] [-W width] [-H height] [-F fps] [device1] [device2]
-v : verbose
-vv : very verbose
-Q length: Number of frame queue (default 10)
-O output: Copy captured frame to a file or a V4L2 device

RTSP options :
-I addr : RTSP interface (default autodetect)
-P port : RTSP port (defa-ult 8554)
-p port : RTSP over HTTP port (default 0)
-U user:password : RTSP user and password
-R realm : use md5 password 'md5(::')
-u url : unicast url (default unicast)
-m url : multicast url (default multicast)
-M addr : multicast group:port (default is random_address:20000)
-c : don't repeat config (default repeat config before IDR frame)
-t secs : RTCP expiration timeout (default 65)
-S[secs] : HTTP segment duration (enable HLS & MPEG-DASH)

V4L2 options :
-r : V4L2 capture using read interface (default use memory mapped buffers)
-w : V4L2 capture using write interface (default use memory mapped buffers)
-s : V4L2 capture using live555 mainloop (default use a separated reading thread)
-f : V4L2 capture using current capture format (-W,-H are ignored)
-fformat : V4L2 capture using format (-W,-H are used)
-W width : V4L2 capture width (default 640)
-H height: V4L2 capture height (default 480)
-F fps : V4L2 capture framerate (default 25, 0 disable setting framerate)
-G x[x] : V4L2 capture format (default 0x0x25)

ALSA options :
-A freq : ALSA capture frequency and channel (default 44100)
-C channels: ALSA capture channels (default 2)
-a fmt : ALSA capture audio format (default S16_LE)

device : V4L2 capture device and/or ALSA device (default /dev/video0)

5 自動起動

Raspberry Pi を起動しただけで、自動的に配信が開始するように、/etc/rc.local に /usr/local/bin/v4l2rtspserver を書いておきます。

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %s\n" "$_IP"
fi

/usr/local/bin/v4l2rtspserver -W 1280 -H 960 -F 7

exit 0