# Redisインプリ ## Redis - Install(Windowsの場合、サービス登録) - 起動 ## BLE Data Logger - Settings.xmlに追加 ``` <IsStoreDB>true</IsStoreDB> <DBPort>6379</DBPort> ``` - データベース1個のテーブル使用 Example | Key | Value | | -------- | -------- | | <SensorName> | YYYY-MM-DD_HH:MM:SS.msec <value> | ``` $ ./redis-cli LRANGE "Temperature" 0 10 2020-05-20_23:24:24.717 23.6953125 2020-05-20_23:24:25.717 23.75390625 2020-05-20_23:24:26.717 23.6875 2020-05-20_23:24:27.717 23.78125 ``` - 起動時にRedis接続。 ```c if (Settings.Instance.IsStoreDB){ try { var conn = ConnectionMultiplexer.Connect("localhost"); db = conn.GetDatabase(); } catch (RedisConnectionException) { } } ``` - データ採取のCSVファイル作成時にconfigファイルにある<CustomerName>をkeyとして   一旦削除。 ```c if (db != null){ db.KeyDelete(this.sensorNameInFileName); } ``` - 書き込み時にKeyとしてList型で"2020-05-20_22:40:717 0.1234"で書き込み ```c if (db != null) { string key = this.sensorNameInFileName; string value = dt.ToString("yyyy-MM-dd_HH:mm:ss.fff ") + val.ToString(); db.ListRightPush(key, value); } ``` ## Dash ``` { "url": "localhost", "port": "6379", "key_names": { "eh1": "EH1", "eh2": "EH2", "acc_x": "ACCEL_X", "acc_y": "ACCEL_Y", "acc_z": "ACCEL_Z", "temp": "Temperature", "pres": "Pressure" }, "app_config_location": "./Debug/Sensor_Config.json", "dash_interval_msec": 1000, "redis_get_maximum": 5000, "deque_length": 3000, "app_port": 8050 } ``` - 起動。dequeをセンサー分あらかじめ確保。 - Configファイル読み込み、Redis Connect - interval(1000ms,,)ごとにRedisから読み込み(あるだけor数指定) # Redis Listコマンド:lpush,rpush,lpop,rpop,lrange等。  順番の値の集合。 時間と値の文字列で入れるしかない。 応用場面:  1)高頻度の追加、queueとして利用  2)時系列(追加順)に表示  3)追加された要素にアクセスが集中 例:Twitterのタイムライン、   ECサイトの現在購入タイムライン、   大量アクセスのqueue $ rpush [key_name] [member]  # リストの末尾に値を追加 $ lpush [key_name] [member]  # リストの先頭に値を追加 $ rpop [key_name]        # リストの末尾の値を削除 $ lpop [key_name]        # リストの先頭の値を削除 $ lrange [key_name] 0 3     # 1番目から4番目まで値を取得 $ lrange [key_name] 0 -1    # 1番目から最後(最後から1番目)までの値を取得 $ lindex [key_name] 2      # 3番目の値を取得 $ lindex [key_name] -1     # 最後の値を取得 $ llen [key]           # 要素の数を取得 --- # Redis(Windows) 1. インストール https://weblabo.oscasierra.net/redis-windows-install/ ``` > CD "C:¥Program Files¥Redis" > redis-server --version Redis server v=3.0.504 sha=00000000:0 malloc=jemalloc-3.6.0 bits=64 build=a4f7a6e86f2d60b3 ``` ``` redis-server /usr/local/etc/redis.conf ``` ``` # 設定ファイルに 「port 6380」 と書くのと同じ $ redis-server --port 6380 ``` https://qiita.com/morrr/items/26dbdd87df03315fa680 ``` redis-cli -h 127.0.0.1 -p 6379 -a password FLUSHALL ``` # C# nuget StackExchange.Redis http://igatea.hatenablog.com/entry/2018/03/23/002937 https://stackexchange.github.io/StackExchange.Redis/Configuration.html - Listの場合の使い方 https://stackoverflow.com/questions/31955977/how-to-store-list-element-in-redis-cache # Redis Install https://github.com/microsoftarchive/redis/releases/tag/win-3.2.100 ``` C:\Users\a863752>cd "C:\Program Files\Redis" C:\Program Files\Redis>dir ドライブ C のボリューム ラベルがありません。 ボリューム シリアル番号は AC8A-B5D5 です C:\Program Files\Redis のディレクトリ 2020/05/18 15:17 <DIR> . 2020/05/18 15:17 <DIR> .. 2016/07/01 16:27 1,024 EventLog.dll 2016/07/01 16:07 12,509 Redis on Windows Release Notes.docx 2016/07/01 16:07 16,727 Redis on Windows.docx 2016/07/01 16:28 409,088 redis-benchmark.exe 2016/07/01 16:28 4,370,432 redis-benchmark.pdb 2016/07/01 16:28 257,024 redis-check-aof.exe 2016/07/01 16:28 3,518,464 redis-check-aof.pdb 2016/07/01 16:28 499,712 redis-cli.exe 2016/07/01 16:28 4,526,080 redis-cli.pdb 2016/07/01 16:28 1,666,560 redis-server.exe 2016/07/01 16:28 7,081,984 redis-server.pdb 2020/05/18 15:17 48,212 redis.windows-service.conf 2016/07/01 16:07 48,201 redis.windows.conf 2020/05/18 15:17 0 server_log.txt 2016/07/01 09:17 14,265 Windows Service Documentation.docx 15 個のファイル 22,470,282 バイト 2 個のディレクトリ 6,544,347,136 バイトの空き領域 C:\Program Files\Redis>redis-server --version Redis server v=3.2.100 sha=00000000:0 malloc=jemalloc-3.6.0 bits=64 build=dd26f1f93c5130ee C:\Program Files\Redis> ``` - Windowsのサービスには自動的に登録される --- # Redis Command ``` $ redis-cli > keys * $ redis-cli keys "*" ``` --- # docker ``` $ docker run --name my-redis -d redis ``` ``` $ docker run -it --link my-redis:redis --rm redis sh -c 'exec redis-cli -h "$REDIS_PORT_6379_TCP_ADDR" -p "$REDIS_PORT_6379_TCP_PORT"' 172.17.0.2:6379[1]> set key1 11111 OK 172.17.0.2:6379[1]> get key1 "11111" ``` ``` $ docker stop my-redis ``` --- # Redis GUI(Windows) RedisInsight https://redislabs.com/redisinsight/ - installer - Docker compose ``` version: "3" networks: redis: driver: bridge services: redis: image: redis:5.0.7-alpine ports: - 6379:6379 command: redis-server --requirepass MY_SUPER_AWESOME_PASSWORD networks: - redis redisinsight: image: redislabs/redisinsight:latest ports: - 8001:8001 volumes: - ./redisinsight:/db networks: - redis ``` --- C# - 文字列変換 - configファイルに設定追加 - port番号 Pythonファイル - 外部にjson設定ファイル - Port番号 - Dashの1秒周期のポーリングじゃダメか? --- ``` (py37) C:\Users\a863752>conda install dash ``` --- ```json { "store_db": false, "db_url": 'db://localhost:5050', } ``` ```json { "config_location": "./", "use_source_in_config": true, } ``` # 手順 1. インストール 2. サーバーを手作業で立ち上げる 3. Logger起動 ## 1.インストール ## 2.サーバーの立ち上げ ## 3. Logger起動 ## 4. Pythonの起動 # App側 - App側 Maxのサンプリング周波数は500Hz - シンプルに各DBのListの長さはMaxは5000としておく - C#側からの使用 - ServiceStack.Redis nugetから - BookSleeve - https://www.buildinsider.net/small/rediscshap/01 http://genpaku3.hatenadiary.jp/entry/2017/11/27/002229 https://stackoverrun.com/ja/q/9061204 - Settings.xmlに追加 ``` <IsStoreDB>true</IsStoreDB> <DBPort>6379</DBPort> ``` - Sensor_Config.json ```json [ { "SensorType": "EH_GEN", "CustomerName": "EH_GEN", "IsEnable": true, "UUID_Notify": "00001011", "UUID_Config": "00001111", "IsSingle": true, "IsMaster": true, "ParentName": "", "Combo": { "ResIndex": 0, "SampleIndex": 2, "RangeIndex": 0, "OtherIndex": 0 }, "ComboResetDefault": { "ResIndex": 0, "SampleIndex": 2, "RangeIndex": 0, "OtherIndex": 0 }, "ComboUserOpen": { "ResIndex": false, "SampleIndex": true, "RangeIndex": false, "OtherIndex": false }, "db_length": }, { "SensorType": "EHS2", "CustomerName": "EH2", "IsEnable": false, "UUID_Notify": "00001010", "UUID_Config": "00001110", "IsSingle": false, "IsMaster": false, "ParentName": "", "Combo": { "ResIndex": 0, "SampleIndex": 3, "RangeIndex": 1, "OtherIndex": 1 }, "ComboResetDefault": { "ResIndex": 0, "SampleIndex": 3, "RangeIndex": 1, "OtherIndex": 1 }, "ComboUserOpen": { "ResIndex": false, "SampleIndex": true, "RangeIndex": true, "OtherIndex": true } }, { "SensorType": "ACCEL_X", "CustomerName": "ACCEL_X", "IsEnable": false, "UUID_Notify": "00001020", "UUID_Config": "00001120", "IsSingle": false, "IsMaster": true, "ParentName": "ACCEL", "Combo": { "ResIndex": 0, "SampleIndex": 0, "RangeIndex": 0, "OtherIndex": 0 }, "ComboResetDefault": { "ResIndex": 0, "SampleIndex": 0, "RangeIndex": 0, "OtherIndex": 0 }, "ComboUserOpen": { "ResIndex": false, "SampleIndex": true, "RangeIndex": true, "OtherIndex": false } }, { "SensorType": "ACCEL_Y", "CustomerName": "ACCEL_Y", "IsEnable": false, "UUID_Notify": "00001020", "UUID_Config": "00001120", "IsSingle": false, "IsMaster": false, "ParentName": "", "Combo": { "ResIndex": 0, "SampleIndex": 0, "RangeIndex": 0, "OtherIndex": 0 }, "ComboResetDefault": { "ResIndex": 0, "SampleIndex": 0, "RangeIndex": 0, "OtherIndex": 0 }, "ComboUserOpen": { "ResIndex": false, "SampleIndex": true, "RangeIndex": true, "OtherIndex": false } }, { "SensorType": "ACCEL_Z", "CustomerName": "ACCEL_Z", "IsEnable": false, "UUID_Notify": "00001020", "UUID_Config": "00001120", "IsSingle": false, "IsMaster": false, "ParentName": "", "Combo": { "ResIndex": 0, "SampleIndex": 0, "RangeIndex": 0, "OtherIndex": 0 }, "ComboResetDefault": { "ResIndex": 0, "SampleIndex": 0, "RangeIndex": 0, "OtherIndex": 0 }, "ComboUserOpen": { "ResIndex": false, "SampleIndex": true, "RangeIndex": true, "OtherIndex": false } }, { "SensorType": "TEMP", "CustomerName": "Temperature", "IsEnable": false, "UUID_Notify": "00001060", "UUID_Config": "00001160", "IsSingle": true, "IsMaster": true, "ParentName": "", "Combo": { "ResIndex": 0, "SampleIndex": 0, "RangeIndex": 0, "OtherIndex": 0 }, "ComboResetDefault": { "ResIndex": 0, "SampleIndex": 0, "RangeIndex": 0, "OtherIndex": 0 }, "ComboUserOpen": { "ResIndex": false, "SampleIndex": true, "RangeIndex": false, "OtherIndex": false } }, { "SensorType": "PRS", "CustomerName": "Pressure", "IsEnable": false, "UUID_Notify": "00001040", "UUID_Config": "00001140", "IsSingle": true, "IsMaster": true, "ParentName": "", "Combo": { "ResIndex": 0, "SampleIndex": 1, "RangeIndex": 0, "OtherIndex": 0 }, "ComboResetDefault": { "ResIndex": 0, "SampleIndex": 1, "RangeIndex": 0, "OtherIndex": 0 }, "ComboUserOpen": { "ResIndex": false, "SampleIndex": true, "RangeIndex": false, "OtherIndex": false } }, { "SensorType": "H_VOL", "CustomerName": "BatteryVoltage", "IsEnable": false, "UUID_Notify": "000010f0", "UUID_Config": "00000000", "IsSingle": false, "IsMaster": false, "ParentName": "", "Combo": { "ResIndex": 0, "SampleIndex": 0, "RangeIndex": 0, "OtherIndex": 0 }, "ComboResetDefault": { "ResIndex": 0, "SampleIndex": 0, "RangeIndex": 0, "OtherIndex": 0 }, "ComboUserOpen": { "ResIndex": false, "SampleIndex": false, "RangeIndex": false, "OtherIndex": false } } ] ``` - Settings.xml ```json <?xml version="1.0"?> <Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <chart_options> <ChartOptions> <Enable>true</Enable> <GridColor>-1</GridColor> <Title /> <FontSize>7</FontSize> <DecimalPoint>1</DecimalPoint> <Enable_AutoScale>true</Enable_AutoScale> <YRangeMax>5</YRangeMax> <YRangeMin>-5</YRangeMin> </ChartOptions> <ChartOptions> <Enable>true</Enable> <GridColor>-1</GridColor> <Title /> <FontSize>7</FontSize> <DecimalPoint>1</DecimalPoint> <Enable_AutoScale>true</Enable_AutoScale> <YRangeMax>5</YRangeMax> <YRangeMin>-5</YRangeMin> </ChartOptions> <ChartOptions> <Enable>true</Enable> <GridColor>-1</GridColor> <Title /> <FontSize>7</FontSize> <DecimalPoint>1</DecimalPoint> <Enable_AutoScale>true</Enable_AutoScale> <YRangeMax>50</YRangeMax> <YRangeMin>0</YRangeMin> </ChartOptions> <ChartOptions> <Enable>false</Enable> <GridColor>-1</GridColor> <Title /> <FontSize>7</FontSize> <DecimalPoint>1</DecimalPoint> <Enable_AutoScale>true</Enable_AutoScale> <YRangeMax>102000</YRangeMax> <YRangeMin>100000</YRangeMin> </ChartOptions> </chart_options> <dataSrcSet> <DataSourceSettings> <Enable>true</Enable> <Block>0</Block> <Name /> <Enable_Chart>true</Enable_Chart> <Chart>0</Chart> <AvgNumber>1</AvgNumber> <LineColor>-65536</LineColor> <Enable_GradientColor>false</Enable_GradientColor> <LineOpacity>251</LineOpacity> <LineWidth>1</LineWidth> <Enable_LineDot>false</Enable_LineDot> <LineDot_Size>3</LineDot_Size> <Enable_LinearConversion>false</Enable_LinearConversion> <Param_a>1</Param_a> <Param_b0>0</Param_b0> <Param_b1>0</Param_b1> </DataSourceSettings> <DataSourceSettings> <Enable>true</Enable> <Block>1</Block> <Name /> <Enable_Chart>true</Enable_Chart> <Chart>0</Chart> <AvgNumber>1</AvgNumber> <LineColor>-16711936</LineColor> <Enable_GradientColor>false</Enable_GradientColor> <LineOpacity>255</LineOpacity> <LineWidth>1</LineWidth> <Enable_LineDot>false</Enable_LineDot> <LineDot_Size>3</LineDot_Size> <Enable_LinearConversion>false</Enable_LinearConversion> <Param_a>1</Param_a> <Param_b0>0</Param_b0> <Param_b1>0</Param_b1> </DataSourceSettings> <DataSourceSettings> <Enable>true</Enable> <Block>2</Block> <Name /> <Enable_Chart>true</Enable_Chart> <Chart>1</Chart> <AvgNumber>1</AvgNumber> <LineColor>-256</LineColor> <Enable_GradientColor>false</Enable_GradientColor> <LineOpacity>255</LineOpacity> <LineWidth>1</LineWidth> <Enable_LineDot>false</Enable_LineDot> <LineDot_Size>3</LineDot_Size> <Enable_LinearConversion>false</Enable_LinearConversion> <Param_a>1</Param_a> <Param_b0>0</Param_b0> <Param_b1>0</Param_b1> </DataSourceSettings> <DataSourceSettings> <Enable>true</Enable> <Block>3</Block> <Name /> <Enable_Chart>true</Enable_Chart> <Chart>1</Chart> <AvgNumber>1</AvgNumber> <LineColor>-65281</LineColor> <Enable_GradientColor>false</Enable_GradientColor> <LineOpacity>255</LineOpacity> <LineWidth>1</LineWidth> <Enable_LineDot>false</Enable_LineDot> <LineDot_Size>3</LineDot_Size> <Enable_LinearConversion>false</Enable_LinearConversion> <Param_a>1</Param_a> <Param_b0>0</Param_b0> <Param_b1>0</Param_b1> </DataSourceSettings> <DataSourceSettings> <Enable>true</Enable> <Block>4</Block> <Name /> <Enable_Chart>true</Enable_Chart> <Chart>1</Chart> <AvgNumber>1</AvgNumber> <LineColor>-32640</LineColor> <Enable_GradientColor>false</Enable_GradientColor> <LineOpacity>255</LineOpacity> <LineWidth>1</LineWidth> <Enable_LineDot>false</Enable_LineDot> <LineDot_Size>3</LineDot_Size> <Enable_LinearConversion>false</Enable_LinearConversion> <Param_a>1</Param_a> <Param_b0>0</Param_b0> <Param_b1>0</Param_b1> </DataSourceSettings> <DataSourceSettings> <Enable>true</Enable> <Block>5</Block> <Name /> <Enable_Chart>true</Enable_Chart> <Chart>2</Chart> <AvgNumber>1</AvgNumber> <LineColor>-1</LineColor> <Enable_GradientColor>false</Enable_GradientColor> <LineOpacity>255</LineOpacity> <LineWidth>1</LineWidth> <Enable_LineDot>false</Enable_LineDot> <LineDot_Size>3</LineDot_Size> <Enable_LinearConversion>false</Enable_LinearConversion> <Param_a>1</Param_a> <Param_b0>0</Param_b0> <Param_b1>0</Param_b1> </DataSourceSettings> <DataSourceSettings> <Enable>false</Enable> <Block>0</Block> <Name /> <Enable_Chart>false</Enable_Chart> <Chart>0</Chart> <AvgNumber>1</AvgNumber> <LineColor>-1</LineColor> <Enable_GradientColor>false</Enable_GradientColor> <LineOpacity>255</LineOpacity> <LineWidth>1</LineWidth> <Enable_LineDot>false</Enable_LineDot> <LineDot_Size>3</LineDot_Size> <Enable_LinearConversion>false</Enable_LinearConversion> <Param_a>1</Param_a> <Param_b0>0</Param_b0> <Param_b1>0</Param_b1> </DataSourceSettings> <DataSourceSettings> <Enable>false</Enable> <Block>0</Block> <Name /> <Enable_Chart>false</Enable_Chart> <Chart>0</Chart> <AvgNumber>1</AvgNumber> <LineColor>-1</LineColor> <Enable_GradientColor>false</Enable_GradientColor> <LineOpacity>255</LineOpacity> <LineWidth>1</LineWidth> <Enable_LineDot>false</Enable_LineDot> <LineDot_Size>3</LineDot_Size> <Enable_LinearConversion>false</Enable_LinearConversion> <Param_a>1</Param_a> <Param_b0>0</Param_b0> <Param_b1>0</Param_b1> </DataSourceSettings> </dataSrcSet> <Com>COM1</Com> <Baudrate>115200</Baudrate> <QueueSize>10240</QueueSize> <XRange>15</XRange> <RefeshInterval>60</RefeshInterval> <Enable_Legend>false</Enable_Legend> <BackgroundColor>-16777216</BackgroundColor> <ChartType>0</ChartType> <Enable_CsvOutput>true</Enable_CsvOutput> <Enable_AntiAliasing>true</Enable_AntiAliasing> <DataDir>./</DataDir> <IsUsePCTime>false</IsUsePCTime> <IsResetDone>false</IsResetDone> <CSVEncoding>SHIFT-JIS</CSVEncoding> <IsBatParcent>false</IsBatParcent> <BatMax>0</BatMax> <DeviceNames>LG_*</DeviceNames> </Settings> ``` --- # 説明用 # CSV Files to DB **convert_csv_to_db.py** extracts data from csv files taken by BLEDataLogger.exe, and store data to db with appropriate form - in csv ``` CSV Columns are #, "Date", "Time", "Value" Example by ACCEL_X.csv # Date Time Value 1 9122019 143719.236 -0.357421875 2 9122019 143719.241 -0.356933594 3 9122019 143719.246 -0.357910156 4 9122019 143719.251 -0.357421875 5 9122019 143719.256 -0.356933594 ``` - in db ``` Example by Redis db with key:Temperature $ ./redis-cli LRANGE "Temperature" 0 10 2020-05-20_23:24:24.717 23.6953125 2020-05-20_23:24:25.717 23.75390625 2020-05-20_23:24:26.717 23.6875 2020-05-20_23:24:27.717 23.78125 ``` "convert_files" in **config.json** shows the files you want to retrieve data and store them to db. ```json "convert_files_path": "./", #Folder where the CSV files are located "convert_files": [ # Files you want to convert in the folder. { "key_name": "ACCEL_X", "file_name": "./DataLog__ACCEL_X.csv" }, { "key_name": "ACCEL_Y", "file_name": "./DataLog__ACCEL_X.csv" } ] ```