2019年3月29日 星期五

python 處理 word 表格

# coding=utf-8
import docx
import glob
import os
import csv

#設置檔案路徑
path = '範例檔'
#設置輸出檔名
output = 'output.csv'

#開啟輸出的 CSV 檔案
with open(output, 'w', newline='') as csvfile:
  #建立 CSV 檔寫入器
  writer = csv.writer(csvfile)
  #header
  writer.writerow(['檔名','學校','班級','學生','國語','數學','社會','自然','藝術'])
 
for filename in glob.glob(os.path.join(path, '*.docx')):    #遍歷所有檔案
    #doc = docx.Document("範例檔\su_sn_11122.docx")
    doc = docx.Document(filename)
    for table in doc.tables:    #遍歷所有表格
        print("--------")
        _school = ''
        _class = ''
        _student = ''
        _score1 = ''
        _score2 = ''
        _score3 = ''
        _score4 = ''
        _score5 = ''
        done = False
        i = 0
        for row in table.rows:  #遍歷表格的所有 row
            #row_str = "\t".join([cell.text for cell in row.cells])  # 一行數據
            #print(row_str)
            j = 0
            for cell in row.cells:  #遍歷 row 中所有 cell
                #print( cell.text + "\t" )
                #print( str(i)+":"+str(j)+":"+table.cell( i, j ).text + "\t" )
                if cell.text == '學校':
                    _school = table.cell( i, j+1 ).text #抓右邊的 cell
                if cell.text == '班級':
                    _class = table.cell( i, j+1 ).text #抓右邊的 cell
                if cell.text == '學生':
                    _student = table.cell( i, j+1 ).text #抓右邊的 cell
                if cell.text == '國語':
                    _score1 = table.cell( i+1, j ).text  #抓下面的 cell
                if cell.text == '數學':
                    _score2 = table.cell( i+1, j ).text  #抓下面的 cell
                if cell.text == '社會':
                    _score3 = table.cell( i+1, j ).text  #下面的 cell
                if cell.text == '自然':
                    _score4 = table.cell( i+1, j ).text  #抓下面的 cell
                if cell.text == '藝術':
                    _score5 = table.cell( i+1, j ).text  #抓下面的 cell
                    done = True #這是最後一筆資料
                j = j + 1   #指向下一 cell
                if done:
                    break   #完成
            i = i + 1   #指向下一 row
            if done:
                break   #完成
        print( _school )
        print( _class )
        print( _student )
        print( _score1 )
        print( _score2 )
        print( _score3 )
        print( _score4 )
        print( _score5 )
        with open('output.csv', 'a', newline='') as csvfile:
            #建立 CSV 檔寫入器
            writer = csv.writer(csvfile)
            #內容
            writer.writerow([filename,_school,_class,_student,_score1,_score2,_score3,_score4,_score5])
        break #限制1檔1表

2019年3月15日 星期五

Modbus 傳輸資料型態轉換

Modbus 協議傳輸的資料一般只有基本的 U16 型態,但在實際應用上可能因裝置不同而有不同的應用,例如長整數、浮點數,但又因為硬體 CPU/MCU/OS 實際狀況而有位元順序的問題,底下是 python 轉換函式…

