Skip to content

Commit

Permalink
add data convert gui tool
Browse files Browse the repository at this point in the history
  • Loading branch information
sourceperl committed Feb 27, 2017
1 parent 74bdef8 commit 9fd7f97
Show file tree
Hide file tree
Showing 2 changed files with 169 additions and 0 deletions.
168 changes: 168 additions & 0 deletions scripts/conv-data-gui
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#!/usr/bin/env python3

import tkinter as tk
from tkinter import ttk
import struct
import binascii

# some const
FORMATS = ['LONG (entier sur 4 octets)',
'SINGLE (flottant sur 4 octets)',
'DOUBLE (flottant sur 8 octets)']


def hex_to_long(s):
b_hex = binascii.unhexlify(s.rjust(8, '0'))
if len(b_hex) > 4:
raise ValueError
return struct.unpack('!l', b_hex.rjust(4, b'\0'))[0]


def hex_to_single(s):
b_hex = binascii.unhexlify(s.rjust(8, '0'))
if len(b_hex) > 4:
raise ValueError
return struct.unpack('!f', b_hex.rjust(4, b'\0'))[0]


def hex_to_double(s):
b_hex = binascii.unhexlify(s.rjust(8, '0'))
if len(b_hex) > 8:
raise ValueError
return struct.unpack('!d', b_hex.rjust(8, b'\0'))[0]


def long_to_hex(l):
return '%08x'.upper() % (struct.unpack('<I', struct.pack('<l', l))[0])


def single_to_hex(s):
return '%08x'.upper() % (struct.unpack('<I', struct.pack('<f', s))[0])


def double_to_hex(d):
return '%016x'.upper() % (struct.unpack('<Q', struct.pack('<d', d))[0])


class FrmTab(tk.Frame):
def __init__(self, notebook, update_ms=500, *args, **kwargs):
tk.Frame.__init__(self, notebook, *args, **kwargs)
# global tk app shortcut
self.notebook = notebook
self.app = notebook.master
# frame auto-refresh delay (in ms)
self.update_ms = update_ms
# setup auto-refresh of notebook tab (on-visibility and every update_ms)
self.bind('<Visibility>', lambda evt: self.tab_update())
self._tab_update()

def _tab_update(self):
if self.winfo_ismapped():
self.tab_update()
self.master.after(self.update_ms, self._tab_update)

def tab_update(self):
pass


class TkApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
# configure main window
self.wm_title('Convertion format de donnée')
# self.attributes('-fullscreen', True)
# self.geometry('800x400')
# build a notebook with tabs
self.fMain = FrmMain(self)
self.fMain.pack(fill=tk.BOTH, expand=tk.YES)

def do_every(self, do_cmd, every_ms=1000):
do_cmd()
self.after(every_ms, lambda: self.do_every(do_cmd, every_ms=every_ms))


class FrmMain(FrmTab):
def __init__(self, notebook, update_ms=500, *args, **kwargs):
FrmTab.__init__(self, notebook, update_ms, *args, **kwargs)
# some vars
self.hex_str = tk.StringVar(value='00000000')
self.value_str = tk.StringVar(value='0')
self.fmt_str = tk.StringVar()
self.data_fmt = ''
# install callback
self.fmt_str.trace('w', self.on_data_fmt_change)
# capture frame
self.frm1 = tk.Frame(self)
self.frm1.grid(row=0, column=0, sticky=tk.NSEW, padx=5, pady=5)
self.lbl_dat = tk.Label(self.frm1, text='Data (format hexa)')
self.lbl_dat.grid(row=0, column=0, sticky=tk.W, padx=5, pady=5)
self.ent_hex = tk.Entry(self.frm1, width=16, validate='all', textvariable=self.hex_str)
self.ent_hex.grid(row=0, column=1, sticky=tk.W, padx=5, pady=5)
self.lbl_val = tk.Label(self.frm1, text='Valeur (format décimal)')
self.lbl_val.grid(row=1, column=0, sticky=tk.W, padx=5, pady=5)
self.ent_val = tk.Entry(self.frm1, width=16, textvariable=self.value_str)
self.ent_val.grid(row=1, column=1, sticky=tk.W, padx=5, pady=5)
self.lbl_fmt = tk.Label(self.frm1, text='formats')
self.lbl_fmt.grid(row=2, column=0, sticky=tk.W, padx=5, pady=5)
self.cbb_fmt = ttk.Combobox(self.frm1, textvariable=self.fmt_str, values=FORMATS, width=25)
self.cbb_fmt.current(newindex=0)
self.cbb_fmt.grid(row=2, column=1, sticky=tk.W, padx=5, pady=5)
self.but_to_value = tk.Button(self.frm1, text='Convertion data > valeur', command=self.data_to_value)
self.but_to_value.grid(row=3, column=0, sticky=tk.EW, padx=5, pady=5)
self.but_to_hex = tk.Button(self.frm1, text='Convertion valeur > data', command=self.value_to_data)
self.but_to_hex.grid(row=3, column=1, sticky=tk.EW, padx=5, pady=5)

def on_data_fmt_change(self, *args):
self.data_fmt = (self.cbb_fmt.get().split(' ')[0])
# 32 bits: limit to 8 digits
if self.data_fmt in ['LONG', 'SINGLE']:
self.hex_str.set(self.hex_str.get().rjust(8, '0')[-8:])
# 64 bits: limit to 16 digits
elif self.data_fmt in ['DOUBLE']:
self.hex_str.set(self.hex_str.get().rjust(16, '0')[-16:])

def data_to_value(self):
if self.data_fmt == 'LONG':
try:
self.value_str.set(hex_to_long(self.hex_str.get()))
self.ent_hex.config(bg='white')
except ValueError:
self.ent_hex.config(bg='red')
elif self.data_fmt == 'SINGLE':
try:
self.value_str.set(hex_to_single(self.hex_str.get()))
self.ent_hex.config(bg='white')
except ValueError:
self.ent_hex.config(bg='red')
elif self.data_fmt == 'DOUBLE':
try:
self.value_str.set(hex_to_double(self.hex_str.get()))
self.ent_hex.config(bg='white')
except ValueError:
self.ent_hex.config(bg='red')

def value_to_data(self):
if self.data_fmt == 'LONG':
try:
self.hex_str.set(long_to_hex(int(self.value_str.get())))
self.ent_val.config(bg='white')
except ValueError:
self.ent_val.config(bg='red')
elif self.data_fmt == 'SINGLE':
try:
self.hex_str.set(single_to_hex(float(self.value_str.get())))
self.ent_val.config(bg='white')
except ValueError:
self.ent_val.config(bg='red')
elif self.data_fmt == 'DOUBLE':
try:
self.hex_str.set(double_to_hex(float(self.value_str.get())))
self.ent_val.config(bg='white')
except ValueError:
self.ent_val.config(bg='red')


if __name__ == '__main__':
# main Tk App
app = TkApp()
app.mainloop()
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@
'scripts/modbus-scan-serial',
'scripts/modbus-request-serial',
'scripts/modbus-gui',
'scripts/conv-data-gui',
],
)

0 comments on commit 9fd7f97

Please sign in to comment.