diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..a9398fb --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,36 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 2023-04-20 + +### Added + +- 讓使用者自定要使用V1版本還是V2版本 (#eac7f6f) +- 新增常數`IOTTALK_VERSION` (#0a21efd) + +## 2023-04-18 + +### Changed + +- tablename的命名方式,改成只刪除-O,不刪後面的數字 (#14b45a9) + +## 2023-04-12 + +### Changed + +- IoTtalk-v2可使用的dashboard(dynamic) (#a2fe8a6) + +## Rule +每一個軟體的版本必須: +* 標明日期(要用上面說過的規範) +* 標明分類(採用英文)。規範如下: +* 'Added' 添加的新功能 +* 'Changed' 功能變更 +* 'Deprecated' 不建議使用,未來會刪掉 +* 'Removed' 之前不建議使用的功能,這次真的刪掉了 +* 'Fixed' 修正的 bug +* 'Security' 修正了安全相關的 bug diff --git a/README.md b/README.md index 8139eaf..bf09b00 100644 --- a/README.md +++ b/README.md @@ -201,4 +201,21 @@ use `{{ _('') }}` to the needing change words. pybabel compile -f -d app/translations ``` +### V2使用 +1. 修改 **config.py**,根據內部註解依序填上資料。 + + 大約在 Line 25 附近,修改 **CSM_HOST** 跟 **IOTTALK_VERSION** + + + CSM_HOST = 'IoTtalk Server IP' + IOTTALK_VERSION = '1 or 2' + + 下面為範例,擇一使用: + + CSM_HOST = 'https://1.iottalk.tw' + IOTTALK_VERSION = 1 + ------------------------------------ + CSM_HOST = 'https://iottalk2.tw/csm' + IOTTALK_VERSION = 2 + * [詳細安裝說明](https://hackmd.io/5LqVk4MBSCinRXQderD_Jw) (此文件已久未更新,僅供參考) diff --git a/app/api.py b/app/api.py index bea82aa..9c5ede7 100644 --- a/app/api.py +++ b/app/api.py @@ -527,7 +527,7 @@ def api_sensor(): if sensor_record > 0: return 'The sensor name "{}" or df_name "{}" already exists'.format(name, df_name), 404 - db.inject_new_model(re.sub(r'-O[\d]*$', '', df_name)) + db.inject_new_model(re.sub(r'-O', '', df_name)) new_sensor = db.models.sensor(df_name=df_name, name=request.json.get('name'), @@ -563,7 +563,7 @@ def api_sensor(): if sensor_record > 0: return 'The sensor name "{}" or df_name "{}" already exists'.format(name, df_name), 404 - db.inject_new_model(re.sub(r'-O[\d]*$', '', df_name)) + db.inject_new_model(re.sub(r'-O', '', df_name)) (g.session .query(db.models.sensor) diff --git a/app/templates/base/css.html b/app/templates/base/css.html index 3557263..05476de 100644 --- a/app/templates/base/css.html +++ b/app/templates/base/css.html @@ -11,4 +11,4 @@ \ No newline at end of file + diff --git a/config.py b/config.py index a8cd5e7..b24c68b 100644 --- a/config.py +++ b/config.py @@ -20,6 +20,9 @@ # ex: '8.8.8.8' or 'google.com', CSM_HOST = '127.0.0.1:9999' +# Set IoTtalk version, 1 or 2 +IOTTALK_VERSION = 1 + # For the demo page without login # The data format is '':'', examples are shown as follows. demo_token = { diff --git a/da/sa.py b/da/sa.py new file mode 100644 index 0000000..b1c8f7f --- /dev/null +++ b/da/sa.py @@ -0,0 +1,95 @@ +import logging +import re +import time + +from config import CSM_HOST +from datetime import datetime +from db import db +from iottalkpy.dai import module_to_sa + + +log = logging.getLogger("\033[1;35m[DA]: \033[0m") + + +def on_register(dan): + print('register successfully') + + +class SaClass: + def __init__(self, api_url, field, field_id, device_name, device_model, + idf_list=[], odf_list=[], device_addr=None, **kwargs): + self.api_url = api_url + self.field = field + self.field_id = field_id + self.device_name = device_name + self.device_model = device_model + self.idf_list = idf_list + self.odf_list = odf_list + self.device_addr = device_addr + self.push_interval = 10 + self.interval = {} + self.kwargs = kwargs + + for k, v in kwargs.items(): + setattr(self, k, v) + + for odf in odf_list: + odf = re.sub(r'-', r'_', odf) + setattr(self, odf, lambda data, odf=odf: self.on_data(data, odf)) + + def on_data(self, data: list, odf): + try: + session = db.get_session() + if data: + value = float(data[0]) + odf_class = getattr(db.models, re.sub(r"[-_]O", "", odf)) + new_record = odf_class(timestamp=datetime.now(), + field=self.field_id, + value=value) + session.add(new_record) + session.commit() + + except KeyboardInterrupt: + log.info(self.field, ': exit') + except Exception as e: + log.error('[ERROR]:', str(e)) + if str(e).find('mac_addr not found:') != -1: + log.error('Reg_addr is not found. Try to re-register...') + else: + log.error('Connection failed due to unknow reasons.') + finally: + session.close() + + +def main(): + db.connect() + processes = [] + + session = db.get_session() + + for field in (session.query(db.models.field).all()): + odf_list = [] + query_df = (session.query(db.models.field_sensor) + .select_from(db.models.field_sensor) + .filter(db.models.field_sensor.field == field.id) + .all()) + for df in query_df: + odf_list.append(df.df_name) + sa = SaClass(CSM_HOST, field, field.id, + device_name=field.name + '_DataServer', + device_model='DataServer', + odf_list=odf_list,) + + process = module_to_sa(sa) + process.daemon = True + process.start() + processes.append(process) + + session.close() + + for process in processes: + process.join() + + +if __name__ == "__main__": + main() diff --git a/requirements.txt b/requirements.txt index cc66faf..538cc05 100644 --- a/requirements.txt +++ b/requirements.txt @@ -29,3 +29,5 @@ pymysql~=0.10.1 tzlocal~=2.1 MarkupSafe==2.0.1 + +iottalk-py==2.3.1 diff --git a/server.py b/server.py index 9987a1b..8ae1d78 100644 --- a/server.py +++ b/server.py @@ -47,7 +47,10 @@ def _start_server(): def _start_da(): - from da.DAI import main as da + if config.IOTTALK_VERSION == 1: + from da.DAI import main as da + elif config.IOTTALK_VERSION == 2: + from da.sa import main as da da()