def Convert( theType, values  ):
    if( theType == 'FLOAT(ABCD)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[0],tobytes[1],tobytes[2],tobytes[3])
            set_value = struct.unpack('>f', packit)[0]
    elif( theType == 'FLOAT(CDAB)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[2],tobytes[3],tobytes[0],tobytes[1])
            set_value = struct.unpack('>f', packit)[0]
    elif( theType == 'FLOAT(BADC)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[1],tobytes[0],tobytes[3],tobytes[2])
            set_value = struct.unpack('>f', packit)[0]
    elif( theType == 'FLOAT(DCBA)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[3],tobytes[2],tobytes[1],tobytes[0])
            set_value = struct.unpack('>f', packit)[0]
    elif( theType == 'UINT32(ABCD)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[0],tobytes[1],tobytes[2],tobytes[3])
            set_value = struct.unpack('>L', packit)[0]
    elif( theType == 'UINT32(CDAB)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[2],tobytes[3],tobytes[0],tobytes[1])
            set_value = struct.unpack('>L', packit)[0]
    elif( theType == 'UINT32(BADC)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[1],tobytes[0],tobytes[3],tobytes[2])
            set_value = struct.unpack('>L', packit)[0]
    elif( theType == 'UINT32(DCBA)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[3],tobytes[2],tobytes[1],tobytes[0])
            set_value = struct.unpack('>L', packit)[0]
    elif( theType == 'INT32(ABCD)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[0],tobytes[1],tobytes[2],tobytes[3])
            set_value = struct.unpack('>l', packit)[0]
    elif( theType == 'INT32(CDAB)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[2],tobytes[3],tobytes[0],tobytes[1])
            set_value = struct.unpack('>l', packit)[0]
    elif( theType == 'INT32(BADC)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[1],tobytes[0],tobytes[3],tobytes[2])
            set_value = struct.unpack('>l', packit)[0]
    elif( theType == 'INT32(DCBA)' ):
            packit = struct.pack('>hh',values[0],values[1])
            tobytes = struct.unpack('>4c', packit)
            packit = struct.pack('>4c',tobytes[3],tobytes[2],tobytes[1],tobytes[0])
            set_value = struct.unpack('>l', packit)[0]
    elif( theType == 'UINT16(AB)' ):
            packit = struct.pack('>h',values[0])
            tobytes = struct.unpack('>2c', packit)
            packit = struct.pack('>cc',tobytes[0],tobytes[1])
            set_value = struct.unpack('>H', packit)[0]
    elif( theType == 'UINT16(BA)' ):
            packit = struct.pack('>h',values[0])
            tobytes = struct.unpack('>2c', packit)
            packit = struct.pack('>cc',tobytes[1],tobytes[0])
            set_value = struct.unpack('>H', packit)[0]
    elif( theType == 'INT16(AB)' ):
            packit = struct.pack('>h',values[0])
            tobytes = struct.unpack('>2c', packit)
            packit = struct.pack('>cc',tobytes[0],tobytes[1])
            set_value = struct.unpack('>h', packit)[0]
    elif( theType == 'INT16(BA)' ):
            packit = struct.pack('>h',values[0])
            tobytes = struct.unpack('>2c', packit)
            packit = struct.pack('>cc',tobytes[1],tobytes[0])
            set_value = struct.unpack('>h', packit)[0]
    else:
        set_value = values[0]
    return set_value

#Modbus 讀值可能是 2byte 也可能是 4byte
values = [-4370,-8756]
Convert( 'FLOAT(ABCD)' ,values )
Convert( 'FLOAT(DCBA)' ,values )
Convert( 'FLOAT(BADC)'  ,values )
Convert( 'FLOAT(CDAB)'  ,values )
Convert( 'UINT32(ABCD)'  ,values )
Convert( 'UINT32(DCBA)'  ,values )
Convert( 'UINT32(BADC)'  ,values )
Convert( 'UINT32(CDAB)'  ,values )
Convert( 'INT32(ABCD)'  ,values )
Convert( 'INT32(DCBA)'  ,values )
Convert( 'INT32(BADC)'  ,values )
Convert( 'INT32(CDAB)'  ,values )
Convert( 'UINT16(AB)'  ,values )
Convert( 'INT16(AB)'  ,values )
Convert( 'INT16(BA)'  ,values )
Convert( 'UINT16(BA)'  ,values )

2019年1月23日 星期三

Holtek 使用 HSI 的方式

Holtek 使用 HSI 的方式…

以 HT32f2220 為例
從 project_template 建立專案的話,修改底下 define …

在 system_ht32f5xxxx_02.c 中…
#define HSI_ENABLE        (1)     /*!< 0: DISABLE,  1: ENABLE                                               */
#define HSE_ENABLE        (0)     /*!< 0: DISABLE,  1: ENABLE                                               */
#define LSI_ENABLE        (1)     /*!< 0: DISABLE,  1: ENABLE                                               */
#define LSE_ENABLE        (0)     /*!< 0: DISABLE,  1: ENABLE                                               */
#define PLL_ENABLE        (1)     /*!< 0: DISABLE,  1: ENABLE                                               */
#define PLL_CLK_SRC       (1)     /*!< 0: HSE,      1: HSI                                                  */

再直接使用 example 中的 SysClockConfig_HSI() 函式進入 HIS 模式即可。

這樣 XTALIN、XTALOUT 就能拿來當 gpio 腳了。

2018年11月21日 星期三

Debian Security Bug Tracker

檢查弱點分析的方式

到…
Debian Security Bug Tracker
https://security-tracker.debian.org/tracker/

查詢弱點…
譬如 CVE-2017-3169

Debian / Raspberry Pi 檢查版本
dpkg -l apache2

比較版本號是否有修正此 bug

2018年7月20日 星期五

備份 Raspberry Pi 時SD卡容量不相符的解決方式

備份回復 rpi image 的時候有時會遇到 sd card 雖號稱一樣 g 數,但實際大小卻不一樣,導致回復時出問題,此時可以用底下 scripts 解決,先把檔案變小就好解決… (linux 環境下)

Shrink your Raspberry Pi SD Card Image size

https://github.com/Drewsif/PiShrink

Very Nice !!


硬體從 rpi2 改到 rpi3
舊 SDCard 無法順利在 rpi3 開機的問題

apt-get install rpi-update
rpi-update

2018年7月1日 星期日

mqtt@RaspberryPi

broker / server / client library install...
# 安裝 broker 及 所需函式庫

sudo apt-get install mosquitto mosquitto-clients
sudo apt-get install python3-pip
sudo pip3 install paho-mqtt

fix python search path...
# poah 安裝路徑若 python 找不到要作修正

cd /usr/lib/python2.7/dist-packages
sudo ln -s /usr/local/lib/python3.5/dist-packages/paho


subscribe...
# Subscribe 訂閱訊息/接收訊息

import paho.mqtt.client as mqtt 
def on_connect(client, userdata, flags, rc):
  print("Connected with result code "+str(rc))
  client.subscribe("where/is/my/topic") 

def on_message(client, userdata, msg):
  print(msg.topic+" "+str(msg.payload)) 

client = mqtt.Client()
client.on_connect = on_connect    #call back function
client.on_message = on_message    #call back function
client.connect("localhost", 1883, 60)
client.loop_forever()

pubilsh...
# Publisher 發佈訊息

import paho.mqtt.publish as publish
# publish a message then disconnect.

host = "localhost"
topic = "where/is/my/topic"
payload = "hello"

# If broker asks user/password.
auth = {'username': "", 'password': ""}

# If broker asks client ID.
client_id = ""

publish.single(topic, payload, qos=1, hostname=host)
#publish.single(topic, payload, qos=1, host=host, auth=auth, client_id=client_id)




2018年5月9日 星期三

Raspberry pi VLAN



Raspberry pi 3 僅一個 RJ45 port,若要當二個實體 ip 用,需建立 VLAN 虛擬網卡

二張網卡在不同子網域 A&B,A是主要網卡,B是延伸的虛擬網卡
A:IP=192.168.254.31
B:IP=192.168.1.31
其中一個 ip 必須能與其它裝置建立 UDP 通訊,且此裝置無法進行進一步的網路設置

注意!! UDP 是透過 python socket 的 create_udp_socket() 來建立連線,界面 A 必須建立在 UDP 所要通訊的網址上,否則無法正常通訊 why? route issues?

一、建立二張網卡界面…
sudo nano /etc/network/interfaces

iface eth0 inet manual

# VLAN Interface
auto eth0.1
iface eth0.1 inet manual
    vlan-raw-device eth0

二、設定二張網卡 ip / router …
sudo nano /etc/dhcpcd.conf

#A-->B-->
#A
interface eth0
static ip_address=192.168.254.31/16
static routers=192.168.1.31
static domain_name_servers=xxx.xxx.xxx.xxx

#B
# Static IP configuration for VLan
interface eth0.1
static ip_address=192.168.1.31/16
static routers=192.168.1.72
static domain_name_servers=xxx.xxx.xxx.xxx



VirtualBox 空間減肥

@windows vm sdelete64 -z c: @macos VBoxManage  modifymedium  disk  "/Users/fellow/VirtualBox VMs/Win10/Win10.vdi"  --compact *.vdi...