Compare commits

...

16 Commits

Author SHA1 Message Date
peterlu14 58bfc86572 - Fixed parameter value string error 2024-10-04 11:59:28 +08:00
peterlu14 febba59c37 - Fix Elite_2.0 ble_write
- Fix Pel_2.0 parameters
2024-10-01 15:09:23 +08:00
peterlu14 b8f39e984b - Add pulse_e_load_2.0 lib 2024-10-01 11:48:25 +08:00
peterlu14 59585507a5 - Fix missing parameter ADC_VALUE_I 2024-09-20 09:45:35 +08:00
peterlu14 f9f15457cf change default parameter 2024-09-11 16:47:34 +08:00
peterlu14 cf62cfbe04 - Add coundown instruction 2024-09-11 10:00:00 +08:00
peterlu14 33697af99c - Add countdown internal instruction for device 2024-09-11 09:59:24 +08:00
peterlu14 985e043ca5 - Complete CPG 1.1 parameters & instructions 2024-09-10 16:04:48 +08:00
peterlu14 8fd119f4f0 support float domain parameter 2024-09-10 16:04:14 +08:00
peterlu14 b5bd64bf6c - BLE_WRITE change instruction type to ALL 2024-08-21 17:42:05 +08:00
peterlu14 241296f36c -Enable TYPE ALL Instruction 2024-08-21 17:40:58 +08:00
peterlu14 f46073a46a -CPG BLE_WRITE extend to 255 bytes 2024-08-21 14:55:28 +08:00
peterlu14 24fd5ca28b -Extension of list parameter parse rule
-Fix the list paratmeter change with changing it's length
2024-08-21 14:42:36 +08:00
peterlu14 288f261abe - Add CPG library 2024-07-31 15:02:29 +08:00
peterlu14 a32267f1fd update pulse_e_load json 2024-07-30 10:27:58 +08:00
Roy c89c6e88d0 update EDC1.5r2 library and new EDC2.0 library 2024-03-05 17:07:52 +08:00
16 changed files with 4224 additions and 29 deletions
+12 -6
View File
@@ -429,17 +429,20 @@ class CC2650Device(Device):
self._start_flag = False
def _encode_instruction(self, ins_type: int, ins_oper: int, *instruction: int) -> bytes:
# print('_encode_instruction', ins_type, ins_oper, instruction)
length = len(instruction)
if length == 1 and instruction[0] < 0:
return struct.pack('2B1b',
(ins_type & 0xF0) | (self.device_id & 0x0F),
(ins_oper & 0xFF),
*instruction)
return struct.pack('%dB' % (length + 2),
(ins_type & 0xF0) | (self.device_id & 0x0F),
(ins_oper & 0xFF),
*instruction)
if ins_type == None:
return struct.pack('%dB' % length, *instruction)
else:
return struct.pack('%dB' % (length + 2),
(ins_type & 0xF0) | (self.device_id & 0x0F),
(ins_oper & 0xFF),
*instruction)
def _decode_data(self, ins_oper: int, data: bytes) -> bytes:
"""CIS data decoder.
@@ -2270,7 +2273,10 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
ins = bytearray()
ins.append(0x06)
ins.append(len(data)+2) #length = handle + C0C0XXXX(data len) + F1
if len(data) + 2 > 255:
ins.append(255)
else:
ins.append(len(data)+2) #length = handle + C0C0XXXX(data len) + F1
ins.append(handle)
ins.extend(data)
ins.append(0xF1)
+8
View File
@@ -836,6 +836,9 @@ class DeviceManager(MasterDevice, Synchronized):
elif func == InternalInstruction.PREDEFINED_IDLE:
self._idle(device, *para)
elif func == InternalInstruction.PREDEFINED_COUNTDOWN:
self._countdown(device, *para)
elif isinstance(device, DebugDevice):
if func == InternalInstruction.PREDEFINED_NOTIFY:
return True
@@ -858,6 +861,11 @@ class DeviceManager(MasterDevice, Synchronized):
self._handler.device_internal_command(device.device_id,
InternalInstruction.PREDEFINED_IDLE,
None)
def _countdown(self, device: Device, expr: AnyStr):
self._handler.device_internal_command(device.device_id,
InternalInstruction.PREDEFINED_COUNTDOWN,
expr)
def _device_data_format_cali(self, device: Device, expr: str, cali: bytes = None):
if cali is None:
+5 -1
View File
@@ -689,11 +689,13 @@ class DeviceInstruction:
TYP_IIS = -1
"""internal instruction"""
TYP_ALL = None
__slots__ = ()
@classmethod
def valid_ins_type(cls, ins_type: int):
if ins_type not in (cls.TYP_RIS, cls.TYP_VIS, cls.TYP_CIS, cls.TYP_IIS):
if ins_type not in (cls.TYP_RIS, cls.TYP_VIS, cls.TYP_CIS, cls.TYP_IIS, cls.TYP_ALL):
raise ValueError('unknown instruction type : ' + str(ins_type))
@classmethod
@@ -704,6 +706,8 @@ class DeviceInstruction:
return cls.TYP_VIS
elif ins_type == 'CIS':
return cls.TYP_CIS
elif ins_type == 'ALL':
return cls.TYP_ALL
else:
raise RuntimeError('unknown instruction type : ' + ins_type)
+29 -3
View File
@@ -120,6 +120,9 @@ class ParameterDomain(JsonSerialize, metaclass=abc.ABCMeta):
elif json == 'int':
return ParameterIntDomain
elif json == 'float':
return ParameterFloatDomain
elif json == 'property':
return ParameterPropertyDomain
@@ -291,6 +294,25 @@ class ParameterIntDomainType(ParameterTypeDomain):
ParameterIntDomain = ParameterIntDomainType()
class ParameterFloatDomainType(ParameterTypeDomain):
__slots__ = ()
def init_para(self, initial: Optional[Any] = None) -> float:
print('ParameterFloatDomainType')
if initial is None:
return 0
else:
return float(initial)
def valid_para(self, value: int) -> bool:
return True
def __str__(self):
return "float"
ParameterFloatDomain = ParameterFloatDomainType()
class ParameterValueDomain(ParameterDomain, metaclass=abc.ABCMeta):
"""limited/ranged P value domain """
@@ -301,7 +323,7 @@ class ParameterValueDomain(ParameterDomain, metaclass=abc.ABCMeta):
if initial is None:
return self.range[0]
else:
initial = int(initial)
initial = initial
f, t = self.range
if f <= initial < t:
@@ -742,6 +764,7 @@ class ParameterListDomain(ParameterCollectionDomain):
sz = len(target)
i = oper.index(sz)
v = oper.value(d)
# print('ParameterListDomain', d, sz, i, v, str(d) == 'float', type(d))
if i is None and v is None:
pass
@@ -780,8 +803,11 @@ class ParameterListDomain(ParameterCollectionDomain):
if isinstance(v, int):
v = [v]
target[i] = v
target[len(v):] = []
if isinstance(d, ParameterFloatDomainType):
target[i] = [float(i) for i in v]
else:
target[i] = v
def _valid_list_limit(self, target: List[Any], inc: int) -> bool:
if self._limit is not None:
+1 -2
View File
@@ -880,8 +880,7 @@ class WhenExpression(ComplexExpression[T]):
def value(self, context: Scope) -> Union[str, T]:
value = super().value(context)
key = str(value)
key = str(int(value))
if key in self._when:
return self._when[key].value(context.child(VALUE=value))
+13
View File
@@ -5,6 +5,13 @@ from .device import *
from .instruction import *
from .parameter import *
def convert_to_float(lst):
# Check if the element is a list (for handling nested lists)
if isinstance(lst, list):
return [convert_to_float(x) for x in lst]
else:
# If it's not a list, convert it to float
return float(lst)
class MatchRule(JsonSerialize, metaclass=abc.ABCMeta):
"""Device matching rule. Program use this table to find correct library according to the response information from
@@ -444,6 +451,12 @@ class DefaultLibraryLoader:
elif guard is not None:
guard = ListGuardExpression([GuardExpression.parse(guard)])
if "float" in str(domain):
initial = convert_to_float(initial)
# print('!@#$%^&')
# print(name, domain, initial, value, value_set)
return ParameterInfo(name, domain,
initial=initial,
+27 -14
View File
@@ -1,4 +1,5 @@
import re
import struct
from random import randint
from time import sleep
from typing import Sequence, Tuple
@@ -284,6 +285,7 @@ class InternalInstruction(SingleInstruction):
PREDEFINED_CDR = '_cdr'
PREDEFINED_DISABLE_CACHE = '_disable_cache'
PREDEFINED_IDLE = '_idle'
PREDEFINED_COUNTDOWN = '_countdown'
PREDEFINED = (
PREDEFINED_SLEEP,
@@ -296,6 +298,7 @@ class InternalInstruction(SingleInstruction):
PREDEFINED_CDR,
PREDEFINED_DISABLE_CACHE,
PREDEFINED_IDLE,
PREDEFINED_COUNTDOWN
)
__slots__ = ('_expr', '_para')
@@ -375,7 +378,7 @@ class InternalInstruction(SingleInstruction):
parser.parse_instruction(context, data)
# tag2
class ListInstruction(Instruction, ImmutableListNode[Union[Instruction, Expression[str]]]):
"""Instruction group, allow the name of the instruction or a expression it.
If instruction name is ``None``, ignore it.
@@ -588,7 +591,7 @@ class InstructionContentWidth:
return InstructionContentWidth(z, t, signed_value=s is not None, little_endian=e == '<'), x
# The start from the json file parse
class InstructionContent(JsonSerialize):
"""
**json format**
@@ -682,7 +685,7 @@ class InstructionContent(JsonSerialize):
return ins_type(width, expr, **ins_argv, comment=comment)
# tag1
class InstructionDataContent(InstructionContent):
"""
**json format**
@@ -743,6 +746,7 @@ class InstructionDataContent(InstructionContent):
return ret[index]
def build_instruction(self, context: Scope, buffer: List[int], shift: int = 0) -> int:
# print('build_instruction', context, buffer, shift, self.value(context))
if self._width.is_array:
raise NotImplementedError()
@@ -750,24 +754,33 @@ class InstructionDataContent(InstructionContent):
value = 1
elif self.value(context) == 'false':
value = 0
elif isinstance(self.value(context), list):
value = self.value(context)
else:
value = int(self.value(context))
value = self.value(context)
# print('value', value, type(value))
# print('self._width.bytes_unit', self._width.bytes_unit)
# print('self._width.size', self._width.size)
if self._width.bytes_unit:
if self._width.size == 1:
buffer.append(value)
else:
tmp = []
for _ in range(self._width.size):
tmp.append(value & 0xFF)
value >>= 8
if self._width.little_endian:
buffer.extend(tmp)
else:
buffer.extend(tmp[::-1])
if isinstance(self.value(context), list):
buffer.extend(value)
elif isinstance(value, int):
tmp = []
for _ in range(self._width.size):
tmp.append(value & 0xFF)
value >>= 8
if self._width.little_endian:
buffer.extend(tmp)
else:
buffer.extend(tmp[::-1])
elif isinstance(value, float):
buffer.extend(struct.pack('>f', value))
return 8
else:
@@ -1112,7 +1125,7 @@ class SendInstruction(SingleInstruction):
else:
for scope in self._foreach_parameter.for_scope(context):
yield ResolvedSendInstruction(self, self._build_instruction(scope))
# tag3
def _build_instruction(self, context: Scope) -> List[int]:
buffer = []
shift = 0
+11 -1
View File
@@ -359,6 +359,7 @@ class DeviceParameter(JsonSerialize):
# initial parameter table
for para_info in library.parameter_table.values():
# print('DeviceParameter', para_info)
try:
para_value = para_info.init_para()
@@ -522,6 +523,7 @@ class DeviceParameter(JsonSerialize):
raise RuntimeError('not a collection parameter ' + para)
target = self._parameter[para]
# print(table, info, domain, target, str(domain) == '[float]', oper)
if isinstance(target, set):
old = set(target)
@@ -1128,13 +1130,21 @@ class CompletedDevice(Device):
:param value: new parameter P value
"""
info = self._library.parameter_table[name]
# print('info', info.domain, info.domain == 'float', info.domain == '[float]')
if isinstance(info.domain, ParameterCollectionDomain):
self._parameter.oper_parameter(name, value)
elif isinstance(info.domain, ParameterFloatDomainType):
self._parameter.set_parameter(name, float(value))
else:
try:
value = value
# value int
value = int(value)
if isinstance(value, str):
if "." in value:
value = float(value)
else:
value = int(value)
except ValueError as e:
# value float
self._parameter.set_parameter(name, value)
+2
View File
@@ -433,6 +433,7 @@ class ParameterInfo(JsonSerialize):
return self._on_change
def init_para(self) -> Any:
# print('initial', self._name, self._initial)
"""
:return: initial P value
:raises value: illegal initial value
@@ -617,6 +618,7 @@ class ParameterInfo(JsonSerialize):
return []
elif isinstance(self._value, ComplexExpression):
print('cast_value_dependency', self._value.dependency)
return self._value.dependency
else:
+30
View File
@@ -2,6 +2,8 @@ from time import sleep
from typing import Iterable
from datetime import datetime
import json
import threading
from time import time
import biopro.impl.vcgencmd as vcg
from biopro.data import DataServerOptions, DataAPI
@@ -1093,6 +1095,34 @@ class ControlServer(SocketServer, ControlServerAPI):
device.status = 1
return True
elif oper == InternalInstruction.PREDEFINED_COUNTDOWN:
if value == 'PULSE_OUTPUT':
continue_mode = device.get_parameter('CONTINUE_MODE')
if continue_mode == 0:
stop_time = device.get_parameter('STOP_TIME')
# Function to send the instruction
def send_instruction():
device.call_instruction('deactive_electrode')
# Function to wait for 30 seconds and then execute the instruction
def delayed_execution(stop_time):
sleep(stop_time)
send_instruction()
device.set_parameter('ACTIVATE_ELECTRODE', 0)
self.mqtt_thread.broadcast_command('device_refresh')
# Create a thread for the delayed execution
thread = threading.Thread(target=delayed_execution, args=(stop_time,))
# Start the thread
thread.start()
# Main program continues without waiting for the thread
# print("Main program continues...")
# print('COUNTDOWN!!!', device, oper, value)
# print(device.get_parameter(value), device.get_parameter_value(value))
return True
else:
return False
File diff suppressed because it is too large Load Diff
+343
View File
@@ -0,0 +1,343 @@
{
"name": "CPG",
"version": "1.2.30",
"match_rule": {
"local_name_pattern": "Elite-CPG.*",
"major_product_number": 0,
"minor_product_number": 8,
"major_version_number": 0,
"minor_version_number": 1
},
"constant": {
"TIME_MAX": 100000,
"VOLT_MAX": 65536,
"Const_Current_Range": 1500001,
"BLE_WRITE_MAX": 255
},
"parameters": {
"ADC_VALUE_I": {
"description": "ADC value current value",
"domain": "int"
},
"FREQUENCY": {
"description": "FREQUENCY",
"record_meta": true,
"initial": [80, 0],
"domain": {
"list": [1000000]
}
},
"AMPLITUDE": {
"description": "AMPLITUDE",
"record_meta": true,
"initial": [1, 1],
"domain": {
"list": "float"
}
},
"PULSE_WIDTH": {
"description": "PULSE_WIDTH",
"record_meta": true,
"initial": [250, 250],
"domain": {
"list": [1000000]
}
},
"PATTERN_MODE": {
"description": "SELECT_ELECTRODE",
"record_meta": true,
"initial": [1, 0],
"domain": {
"list": "float"
}
},
"CONTINUE_MODE": {
"description": "CONTINUE_MODE",
"record_meta": true,
"initial": 1,
"domain": [2],
"value": {
"expression": "VALUE"
}
},
"STOP_TIME": {
"description": "STOP_TIME",
"record_meta": true,
"initial": 30,
"domain": [1000000],
"value": {
"expression": "VALUE"
}
},
"ELECTRODE_SELECTOR": {
"description": "ELECTRODE_SELECTOR",
"record_meta": true,
"initial": [true,false,true,false],
"domain": {
"list": [2]
}
},
"WORKING_ELECTRODE": {
"description": "WORKING_ELECTRODE",
"record_meta": true,
"initial": [0, 0, 0, 0],
"domain": {
"list": "float"
}
},
"PATTERN_SELECTOR": {
"description": "PATTERN_SELECTOR",
"record_meta": true,
"initial": [0, 0, 1, 1],
"domain": {
"list": "float"
}
},
"ACTIVATE_ELECTRODE": {
"description": "PATTERN_SELECTOR",
"record_meta": true,
"initial": 0,
"domain": "float"
},
"CHANNEL": {
"description": "record channels",
"record_meta": true,
"domain": "property",
"value": "[0, 1, 2]"
},
"CHANNEL_LABEL": {
"description": "channel label",
"record_meta": true,
"domain": "property",
"value": "['current', 'voltage', 'impedance']"
},
"SAMPLE_RATE": {
"description": "data sampling rate",
"record_meta": true,
"initial": 1000,
"domain": [
1001
],
"value": {
"expression": "VALUE"
},
"on_change": "set_sample_rate"
},
"AMP_GAIN": {
"description": "amp gain",
"record_meta": true,
"domain": "constant",
"value": 1
},
"MODE": {
"description": "working mode",
"record_meta": true,
"initial": 0,
"value": [
"Electrical stimulation",
"Dev Mode"
]
},
"BLE_WRITE": {
"description": "send msg to elite",
"domain": {
"list": [
"BLE_WRITE_MAX"
]
},
"initial": "[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]",
"value": "VALUE"
},
"BLE_READ": {
"description": "receive msg from elite",
"domain": "int"
},
"TIME_UNIT": {
"description": "Duration unit",
"initial": 2,
"value": [
"h",
"m",
"s",
"ms"
]
},
"TIME_DURATION": {
"description": "Run duration",
"record_meta": true,
"initial": 0,
"domain": [
"TIME_MAX"
],
"value": {
"expression": "VALUE"
}
}
},
"instruction": {
"output": [
"active_electrode",
"_countdown('PULSE_OUTPUT')"
],
"active_electrode": {
"type": "RIS",
"parameter": {
"ch0": "ELECTRODE_SELECTOR[0]",
"ch1": "ELECTRODE_SELECTOR[1]",
"ch2": "ELECTRODE_SELECTOR[2]",
"ch3": "ELECTRODE_SELECTOR[3]",
"Amp1": {
"expression": "PATTERN_SELECTOR[0]",
"when": {
"0": "AMPLITUDE[0]",
"1": "AMPLITUDE[1]"
}
},
"Freq1": {
"expression": "PATTERN_SELECTOR[0]",
"when": {
"0": "FREQUENCY[0]",
"1": "FREQUENCY[1]"
}
},
"Pulse1": {
"expression": "PATTERN_SELECTOR[0]",
"when": {
"0": "PULSE_WIDTH[0]",
"1": "PULSE_WIDTH[1]"
}
},
"Amp2": {
"expression": "PATTERN_SELECTOR[2]",
"when": {
"0": "AMPLITUDE[0]",
"1": "AMPLITUDE[1]"
}
},
"Freq2": {
"expression": "PATTERN_SELECTOR[2]",
"when": {
"0": "FREQUENCY[0]",
"1": "FREQUENCY[1]"
}
},
"Pulse2": {
"expression": "PATTERN_SELECTOR[2]",
"when": {
"0": "PULSE_WIDTH[0]",
"1": "PULSE_WIDTH[1]"
}
}
},
"data": [
"1XFF;1X02;1XA0;",
"1bch0;1bch1;6b000000;",
"4BAmp1;4BPulse1;4BFreq1;",
"2b00;1bch2;1bch3;4b0000;",
"4BAmp2;4BPulse2;4BFreq2;",
"4BSTOP_TIME;",
"1bch0;1bch1;1bch2;1bch3;4b0000;"
]
},
"deactive_electrode": {
"type": "RIS",
"parameter": {
"ch0": "ELECTRODE_SELECTOR[0]",
"ch1": "ELECTRODE_SELECTOR[1]",
"ch2": "ELECTRODE_SELECTOR[2]",
"ch3": "ELECTRODE_SELECTOR[3]"
},
"data": [
"1XFF;1X02;1XA1;",
"1bch0;1bch1;1bch2;1bch3;4b0000;"
]
},
"resume_electrode_0": {
"type": "RIS",
"data": [
"1XFF;1X02;1X06;4b1000;4b0000;"
]
},
"resume_electrode_1": {
"type": "RIS",
"data": [
"1XFF;1X02;1X06;4b0100;4b0000;"
]
},
"resume_electrode_2": {
"type": "RIS",
"data": [
"1XFF;1X02;1X06;4b0010;4b0000;"
]
},
"resume_electrode_3": {
"type": "RIS",
"data": [
"1XFF;1X02;1X06;4b0001;4b0000;"
]
},
"suspend_electrode_0": {
"type": "RIS",
"data": [
"1XFF;1X02;1X05;4b1000;4b0000;"
]
},
"suspend_electrode_1": {
"type": "RIS",
"data": [
"1XFF;1X02;1X05;4b0100;4b0000;"
]
},
"suspend_electrode_2": {
"type": "RIS",
"data": [
"1XFF;1X02;1X05;4b0010;4b0000;"
]
},
"suspend_electrode_3": {
"type": "RIS",
"data": [
"1XFF;1X02;1X05;4b0001;4b0000;"
]
},
"idle": [
"_idle()"
],
"data_format": [
"_data_format('I4V4Z4T4')",
{
"expression": "MODE",
"when": {
"0": "_disable_cache(True)",
"1": "_disable_cache(True)",
"*": "_disable_cache(False)"
}
}
],
"ble_instru_send": [
"ble_write",
"_cdr('20X>ADC_VALUE_I')"
],
"ble_write": {
"type": "ALL",
"data": [
"255X>BLE_WRITE;"
]
},
"dev_version": [
"CIS_VERSION",
"_cdr('20X>ADC_VALUE_I')"
],
"dev_battery": [
"CIS_VOLT",
"_cdr('20X>ADC_VALUE_I')"
],
"set_para_DAC_VOLT": {
"type": "RIS",
"data": [
"XE2;X01;2B>DAC_VOLT"
]
}
}
}
@@ -1,12 +1,12 @@
{
"name": "Elite_EDC_1.5re",
"name": "Elite_EDC_1.5r2",
"version": "1.2.30",
"match_rule": {
"local_name_pattern": "Elite.*",
"major_product_number": 0,
"minor_product_number": 2,
"major_version_number": 1,
"minor_version_number": 7
"minor_version_number": 8
},
"constant": {
"TIME_MAX": 100000,
File diff suppressed because it is too large Load Diff
+122
View File
@@ -0,0 +1,122 @@
{
"name": "PEL_1.0",
"version": "1.2.30",
"match_rule": {
"local_name_pattern": "Elite-PEL.*",
"major_product_number": 0,
"minor_product_number": 7,
"major_version_number": 0,
"minor_version_number": 0
},
"constant": {
"TIME_MAX": 100000,
"VOLT_MAX": 65536,
"Const_Current_Range": 1500001,
"BLE_WRITE_MAX": 255
},
"parameters": {
"CHANNEL": {
"description": "record channels",
"record_meta": true,
"domain": "property",
"value": "[0, 1, 2]"
},
"SAMPLE_RATE": {
"description": "data sampling rate",
"record_meta": true,
"initial": 1000,
"domain": [
1001
],
"value": {
"expression": "VALUE"
},
"on_change": "set_sample_rate"
},
"AMP_GAIN": {
"description": "amp gain",
"record_meta": true,
"domain": "constant",
"value": 1
},
"PATTERN_SWITCH": {
"description": "switch of pattern",
"initial": 1,
"domain": [
2
],
"value": {
"expression": "VALUE"
}
},
"PULSE": {
"description": "Pulse Mode Segment Duration 2",
"record_meta": true,
"initial": [
0,
0,
0
],
"domain": {
"list": [
66536
]
},
"value": {
"expression": "VALUE"
}
},
"PATTERN": {
"description": "Pulse Mode Segment Duration 2",
"record_meta": true,
"initial": 1,
"domain": [
44
],
"value": {
"expression": "VALUE"
}
}
},
"instruction": {
"start": [
"pulse_e_load"
],
"pulse_e_load": [
{
"expression": "PATTERN_SWITCH",
"when": {
"0": "pattern",
"1": "manual"
}
}
],
"manual": {
"type": "RIS",
"parameter": {
"pa": "PULSE[0]",
"pb": "PULSE[1]",
"pc": "PULSE[2]"
},
"data": [
"XFF;",
"X62;",
"4b1;4b>pa;4b>pb;4b>pc;"
]
},
"pattern": {
"type": "RIS",
"parameter": {
"pa": "PATTERN"
},
"data": [
"XFF;X62;",
"4b>0;12b>pa;"
]
},
"ble_instru_send": [
"ble_write",
"_cdr('20X>ADC_VALUE_I')"
]
}
}
+155
View File
@@ -0,0 +1,155 @@
{
"name": "PEL_2.0",
"version": "1.2.30",
"match_rule": {
"local_name_pattern": "Elite-PEL.*",
"major_product_number": 0,
"minor_product_number": 7,
"major_version_number": 0,
"minor_version_number": 1
},
"constant": {
"TIME_MAX": 100000,
"VOLT_MAX": 65536,
"Const_Current_Range": 1500001,
"BLE_WRITE_MAX": 255
},
"parameters": {
"CHANNEL": {
"description": "record channels",
"record_meta": true,
"domain": "property",
"value": "[0, 1, 2]"
},
"SAMPLE_RATE": {
"description": "data sampling rate",
"record_meta": true,
"initial": 1000,
"domain": [
1001
],
"value": {
"expression": "VALUE"
},
"on_change": "set_sample_rate"
},
"AMP_GAIN": {
"description": "amp gain",
"record_meta": true,
"domain": "constant",
"value": 1
},
"MODE": {
"description": "working mode",
"record_meta": true,
"initial": 0,
"value": [
"Select Resistor Mode",
"Dev Mode"
]
},
"BLE_WRITE": {
"description": "send msg to elite",
"domain": {
"list": [
"BLE_WRITE_MAX"
]
},
"initial": "[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]",
"value": "VALUE"
},
"BLE_READ": {
"description": "receive msg from elite",
"domain": "int"
},
"ADC_VALUE_I": {
"description": "ADC value current value",
"domain": "int"
},
"PATTERN_SWITCH": {
"description": "switch of pattern",
"initial": 1,
"domain": [
2
],
"value": {
"expression": "VALUE"
}
},
"PULSE": {
"description": "Pulse Mode Segment Duration 2",
"record_meta": true,
"initial": [
0,
0,
0
],
"domain": {
"list": [
66536
]
},
"value": {
"expression": "VALUE"
}
},
"PATTERN": {
"description": "Pulse Mode Segment Duration 2",
"record_meta": true,
"initial": 1,
"domain": [
44
],
"value": {
"expression": "VALUE"
}
}
},
"instruction": {
"start": [
"pulse_e_load"
],
"pulse_e_load": [
{
"expression": "PATTERN_SWITCH",
"when": {
"0": "pattern",
"1": "manual"
}
}
],
"manual": {
"type": "RIS",
"parameter": {
"pa": "PULSE[0]",
"pb": "PULSE[1]",
"pc": "PULSE[2]"
},
"data": [
"XFF;",
"X62;",
"4b1;4b>pa;4b>pb;4b>pc;"
]
},
"pattern": {
"type": "RIS",
"parameter": {
"pa": "PATTERN"
},
"data": [
"XFF;X62;",
"4b>0;12b>pa;"
]
},
"ble_instru_send": [
"ble_write",
"_cdr('20X>ADC_VALUE_I')"
],
"ble_write": {
"type": "ALL",
"data": [
"255X>BLE_WRITE;"
]
}
}
}